@@ -89,12 +89,14 @@ inline std::ostream& operator<<(std::ostream& out, const OptionalConst& oc) {
8989// forbidden in C++. We avoid the problem using a typedef.
9090typedef const IR::Type ConstType;
9191
92- struct NameTypePair {
92+ struct DeclaratorInfo {
93+ Util::SourceInfo srcInfo;
9394 const IR::ID *name;
9495 const IR::Type *type;
96+ const IR::Expression *init;
9597};
9698
97- inline std::ostream &operator<<(std::ostream &out, const NameTypePair &nt) {
99+ inline std::ostream &operator<<(std::ostream &out, const DeclaratorInfo &nt) {
98100 return out << nt.name << ":" << nt.type;
99101}
100102
@@ -271,7 +273,8 @@ using namespace P4;
271273
272274
273275%type<IR::ID*> name dot_name nonTypeName nonTableKwName annotationName
274- %type<NameTypePair> declarator
276+ %type<DeclaratorInfo> declarator
277+ %type<std::vector<DeclaratorInfo>> declaratorList initDeclaratorList
275278%type<IR::Direction> direction
276279%type<IR::Path*> prefixedNonTypeName prefixedType
277280%type<IR::IndexedVector<IR::Type_Var>*> typeParameterList
@@ -308,20 +311,20 @@ using namespace P4;
308311 forStatement breakStatement continueStatement
309312%type<IR::BlockStatement*> blockStatement parserBlockStatement controlBody
310313 optObjInitializer
311- %type<IR::StatOrDecl*> statementOrDeclaration parserStatement
312- declOrAssignmentOrMethodCallStatement
313- %type<IR::IndexedVector<IR::StatOrDecl>*> objDeclarations statOrDeclList parserStatements
314+ %type<IR::StatOrDecl*> declOrAssignmentOrMethodCallStatement
315+ %type<IR::IndexedVector<IR::StatOrDecl>*> objDeclarations parserStatement
316+ statementOrDeclaration parserStatements statOrDeclList
314317 forInitStatements forInitStatementsNonEmpty
315318 forUpdateStatements forUpdateStatementsNonEmpty
316319%type<IR::SwitchCase*> switchCase
317320%type<IR::Vector<IR::SwitchCase>*> switchCases
318321%type<IR::Vector<IR::Type>*> typeArgumentList realTypeArgumentList
319322%type<IR::ParserState*> parserState
320323%type<IR::IndexedVector<IR::ParserState>*> parserStates
321- %type<IR::Declaration*> constantDeclaration actionDeclaration
322- variableDeclaration variableDeclarationWithoutSemicolon instantiation functionDeclaration
323- objDeclaration tableDeclaration controlLocalDeclaration
324- parserLocalElement valueSetDeclaration
324+ %type<IR::IndexedVector<IR:: Declaration> *> constantDeclaration variableDeclaration parserLocalElement controlLocalDeclaration
325+ %type<IR::Declaration*> actionDeclaration variableDeclarationWithoutSemicolon instantiation
326+ functionDeclaration objDeclaration tableDeclaration
327+ valueSetDeclaration
325328%type<IR::Type_Declaration*> headerTypeDeclaration structTypeDeclaration
326329 headerUnionDeclaration derivedTypeDeclaration
327330 parserDeclaration controlDeclaration enumDeclaration
@@ -332,8 +335,7 @@ using namespace P4;
332335%type<IR::Type_Parser*> parserTypeDeclaration
333336%type<IR::Type_Control*> controlTypeDeclaration
334337%type<IR::IndexedVector<IR::Declaration>*> parserLocalElements controlLocalDeclarations
335- %type<IR::StructField*> structField
336- %type<IR::IndexedVector<IR::StructField>*> structFieldList
338+ %type<IR::IndexedVector<IR::StructField>*> structField structFieldList
337339%type<IR::IndexedVector<IR::SerEnumMember>*> specifiedIdentifierList
338340%type<IR::SerEnumMember*> specifiedIdentifier
339341%type<IR::Method*> methodPrototype functionPrototype
@@ -485,10 +487,14 @@ p4rtControllerType
485487program : input END { YYACCEPT; };
486488
487489input
488- : %empty { driver.result = $$ = new IR::P4Program; }
489- | input declaration { if ($2) $1->objects.push_back($2->getNode());
490- $$ = $1; }
491- | input ";" { $$ = $1; } // empty declaration
490+ : %empty { driver.result = $$ = new IR::P4Program; }
491+ | input declaration { $$ = $1;
492+ if (!$2) { /* do nothing */ }
493+ else if (auto *v = $2->to<IR::VectorBase>())
494+ $$->objects.append(*v);
495+ else
496+ $$->objects.push_back($2); }
497+ | input ";" { $$ = $1; } // empty declaration
492498 ;
493499
494500declaration
@@ -841,14 +847,14 @@ parserDeclaration
841847
842848parserLocalElements
843849 : %empty { $$ = new IR::IndexedVector<IR::Declaration>(); }
844- | parserLocalElements parserLocalElement { $$ = $1; $$->push_back( $2); $$->srcInfo = @1 + @2; }
850+ | parserLocalElements parserLocalElement { $$ = $1; $$->append(* $2); $$->srcInfo = @1 + @2; }
845851 ;
846852
847853parserLocalElement
848854 : constantDeclaration { $$ = $1; }
849- | instantiation { $$ = $1 ; }
855+ | instantiation { $$ = new IR::IndexedVector<IR::Declaration>($1) ; }
850856 | variableDeclaration { $$ = $1; }
851- | valueSetDeclaration { $$ = $1 ; }
857+ | valueSetDeclaration { $$ = new IR::IndexedVector<IR::Declaration>($1) ; }
852858 ;
853859
854860parserTypeDeclaration
@@ -876,17 +882,17 @@ parserState
876882
877883parserStatements
878884 : %empty { $$ = new IR::IndexedVector<IR::StatOrDecl>(); }
879- | parserStatements parserStatement { $$ = $1; $1->push_back( $2); $$->srcInfo = @1 + @2; }
885+ | parserStatements parserStatement { $$ = $1; $1->append(* $2); $$->srcInfo = @1 + @2; }
880886 ;
881887
882888parserStatement
883- : assignmentOrMethodCallStatement { $$ = $1 ; }
884- | directApplication { $$ = $1 ; }
885- | emptyStatement { $$ = $1 ; }
886- | variableDeclaration { $$ = $1 ; }
887- | constantDeclaration { $$ = $1 ; }
888- | parserBlockStatement { $$ = $1 ; }
889- | conditionalStatement { $$ = $1 ; }
889+ : assignmentOrMethodCallStatement { $$ = new IR::IndexedVector<IR::StatOrDecl>($1) ; }
890+ | directApplication { $$ = new IR::IndexedVector<IR::StatOrDecl>($1) ; }
891+ | emptyStatement { $$ = new IR::IndexedVector<IR::StatOrDecl>($1) ; }
892+ | variableDeclaration { $$ = new IR::IndexedVector<IR::StatOrDecl>($1->begin(), $1->end()) ; }
893+ | constantDeclaration { $$ = new IR::IndexedVector<IR::StatOrDecl>($1->begin(), $1->end()) ; }
894+ | parserBlockStatement { $$ = new IR::IndexedVector<IR::StatOrDecl>($1) ; }
895+ | conditionalStatement { $$ = new IR::IndexedVector<IR::StatOrDecl>($1) ; }
890896 ;
891897
892898parserBlockStatement
@@ -992,14 +998,16 @@ controlTypeDeclaration
992998
993999controlLocalDeclarations
9941000 : %empty { $$ = new IR::IndexedVector<IR::Declaration>(); }
995- | controlLocalDeclarations controlLocalDeclaration { $$ = $1; $$->push_back($2); $$->srcInfo = @1 + @2; }
1001+ | controlLocalDeclarations controlLocalDeclaration {
1002+ ($$ = $1)->append(*$2);
1003+ $$->srcInfo = @1 + @2; }
9961004 ;
9971005
9981006controlLocalDeclaration
9991007 : constantDeclaration { $$ = $1; }
1000- | actionDeclaration { $$ = $1 ; }
1001- | tableDeclaration { $$ = $1 ; }
1002- | instantiation { $$ = $1 ; }
1008+ | actionDeclaration { $$ = new IR::IndexedVector<IR::Declaration>($1) ; }
1009+ | tableDeclaration { $$ = new IR::IndexedVector<IR::Declaration>($1) ; }
1010+ | instantiation { $$ = new IR::IndexedVector<IR::Declaration>($1) ; }
10031011 | variableDeclaration { $$ = $1; }
10041012 ;
10051013
@@ -1212,11 +1220,23 @@ headerUnionDeclaration
12121220
12131221structFieldList
12141222 : %empty { $$ = new IR::IndexedVector<IR::StructField>(); }
1215- | structFieldList structField { $$ = $1; $1->push_back( $2); $$->srcInfo = @1 + @2; }
1223+ | structFieldList structField { $$ = $1; $1->append(* $2); $$->srcInfo = @1 + @2; }
12161224 ;
12171225
12181226structField
1219- : optAnnotations typeRef declarator ";" { $$ = new IR::StructField(@3, *$3.name, *$1, $3.type); }
1227+ : optAnnotations typeRef declaratorList ";" {
1228+ $$ = new IR::IndexedVector<IR::StructField>();
1229+ for (auto &decl : $3)
1230+ $$->push_back(new IR::StructField(decl.srcInfo, *decl.name, *$1, decl.type)); }
1231+ ;
1232+
1233+ declaratorList
1234+ : declarator { $$.emplace_back($1); }
1235+ | declaratorList "," <ConstType*>{ $$ = $<ConstType*>0; } declarator {
1236+ if ($1.size() == 1)
1237+ warning(ErrorType::WARN_EXTENSION,
1238+ "%1%Multiple declarators is a non-standard extension", @4);
1239+ ($$=$1).emplace_back($4); }
12201240 ;
12211241
12221242enumDeclaration
@@ -1349,15 +1369,15 @@ continueStatement
13491369// To support direct invocation of a control or parser without instantiation
13501370directApplication
13511371 : typeName "." APPLY "(" argumentList ")" ";" {
1352- auto method = new IR::Member(
1353- @1 + @3, new IR::TypeNameExpression($1), IR::ID(@3, "apply"_cs));
1354- auto mce = new IR::MethodCallExpression(@1 + @6, method, $5);
1355- $$ = new IR::MethodCallStatement(@1 + @6, mce); }
1372+ auto method = new IR::Member(@1 + @3, new IR::TypeNameExpression($1),
1373+ IR::ID(@3, "apply"_cs));
1374+ auto mce = new IR::MethodCallExpression(@1 + @6, method, $5);
1375+ $$ = new IR::MethodCallStatement(@1 + @6, mce); }
13561376 | specializedType "." APPLY "(" argumentList ")" ";" {
1357- auto method = new IR::Member(
1358- @1 + @3, new IR::TypeNameExpression($1), IR::ID(@3, "apply"_cs));
1359- auto mce = new IR::MethodCallExpression(@1 + @6, method, $5);
1360- $$ = new IR::MethodCallStatement(@1 + @6, mce); }
1377+ auto method = new IR::Member(@1 + @3, new IR::TypeNameExpression($1),
1378+ IR::ID(@3, "apply"_cs));
1379+ auto mce = new IR::MethodCallExpression(@1 + @6, method, $5);
1380+ $$ = new IR::MethodCallStatement(@1 + @6, mce); }
13611381 ;
13621382
13631383statement
@@ -1382,7 +1402,7 @@ blockStatement
13821402
13831403statOrDeclList
13841404 : %empty { $$ = new IR::IndexedVector<IR::StatOrDecl>(); }
1385- | statOrDeclList statementOrDeclaration { $$ = $1; $$->push_back( $2); $$->srcInfo = @1 + @2; }
1405+ | statOrDeclList statementOrDeclaration { $$ = $1; $$->append(* $2); $$->srcInfo = @1 + @2; }
13861406 ;
13871407
13881408switchStatement
@@ -1406,14 +1426,14 @@ switchLabel
14061426 ;
14071427
14081428statementOrDeclaration
1409- : variableDeclaration { $$ = $1 ; }
1410- | constantDeclaration { $$ = $1 ; }
1411- | statement { $$ = $1 ; }
1429+ : variableDeclaration { $$ = new IR::IndexedVector<IR::StatOrDecl>($1->begin(), $1->end()) ; }
1430+ | constantDeclaration { $$ = new IR::IndexedVector<IR::StatOrDecl>($1->begin(), $1->end()) ; }
1431+ | statement { $$ = new IR::IndexedVector<IR::StatOrDecl>($1) ; }
14121432 // The transition to instantiation below is not required by the
14131433 // languge spec, but it does help p4c give a more clear error
14141434 // message if one erroneously attempts to perform an
14151435 // instantiation inside of a block.
1416- | instantiation { $$ = $1 ; }
1436+ | instantiation { $$ = new IR::IndexedVector<IR::StatOrDecl>($1) ; }
14171437 ;
14181438
14191439forStatement
@@ -1566,7 +1586,18 @@ actionDeclaration
15661586/************************* VARIABLES *****************************/
15671587
15681588variableDeclaration
1569- : variableDeclarationWithoutSemicolon ";" { $$ = $1; }
1589+ : annotations typeRef initDeclaratorList ";" {
1590+ $$ = new IR::IndexedVector<IR::Declaration>();
1591+ for (auto &decl : $3) {
1592+ $$->push_back(new IR::Declaration_Variable(decl.srcInfo, *decl.name, *$1,
1593+ decl.type, decl.init));
1594+ driver.structure->declareObject(*decl.name, decl.type->toString()); } }
1595+ | typeRef initDeclaratorList ";" {
1596+ $$ = new IR::IndexedVector<IR::Declaration>();
1597+ for (auto &decl : $2) {
1598+ $$->push_back(new IR::Declaration_Variable(decl.srcInfo, *decl.name,
1599+ decl.type, decl.init));
1600+ driver.structure->declareObject(*decl.name, decl.type->toString()); } }
15701601 ;
15711602
15721603variableDeclarationWithoutSemicolon
@@ -1579,15 +1610,27 @@ variableDeclarationWithoutSemicolon
15791610 ;
15801611
15811612constantDeclaration
1582- : optAnnotations CONST typeRef declarator "=" initializer ";"
1583- { $$ = new IR::Declaration_Constant(@4, *$4.name, *$1, $4.type, $6);
1584- driver.structure->declareObject(*$4.name, $4.type->toString()); }
1613+ : optAnnotations CONST typeRef initDeclaratorList ";" {
1614+ $$ = new IR::IndexedVector<IR::Declaration>();
1615+ for (auto &decl : $4) {
1616+ if (!decl.init)
1617+ P4::error(ErrorType::ERR_EXPECTED,
1618+ "Const %1% declaration requires an initializer", decl.name);
1619+ $$->push_back(new IR::Declaration_Constant(decl.srcInfo, *decl.name, *$1,
1620+ decl.type, decl.init));
1621+ driver.structure->declareObject(*decl.name, decl.type->toString()); } }
15851622 ;
15861623
15871624declarator
1588- : name { $$.name = $1; $$.type = $<ConstType *>0; }
1589- | declarator "[" expression "]"
1590- { $$ = $1; $$.type = new IR::Type_Array(@2+@4, $1.type, $3); }
1625+ : name { $$.srcInfo = @1;
1626+ $$.name = $1;
1627+ $$.type = $<ConstType *>0;
1628+ $$.init = nullptr; }
1629+ | declarator "[" expression "]" {
1630+ $$ = $1;
1631+ $$.srcInfo += @4;
1632+ $$.type = new IR::Type_Array(@2+@4, $1.type, $3);
1633+ $$.init = nullptr; }
15911634 ;
15921635
15931636optInitializer
@@ -1599,6 +1642,18 @@ initializer
15991642 : expression { $$ = $1; }
16001643 ;
16011644
1645+ initDeclaratorList
1646+ : declarator optInitializer {
1647+ $$.emplace_back($1);
1648+ $$.back().init = $2; }
1649+ | initDeclaratorList "," <ConstType*>{ $$ = $<ConstType*>0; } declarator optInitializer {
1650+ if ($1.size() == 1)
1651+ warning(ErrorType::WARN_EXTENSION,
1652+ "%1%Multiple declarators is a non-standard extension", @4);
1653+ ($$=$1).emplace_back($4);
1654+ $$.back().init = $5; }
1655+ ;
1656+
16021657/**************** Expressions ****************/
16031658
16041659functionDeclaration
0 commit comments