diff --git a/frontends/parsers/p4/p4parser.ypp b/frontends/parsers/p4/p4parser.ypp index 74d4b2852cf..229c0abc4a5 100644 --- a/frontends/parsers/p4/p4parser.ypp +++ b/frontends/parsers/p4/p4parser.ypp @@ -289,16 +289,16 @@ using namespace P4; %type> identifierList %type selectCase %type> selectCaseList -%type statement emptyStatement returnStatement +%type statement parserStatement emptyStatement returnStatement switchStatement exitStatement - assignmentOrMethodCallStatement conditionalStatement + assignmentOrMethodCallStatement conditionalStatement parserConditionalStatement assignmentOrMethodCallStatementWithoutSemicolon forStatement breakStatement continueStatement %type blockStatement parserBlockStatement controlBody optObjInitializer -%type statementOrDeclaration parserStatement +%type statementOrDeclaration parserStatementOrDeclaration declOrAssignmentOrMethodCallStatement -%type> objDeclarations statOrDeclList parserStatements +%type> objDeclarations statOrDeclList parserStatOrDeclList forInitStatements forInitStatementsNonEmpty forUpdateStatements forUpdateStatementsNonEmpty %type switchCase @@ -859,29 +859,41 @@ parserStates parserState : optAnnotations STATE name { driver.structure->pushContainerType($3, false); } - "{" parserStatements transitionStatement "}" { + "{" parserStatOrDeclList transitionStatement "}" { driver.structure->pop(); $$ = new IR::ParserState(@3, std::move($3), std::move($1), std::move($6), $7); } ; -parserStatements - : %empty { $$ = {}; } - | parserStatements parserStatement { ($$ = std::move($1)).push_back($2); $$.srcInfo = @1 + @2; } - ; - parserStatement : assignmentOrMethodCallStatement { $$ = $1; } | emptyStatement { $$ = $1; } - | variableDeclaration { $$ = $1; } - | constantDeclaration { $$ = $1; } | parserBlockStatement { $$ = $1; } - | conditionalStatement { $$ = $1; } + | parserConditionalStatement { $$ = $1; } + ; + +parserStatementOrDeclaration + : variableDeclaration { $$ = $1; } + | constantDeclaration { $$ = $1; } + | parserStatement { $$ = $1; } + ; + +parserStatOrDeclList + : %empty { $$ = {}; } + | parserStatOrDeclList parserStatementOrDeclaration { ($$ = std::move($1)).push_back($2); + $$.srcInfo = @1 + @2; } ; parserBlockStatement - : optAnnotations "{" { driver.structure->pushNamespace(@2, false); } - parserStatements "}" { driver.structure->pop(); - $$ = new IR::BlockStatement(@1+@5, std::move($1), std::move($4)); } + : optAnnotations "{" { driver.structure->pushNamespace(@2, false); } + parserStatOrDeclList "}" { driver.structure->pop(); + $$ = new IR::BlockStatement(@1+@5, std::move($1), std::move($4)); } + ; + +parserConditionalStatement + : IF "(" expression ")" parserStatement %prec THEN + { $$ = new IR::IfStatement(@1, $3, $5, nullptr); } + | IF "(" expression ")" parserStatement ELSE parserStatement %prec THEN + { $$ = new IR::IfStatement(@1, $3, $5, $7); } ; transitionStatement