From d2bee691d8f05af0adbc78318c730560c1cb4d6e Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 4 Nov 2016 08:44:31 +0200 Subject: Use variable lookup hook in testscript parser --- build2/test/script/lexer | 2 +- build2/test/script/lexer.cxx | 5 +++++ build2/test/script/parser | 9 ++++++++- build2/test/script/parser.cxx | 23 ++++++++++++++++------- unit-tests/test/script/lexer/script-line.test | 5 +++++ 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/build2/test/script/lexer b/build2/test/script/lexer index f3d8fa9..99f87c0 100644 --- a/build2/test/script/lexer +++ b/build2/test/script/lexer @@ -25,7 +25,7 @@ namespace build2 enum { script_line = base_type::value_next, - variable_line, + variable_line, // Auto-expires at the end of the line. test_line, command_line, here_line diff --git a/build2/test/script/lexer.cxx b/build2/test/script/lexer.cxx index 3367d52..324e577 100644 --- a/build2/test/script/lexer.cxx +++ b/build2/test/script/lexer.cxx @@ -119,6 +119,11 @@ namespace build2 { case '\n': { + // Expire variable value mode at the end of the line. + // + if (m == lexer_mode::variable_line) + state_.pop (); + return make_token (type::newline); } diff --git a/build2/test/script/parser b/build2/test/script/parser index 55dc003..ea0cadb 100644 --- a/build2/test/script/parser +++ b/build2/test/script/parser @@ -39,7 +39,8 @@ namespace build2 // // Each parse function receives the token/type from which it should // start consuming. On return the token/type should contain the first - // token that has not been consumed. + // token that has not been consumed. For *_line() functions this is + // the newline. // protected: void @@ -60,6 +61,12 @@ namespace build2 string parse_here_document (token&, token_type&, const string&); + // Customization hooks. + // + protected: + virtual lookup + lookup_variable (name&&, string&&, const location&) override; + protected: using base_parser = build2::parser; diff --git a/build2/test/script/parser.cxx b/build2/test/script/parser.cxx index 827aae7..4948679 100644 --- a/build2/test/script/parser.cxx +++ b/build2/test/script/parser.cxx @@ -48,7 +48,7 @@ namespace build2 void parser:: parse_script (token& t, token_type& tt) { - while (tt != type::eos) + for (; tt != type::eos; next (t, tt)) { parse_script_line (t, tt); } @@ -120,6 +120,9 @@ namespace build2 // value rhs (variable_value (t, tt, lexer_mode::variable_line)); + if (tt != type::newline) + fail (t) << "unexpected " << t; + value& lhs (kind == type::assign ? script_->assign (var) : script_->append (var)); @@ -505,7 +508,7 @@ namespace build2 // Parse here-document fragments in the order they were mentioned on // the command line. // - if (!hd.empty ()) + for (redirect& r: hd) { // Switch to the here-line mode which is like double-quoted but // recognized the newline as a separator. @@ -515,13 +518,10 @@ namespace build2 // The end marker is temporarily stored as the redirect's value. // - for (redirect& r: hd) - r.value = parse_here_document (t, tt, r.value); + r.value = parse_here_document (t, tt, r.value); expire_mode (); } - else - next (t, tt); // Now that we have all the pieces, run the test. // @@ -600,9 +600,18 @@ namespace build2 if (tt == type::eos) fail (t) << "missing here-document end marker '" << em << "'"; - next (t, tt); return r; } + + lookup parser:: + lookup_variable (name&& qual, string&& name, const location& l) + { + if (!qual.empty ()) + fail (l) << "qualified variable name"; + + const variable& var (script_->var_pool.insert (move (name))); + return script_->find (var); + } } } } diff --git a/unit-tests/test/script/lexer/script-line.test b/unit-tests/test/script/lexer/script-line.test index 3bd1f0e..79dd9a6 100644 --- a/unit-tests/test/script/lexer/script-line.test +++ b/unit-tests/test/script/lexer/script-line.test @@ -1,2 +1,7 @@ foo bar +$cxx.target.class +foo = baz +$foo +fox = $foo-$cxx.target.class +$fox -- cgit v1.1