@@ -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
@@ -1209,11 +1217,23 @@ headerUnionDeclaration
12091217
12101218structFieldList
12111219 : %empty { $$ = new IR::IndexedVector<IR::StructField>(); }
1212- | structFieldList structField { $$ = $1; $1->push_back( $2); $$->srcInfo = @1 + @2; }
1220+ | structFieldList structField { $$ = $1; $1->append(* $2); $$->srcInfo = @1 + @2; }
12131221 ;
12141222
12151223structField
1216- : optAnnotations typeRef declarator ";" { $$ = new IR::StructField(@3, *$3.name, *$1, $3.type); }
1224+ : optAnnotations typeRef declaratorList ";" {
1225+ $$ = new IR::IndexedVector<IR::StructField>();
1226+ for (auto &decl : $3)
1227+ $$->push_back(new IR::StructField(decl.srcInfo, *decl.name, *$1, decl.type)); }
1228+ ;
1229+
1230+ declaratorList
1231+ : declarator { $$.emplace_back($1); }
1232+ | declaratorList "," <ConstType*>{ $$ = $<ConstType*>0; } declarator {
1233+ if ($1.size() == 1)
1234+ warning(ErrorType::WARN_EXTENSION,
1235+ "%1%Multiple declarators is a non-standard extension", @4);
1236+ ($$=$1).emplace_back($4); }
12171237 ;
12181238
12191239enumDeclaration
@@ -1346,15 +1366,15 @@ continueStatement
13461366// To support direct invocation of a control or parser without instantiation
13471367directApplication
13481368 : typeName "." APPLY "(" argumentList ")" ";" {
1349- auto method = new IR::Member(
1350- @1 + @3, new IR::TypeNameExpression($1), IR::ID(@3, "apply"_cs));
1351- auto mce = new IR::MethodCallExpression(@1 + @6, method, $5);
1352- $$ = new IR::MethodCallStatement(@1 + @6, mce); }
1369+ auto method = new IR::Member(@1 + @3, new IR::TypeNameExpression($1),
1370+ IR::ID(@3, "apply"_cs));
1371+ auto mce = new IR::MethodCallExpression(@1 + @6, method, $5);
1372+ $$ = new IR::MethodCallStatement(@1 + @6, mce); }
13531373 | specializedType "." APPLY "(" argumentList ")" ";" {
1354- auto method = new IR::Member(
1355- @1 + @3, new IR::TypeNameExpression($1), IR::ID(@3, "apply"_cs));
1356- auto mce = new IR::MethodCallExpression(@1 + @6, method, $5);
1357- $$ = new IR::MethodCallStatement(@1 + @6, mce); }
1374+ auto method = new IR::Member(@1 + @3, new IR::TypeNameExpression($1),
1375+ IR::ID(@3, "apply"_cs));
1376+ auto mce = new IR::MethodCallExpression(@1 + @6, method, $5);
1377+ $$ = new IR::MethodCallStatement(@1 + @6, mce); }
13581378 ;
13591379
13601380statement
@@ -1379,7 +1399,7 @@ blockStatement
13791399
13801400statOrDeclList
13811401 : %empty { $$ = new IR::IndexedVector<IR::StatOrDecl>(); }
1382- | statOrDeclList statementOrDeclaration { $$ = $1; $$->push_back( $2); $$->srcInfo = @1 + @2; }
1402+ | statOrDeclList statementOrDeclaration { $$ = $1; $$->append(* $2); $$->srcInfo = @1 + @2; }
13831403 ;
13841404
13851405switchStatement
@@ -1403,14 +1423,14 @@ switchLabel
14031423 ;
14041424
14051425statementOrDeclaration
1406- : variableDeclaration { $$ = $1 ; }
1407- | constantDeclaration { $$ = $1 ; }
1408- | statement { $$ = $1 ; }
1426+ : variableDeclaration { $$ = new IR::IndexedVector<IR::StatOrDecl>($1->begin(), $1->end()) ; }
1427+ | constantDeclaration { $$ = new IR::IndexedVector<IR::StatOrDecl>($1->begin(), $1->end()) ; }
1428+ | statement { $$ = new IR::IndexedVector<IR::StatOrDecl>($1) ; }
14091429 // The transition to instantiation below is not required by the
14101430 // languge spec, but it does help p4c give a more clear error
14111431 // message if one erroneously attempts to perform an
14121432 // instantiation inside of a block.
1413- | instantiation { $$ = $1 ; }
1433+ | instantiation { $$ = new IR::IndexedVector<IR::StatOrDecl>($1) ; }
14141434 ;
14151435
14161436forStatement
@@ -1563,7 +1583,18 @@ actionDeclaration
15631583/************************* VARIABLES *****************************/
15641584
15651585variableDeclaration
1566- : variableDeclarationWithoutSemicolon ";" { $$ = $1; }
1586+ : annotations typeRef initDeclaratorList ";" {
1587+ $$ = new IR::IndexedVector<IR::Declaration>();
1588+ for (auto &decl : $3) {
1589+ $$->push_back(new IR::Declaration_Variable(decl.srcInfo, *decl.name, *$1,
1590+ decl.type, decl.init));
1591+ driver.structure->declareObject(*decl.name, decl.type->toString()); } }
1592+ | typeRef initDeclaratorList ";" {
1593+ $$ = new IR::IndexedVector<IR::Declaration>();
1594+ for (auto &decl : $2) {
1595+ $$->push_back(new IR::Declaration_Variable(decl.srcInfo, *decl.name,
1596+ decl.type, decl.init));
1597+ driver.structure->declareObject(*decl.name, decl.type->toString()); } }
15671598 ;
15681599
15691600variableDeclarationWithoutSemicolon
@@ -1576,15 +1607,27 @@ variableDeclarationWithoutSemicolon
15761607 ;
15771608
15781609constantDeclaration
1579- : optAnnotations CONST typeRef declarator "=" initializer ";"
1580- { $$ = new IR::Declaration_Constant(@4, *$4.name, *$1, $4.type, $6);
1581- driver.structure->declareObject(*$4.name, $4.type->toString()); }
1610+ : optAnnotations CONST typeRef initDeclaratorList ";" {
1611+ $$ = new IR::IndexedVector<IR::Declaration>();
1612+ for (auto &decl : $4) {
1613+ if (!decl.init)
1614+ P4::error(ErrorType::ERR_EXPECTED,
1615+ "Const %1% declaration requires an initializer", decl.name);
1616+ $$->push_back(new IR::Declaration_Constant(decl.srcInfo, *decl.name, *$1,
1617+ decl.type, decl.init));
1618+ driver.structure->declareObject(*decl.name, decl.type->toString()); } }
15821619 ;
15831620
15841621declarator
1585- : name { $$.name = $1; $$.type = $<ConstType *>0; }
1586- | declarator "[" expression "]"
1587- { $$ = $1; $$.type = new IR::Type_Array(@2+@4, $1.type, $3); }
1622+ : name { $$.srcInfo = @1;
1623+ $$.name = $1;
1624+ $$.type = $<ConstType *>0;
1625+ $$.init = nullptr; }
1626+ | declarator "[" expression "]" {
1627+ $$ = $1;
1628+ $$.srcInfo += @4;
1629+ $$.type = new IR::Type_Array(@2+@4, $1.type, $3);
1630+ $$.init = nullptr; }
15881631 ;
15891632
15901633optInitializer
@@ -1596,6 +1639,18 @@ initializer
15961639 : expression { $$ = $1; }
15971640 ;
15981641
1642+ initDeclaratorList
1643+ : declarator optInitializer {
1644+ $$.emplace_back($1);
1645+ $$.back().init = $2; }
1646+ | initDeclaratorList "," <ConstType*>{ $$ = $<ConstType*>0; } declarator optInitializer {
1647+ if ($1.size() == 1)
1648+ warning(ErrorType::WARN_EXTENSION,
1649+ "%1%Multiple declarators is a non-standard extension", @4);
1650+ ($$=$1).emplace_back($4);
1651+ $$.back().init = $5; }
1652+ ;
1653+
15991654/**************** Expressions ****************/
16001655
16011656functionDeclaration
0 commit comments