From 141693278ef900655efae53990d084058b008a90 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 21 Jul 2016 12:05:31 +0200 Subject: Add support for single line if-blocks So now we can do: if true print true else print false Instead having to do: if true { print true } else { print false } --- build2/parser.cxx | 73 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 23 deletions(-) (limited to 'build2/parser.cxx') diff --git a/build2/parser.cxx b/build2/parser.cxx index 1987945..04accd2 100644 --- a/build2/parser.cxx +++ b/build2/parser.cxx @@ -192,8 +192,8 @@ namespace build2 return make_pair (move (lhs), move (t)); } - void parser:: - clause (token& t, type& tt) + bool parser:: + clause (token& t, type& tt, bool one) { tracer trace ("parser::clause", &path_); @@ -203,7 +203,9 @@ namespace build2 // for if-else blocks, directory scopes, etc., that assume the } token // they see is on the new line. // - while (tt != type::eos) + bool parsed (false); + + while (tt != type::eos && !(one && parsed)) { // Extract attributes if any. // @@ -228,6 +230,11 @@ namespace build2 break; } + // Now we will either parse something or fail. + // + if (!parsed) + parsed = true; + // See if this is one of the directives. // if (tt == type::name && keyword (t)) @@ -689,6 +696,8 @@ namespace build2 fail (t) << "unexpected " << t; } + + return parsed; } void parser:: @@ -1286,33 +1295,51 @@ namespace build2 fail (t) << "expected newline instead of " << t << " after " << k << (k != "else" ? "-expression" : ""); - if (next (t, tt) != type::lcbrace) - fail (t) << "expected { instead of " << t << " at the beginning of " - << k << "-block"; + // This can be a block or a single line. + // + if (next (t, tt) == type::lcbrace) + { + if (next (t, tt) != type::newline) + fail (t) << "expected newline after {"; - if (next (t, tt) != type::newline) - fail (t) << "expected newline after {"; + next (t, tt); - next (t, tt); + if (take) + { + clause (t, tt); + taken = true; + } + else + skip_block (t, tt); - if (take) - { - clause (t, tt); - taken = true; + if (tt != type::rcbrace) + fail (t) << "expected } instead of " << t << " at the end of " << k + << "-block"; + + next (t, tt); + + if (tt == type::newline) + next (t, tt); + else if (tt != type::eos) + fail (t) << "expected newline after }"; } else - skip_block (t, tt); - - if (tt != type::rcbrace) - fail (t) << "expected } instead of " << t << " at the end of " << k - << "-block"; + { + if (take) + { + if (!clause (t, tt, true)) + fail (t) << "expected " << k << "-line instead of " << t; - next (t, tt); + taken = true; + } + else + { + skip_line (t, tt); - if (tt == type::newline) - next (t, tt); - else if (tt != type::eos) - fail (t) << "expected newline after }"; + if (tt == type::newline) + next (t, tt); + } + } // See if we have another el* keyword. // -- cgit v1.1