summaryrefslogtreecommitdiffstats
path: root/parse.cxx
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-12-21 22:37:20 +0100
committerMark Wielaard <mjw@redhat.com>2009-12-21 22:37:20 +0100
commit40b71c4777ca110d69d5d61563d032a5ba1355df (patch)
treee383554e3b6a49f729f6a381a28b57ecbce33571 /parse.cxx
parentc6fcc4c1ca5f222cf90bf3968e34a10f09b30be4 (diff)
downloadsystemtap-steved-40b71c4777ca110d69d5d61563d032a5ba1355df.tar.gz
systemtap-steved-40b71c4777ca110d69d5d61563d032a5ba1355df.tar.xz
systemtap-steved-40b71c4777ca110d69d5d61563d032a5ba1355df.zip
PR11038 Trailing semicolon as null-statement confusing.
* parse.cxx (parser::parse_statement): Squash semicolon after non-block-like statements. * testsuite/buildok/semicolon.stp: New test.
Diffstat (limited to 'parse.cxx')
-rw-r--r--parse.cxx35
1 files changed, 22 insertions, 13 deletions
diff --git a/parse.cxx b/parse.cxx
index 74d7c634..55ec53fb 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -1207,6 +1207,7 @@ parser::parse_stmt_block ()
statement*
parser::parse_statement ()
{
+ statement *ret;
const token* t = peek ();
if (t && t->type == tok_operator && t->content == ";")
{
@@ -1215,34 +1216,42 @@ parser::parse_statement ()
return n;
}
else if (t && t->type == tok_operator && t->content == "{")
- return parse_stmt_block ();
+ return parse_stmt_block (); // Don't squash semicolons.
else if (t && t->type == tok_keyword && t->content == "if")
- return parse_if_statement ();
+ return parse_if_statement (); // Don't squash semicolons.
else if (t && t->type == tok_keyword && t->content == "for")
- return parse_for_loop ();
+ return parse_for_loop (); // Don't squash semicolons.
else if (t && t->type == tok_keyword && t->content == "foreach")
- return parse_foreach_loop ();
+ return parse_foreach_loop (); // Don't squash semicolons.
+ else if (t && t->type == tok_keyword && t->content == "while")
+ return parse_while_loop (); // Don't squash semicolons.
else if (t && t->type == tok_keyword && t->content == "return")
- return parse_return_statement ();
+ ret = parse_return_statement ();
else if (t && t->type == tok_keyword && t->content == "delete")
- return parse_delete_statement ();
- else if (t && t->type == tok_keyword && t->content == "while")
- return parse_while_loop ();
+ ret = parse_delete_statement ();
else if (t && t->type == tok_keyword && t->content == "break")
- return parse_break_statement ();
+ ret = parse_break_statement ();
else if (t && t->type == tok_keyword && t->content == "continue")
- return parse_continue_statement ();
+ ret = parse_continue_statement ();
else if (t && t->type == tok_keyword && t->content == "next")
- return parse_next_statement ();
- // XXX: "do/while" statement?
+ ret = parse_next_statement ();
else if (t && (t->type == tok_operator || // expressions are flexible
t->type == tok_identifier ||
t->type == tok_number ||
t->type == tok_string))
- return parse_expr_statement ();
+ ret = parse_expr_statement ();
// XXX: consider generally accepting tok_embedded here too
else
throw parse_error ("expected statement");
+
+ // Squash "empty" trailing colons after any "non-block-like" statement.
+ t = peek ();
+ if (t && t->type == tok_operator && t->content == ";")
+ {
+ next (); // Silently eat trailing ; after statement
+ }
+
+ return ret;
}