diff options
Diffstat (limited to 'libbuild2/script/lexer.hxx')
-rw-r--r-- | libbuild2/script/lexer.hxx | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/libbuild2/script/lexer.hxx b/libbuild2/script/lexer.hxx index c0d617d..bdeba66 100644 --- a/libbuild2/script/lexer.hxx +++ b/libbuild2/script/lexer.hxx @@ -33,21 +33,58 @@ namespace build2 lexer_mode (base_type v): base_type (v) {} }; + // Redirects the <, <<, <<<, >, >>, and >>> aliases resolve to. + // + struct redirect_aliases + { + optional<token_type> l; // < + optional<token_type> ll; // << + optional<token_type> lll; // <<< + optional<token_type> g; // > + optional<token_type> gg; // >> + optional<token_type> ggg; // >>> + + // If the token type is a redirect alias then return the token type + // it resolves to and the passed type otherwise. It's the caller's + // responsibility to make sure that the corresponding alias is present. + // + token_type + resolve (token_type t) const noexcept + { + switch (t) + { + case token_type::in_l: assert (l); return *l; + case token_type::in_ll: assert (ll); return *ll; + case token_type::in_lll: assert (lll); return *lll; + case token_type::out_g: assert (g); return *g; + case token_type::out_gg: assert (gg); return *gg; + case token_type::out_ggg: assert (ggg); return *ggg; + } + + return t; + } + }; + class lexer: public build2::lexer { public: using base_lexer = build2::lexer; using base_mode = build2::lexer_mode; - // Note that neither the name nor escape arguments are copied. + using redirect_aliases_type = script::redirect_aliases; + + // Note that none of the name, redirect aliases, and escape arguments + // are copied. // lexer (istream& is, const path_name& name, lexer_mode m, + const redirect_aliases_type& ra, const char* escapes = nullptr) : base_lexer (is, name, 1 /* line */, nullptr /* escapes */, - false /* set_mode */) + false /* set_mode */), + redirect_aliases (ra) { mode (m, '\0', escapes); } @@ -69,19 +106,23 @@ namespace build2 virtual token next () override; + public: + const redirect_aliases_type& redirect_aliases; + protected: lexer (istream& is, const path_name& name, uint64_t line, const char* escapes, - bool set_mode) - : base_lexer (is, name, line, escapes, set_mode) {} + bool set_mode, + const redirect_aliases_type& ra) + : base_lexer (is, name, line, escapes, set_mode), + redirect_aliases (ra) {} // Return the next token if it is a command operator (|, ||, &&, // redirect, or cleanup) and nullopt otherwise. // optional<token> next_cmd_op (const xchar&, // The token first character (last got char). - bool sep, // The token is separated. - lexer_mode); // The current (potentially "expired") mode. + bool sep); // The token is separated. private: token |