From 40b71c4777ca110d69d5d61563d032a5ba1355df Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 21 Dec 2009 22:37:20 +0100 Subject: [PATCH] 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. --- parse.cxx | 35 +++++++++++++++++++++------------ testsuite/buildok/semicolon.stp | 18 +++++++++++++++++ 2 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 testsuite/buildok/semicolon.stp diff --git a/parse.cxx b/parse.cxx index 74d7c634e..55ec53fb4 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; } diff --git a/testsuite/buildok/semicolon.stp b/testsuite/buildok/semicolon.stp new file mode 100644 index 000000000..0ec419568 --- /dev/null +++ b/testsuite/buildok/semicolon.stp @@ -0,0 +1,18 @@ +#! stap -p4 + +# Test that semicolons are really optional (in non-block-like context). +# PR11038. + +global x = 0; +probe begin +{ + if (x) log("true") else log("false") + if (x) { log("true") } else { log("false") } + if (x) log("true"); else log("false") + if (x) log("true") else log("false"); +} + +probe end +{ + x = 1; +} -- 2.43.5