diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2016-07-21 12:05:31 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2016-07-21 12:05:31 +0200 |
commit | 141693278ef900655efae53990d084058b008a90 (patch) | |
tree | 5b247e57d279a5f40e380d8ca35e871332d82712 /build2 | |
parent | 4a5c11f559e72bb6f5d8c28815c57c1690408f29 (diff) |
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
}
Diffstat (limited to 'build2')
-rw-r--r-- | build2/parser | 11 | ||||
-rw-r--r-- | build2/parser.cxx | 73 |
2 files changed, 59 insertions, 25 deletions
diff --git a/build2/parser b/build2/parser index 0962348..af5c500 100644 --- a/build2/parser +++ b/build2/parser @@ -56,8 +56,15 @@ namespace build2 // Recursive descent parser. // protected: - void - clause (token&, token_type&); + // If one is true then parse a single (logical) line (logical means it + // can actually be several lines, e.g., an if-block). Return false if + // nothing has been parsed (i.e., we are on the same token). + // + // Note that after this function returns, the token is the first token on + // the next line (or eos). + // + bool + clause (token&, token_type&, bool one = false); void print (token&, token_type&); 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. // |