Skip to content

Commit

Permalink
[parser] fix semicolon after if statements
Browse files Browse the repository at this point in the history
If we have two if statements, before the first if statmenet there's no
other statement and between the two stamenets there's another statement,
our parser will complain there's no semicolon after our first if
statement. This commit tries to fix it.

Fixes: #544
  • Loading branch information
mmarchini committed Apr 15, 2019
1 parent 7065bfb commit 13de974
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 14 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Expand Up @@ -44,7 +44,7 @@ include_directories(SYSTEM ${LIBELF_INCLUDE_DIRS})

find_package(BISON REQUIRED)
find_package(FLEX REQUIRED)
bison_target(bison_parser src/parser.yy ${CMAKE_BINARY_DIR}/parser.tab.cc)
bison_target(bison_parser src/parser.yy ${CMAKE_BINARY_DIR}/parser.tab.cc VERBOSE)
flex_target(flex_lexer src/lexer.l ${CMAKE_BINARY_DIR}/lex.yy.cc)
add_flex_bison_dependency(flex_lexer bison_parser)
add_library(parser ${BISON_bison_parser_OUTPUTS} ${FLEX_flex_lexer_OUTPUTS})
Expand Down
18 changes: 8 additions & 10 deletions src/parser.yy
Expand Up @@ -94,8 +94,8 @@ void yyerror(bpftrace::Driver &driver, const char *s);
%type <ast::Probe *> probe
%type <ast::Predicate *> pred
%type <ast::Ternary *> ternary
%type <ast::StatementList *> block stmts block_stmts
%type <ast::Statement *> block_stmt stmt
%type <ast::StatementList *> block stmts
%type <ast::Statement *> block_stmt stmt semicolon_ended_stmt
%type <ast::Expression *> expr
%type <ast::Call *> call
%type <ast::Map *> map
Expand Down Expand Up @@ -173,19 +173,17 @@ ternary : expr QUES expr COLON expr { $$ = new ast::Ternary($1, $3, $5); }
param : DOLLAR INT { $$ = new ast::PositionalParameter($2); }

block : "{" stmts "}" { $$ = $2; }
| "{" stmts ";" "}" { $$ = $2; }
;

stmts : stmts ";" stmt { $$ = $1; $1->push_back($3); }
| stmts ";" block_stmts stmt { $$ = $1; $1->insert($1->end(), $3->begin(), $3->end()); $1->push_back($4); }
| stmts ";" block_stmts { $$ = $1; $1->insert($1->end(), $3->begin(), $3->end()); }
| block_stmts { $$ = $1; }
semicolon_ended_stmt: stmt ";" { $$ = $1; }
;

stmts : semicolon_ended_stmt stmts { $$ = $2; $2->insert($2->begin(), $1); }
| block_stmt stmts { $$ = $2; $2->insert($2->begin(), $1); }
| stmt { $$ = new ast::StatementList; $$->push_back($1); }
| { $$ = new ast::StatementList; }
;

block_stmts : block_stmts block_stmt { $$ = $1; $1->push_back($2); }
| block_stmt { $$ = new ast::StatementList; $$->push_back($1); }

block_stmt : IF "(" expr ")" block { $$ = new ast::If($3, $5); }
| IF "(" expr ")" block ELSE block { $$ = new ast::If($3, $5, $7); }
| UNROLL "(" INT ")" block { $$ = new ast::Unroll($3, $5); }
Expand Down
2 changes: 1 addition & 1 deletion tests/codegen/if_else_variable.cpp
Expand Up @@ -6,7 +6,7 @@ namespace codegen {

TEST(codegen, if_else_variable)
{
test("kprobe:f { if (pid > 10000) { $s = 10 } else { $s = 20 }; printf(\"s = %d\", $s) }",
test("kprobe:f { if (pid > 10000) { $s = 10 } else { $s = 20 } printf(\"s = %d\", $s) }",

R"EXPECTED(%printf_t = type { i64, i64 }
Expand Down
2 changes: 1 addition & 1 deletion tests/codegen/if_variable.cpp
Expand Up @@ -6,7 +6,7 @@ namespace codegen {

TEST(codegen, if_variable)
{
test("kprobe:f { if (pid > 10000) { $s = 10 }; printf(\"s = %d\", $s); }",
test("kprobe:f { if (pid > 10000) { $s = 10 } printf(\"s = %d\", $s); }",

#if LLVM_VERSION_MAJOR < 6
R"EXPECTED(%printf_t = type { i64, i64 }
Expand Down
28 changes: 27 additions & 1 deletion tests/parser.cpp
Expand Up @@ -381,6 +381,32 @@ TEST(Parser, if_block)
" builtin: pid\n");
}

TEST(Parser, if_stmt_if)
{
test("kprobe:sys_open { if (pid > 10000) { printf(\"%d is high\\n\", pid); } @pid = pid; if (pid < 1000) { printf(\"%d is low\\n\", pid); } }",
"Program\n"
" kprobe:sys_open\n"
" if\n"
" >\n"
" builtin: pid\n"
" int: 10000\n"
" then\n"
" call: printf\n"
" string: %d is high\\n\n"
" builtin: pid\n"
" =\n"
" map: @pid\n"
" builtin: pid\n"
" if\n"
" <\n"
" builtin: pid\n"
" int: 1000\n"
" then\n"
" call: printf\n"
" string: %d is low\\n\n"
" builtin: pid\n");
}

TEST(Parser, if_block_variable)
{
test("kprobe:sys_open { if (pid > 10000) { $s = 10; } }",
Expand All @@ -398,7 +424,7 @@ TEST(Parser, if_block_variable)

TEST(Parser, if_else)
{
test("kprobe:sys_open { if (pid > 10000) { $s = \"a\"; } else { $s= \"b\"; }; printf(\"%d is high\\n\", pid, $s); }",
test("kprobe:sys_open { if (pid > 10000) { $s = \"a\"; } else { $s= \"b\"; } printf(\"%d is high\\n\", pid, $s); }",
"Program\n"
" kprobe:sys_open\n"
" if\n"
Expand Down

0 comments on commit 13de974

Please sign in to comment.