From fbd3c230d3861084b7316a6d5a8597cb00c9510b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 2 Mar 2015 09:10:28 +0200 Subject: Implement value lexing mode So that we can do foo=g++ without having to resort to quoting --- build/lexer.cxx | 76 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 18 deletions(-) (limited to 'build/lexer.cxx') diff --git a/build/lexer.cxx b/build/lexer.cxx index 2870620..6836322 100644 --- a/build/lexer.cxx +++ b/build/lexer.cxx @@ -25,12 +25,13 @@ namespace build // case '\n': { + // Restore the normal mode at the end of the line. + // + if (mode_ == mode::value) + mode_ = mode::normal; + return token (token_type::newline, ln, cn); } - case ':': - { - return token (token_type::colon, ln, cn); - } case '{': { return token (token_type::lcbrace, ln, cn); @@ -39,16 +40,34 @@ namespace build { return token (token_type::rcbrace, ln, cn); } - case '=': - { - return token (token_type::equal, ln, cn); - } - case '+': + } + + // The following characters are not treated as special in the + // value mode. + // + if (mode_ != mode::value) + { + // NOTE: remember to update name() if adding new punctuations. + // + switch (c) { - if (get () != '=') - fail (c) << "expected = after +"; + case ':': + { + return token (token_type::colon, ln, cn); + } + case '=': + { + mode_ = mode::value; + return token (token_type::equal, ln, cn); + } + case '+': + { + if (get () != '=') + fail (c) << "expected = after +"; - return token (token_type::plus_equal, ln, cn); + mode_ = mode::value; + return token (token_type::plus_equal, ln, cn); + } } } @@ -127,35 +146,56 @@ namespace build for (c = peek (); !is_eos (c); c = peek ()) { + bool done (false); + + // The following characters are not treated as special in the + // value mode. + // + if (mode_ != mode::value) + { + switch (c) + { + case ':': + case '=': + case '+': + { + done = true; + break; + } + } + + if (done) + break; + } + switch (c) { case ' ': case '\t': case '\n': case '#': - case ':': case '{': case '}': - case '=': - case '+': { + done = true; break; } case '\\': { get (); lexeme += escape (); - continue; + break; } default: { get (); lexeme += c; - continue; + break; } } - break; + if (done) + break; } return token (lexeme, ln, cn); -- cgit v1.1