From efd76ff778c0b7b1f8cb9e0485bb9b4b62b149a7 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 8 Sep 2015 12:37:39 +0200 Subject: Implement single quote support --- build/bootstrap.build | 1 + build/lexer | 5 ++++- build/lexer.cxx | 39 +++++++++++++++++++++++++++++++++++---- build/root.build | 7 +++++++ 4 files changed, 47 insertions(+), 5 deletions(-) (limited to 'build') diff --git a/build/bootstrap.build b/build/bootstrap.build index 381b45e..05aac3e 100644 --- a/build/bootstrap.build +++ b/build/bootstrap.build @@ -4,3 +4,4 @@ project = build2 subprojects = # No subprojects. using config +using test diff --git a/build/lexer b/build/lexer index e5676cc..9a0582d 100644 --- a/build/lexer +++ b/build/lexer @@ -61,7 +61,10 @@ namespace build private: token - name (xchar, bool separated); + name (bool separated); + + void + single_quote (std::string& lexeme); // Return true we have seen any spaces. Skipped empty lines don't // count. In other words, we are only interested in spaces that diff --git a/build/lexer.cxx b/build/lexer.cxx index 88628d3..4151087 100644 --- a/build/lexer.cxx +++ b/build/lexer.cxx @@ -94,17 +94,20 @@ namespace build // Otherwise it is a name. // - return name (c, sep); + unget (c); + return name (sep); } token lexer:: - name (xchar c, bool sep) + name (bool sep) { + xchar c (peek ()); + assert (!eos (c)); + uint64_t ln (c.line), cn (c.column); string lexeme; - lexeme += (c != '\\' ? c : escape ()); - for (c = peek (); !eos (c); c = peek ()) + for (; !eos (c); c = peek ()) { bool done (false); @@ -173,6 +176,11 @@ namespace build lexeme += escape (); break; } + case '\'': + { + single_quote (lexeme); + break; + } default: { get (); @@ -185,12 +193,35 @@ namespace build break; } + // The first character shall not be a separator (we shouldn't have + // been called if that's the case). + // + assert (c.line != ln || c.column != cn); + if (mode_ == lexer_mode::variable) next_mode_ = prev_mode_; return token (lexeme, sep, ln, cn); } + // Assuming the next character is the opening single quote, scan + // the stream until the closing quote (or eos), accumulating + // characters in between in lexeme. Fail if eos is reached before + // the closing quote. + // + void lexer:: + single_quote (string& lexeme) + { + xchar c (get ()); // Opening quote mark. + assert (c == '\''); + + for (c = get (); !eos (c) && c != '\''; c = get ()) + lexeme += c; + + if (eos (c)) + fail (c) << "unterminated single-quoted sequence"; + } + bool lexer:: skip_spaces () { diff --git a/build/root.build b/build/root.build index 5af4637..1afbe80 100644 --- a/build/root.build +++ b/build/root.build @@ -11,3 +11,10 @@ cxx.ext = cxx cxx.std = 14 cxx.poptions += -I$src_root + +# All exe{} in tests/ are, well, tests. +# +tests/: +{ + test.exe = true +} -- cgit v1.1