aboutsummaryrefslogtreecommitdiff
path: root/build2/parser.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-07-21 12:05:31 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-07-21 12:05:31 +0200
commit141693278ef900655efae53990d084058b008a90 (patch)
tree5b247e57d279a5f40e380d8ca35e871332d82712 /build2/parser.cxx
parent4a5c11f559e72bb6f5d8c28815c57c1690408f29 (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/parser.cxx')
-rw-r--r--build2/parser.cxx73
1 files changed, 50 insertions, 23 deletions
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.
//