@@ -79,12 +79,14 @@ inline std::ostream& operator<<(std::ostream& out, const OptionalConst& oc) {
7979// forbidden in C++. We avoid the problem using a typedef.
8080typedef const IR::Type ConstType;
8181
82- struct NameTypePair {
82+ struct DeclaratorInfo {
83+ Util::SourceInfo srcInfo;
8384 IR::ID name;
8485 const IR::Type *type;
86+ const IR::Expression *init;
8587};
8688
87- inline std::ostream &operator<<(std::ostream &out, const NameTypePair &nt) {
89+ inline std::ostream &operator<<(std::ostream &out, const DeclaratorInfo &nt) {
8890 return out << nt.name << ":" << nt.type;
8991}
9092
@@ -107,7 +109,7 @@ class Token {
107109
108110 Token() : Token(0, cstring::empty, nullptr) { }
109111 Token(int type, cstring text) : Token(type, text, nullptr) { }
110- Token(int type, const char* text) : Token(type, cstring(text), nullptr) { }
112+ Token(int type, const char* text) : Token(type, cstring(text), nullptr) { }
111113 Token(int type, UnparsedConstant unparsedConstant)
112114 : Token(type, unparsedConstant.text,
113115 new UnparsedConstant(unparsedConstant)) { }
@@ -261,7 +263,8 @@ using namespace P4;
261263
262264
263265%type<IR::ID> name dot_name nonTypeName nonTableKwName annotationName
264- %type<NameTypePair> declarator
266+ %type<DeclaratorInfo> declarator
267+ %type<std::vector<DeclaratorInfo>> declaratorList initDeclaratorList
265268%type<IR::Direction> direction
266269%type<IR::Path*> prefixedNonTypeName prefixedType
267270%type<IR::TypeParameters*> optTypeParameters typeParameters typeParameterList
@@ -296,20 +299,20 @@ using namespace P4;
296299 forStatement breakStatement continueStatement
297300%type<IR::BlockStatement*> blockStatement parserBlockStatement controlBody
298301 optObjInitializer
299- %type<IR::StatOrDecl*> statementOrDeclaration parserStatement
300- declOrAssignmentOrMethodCallStatement
301- %type<IR::IndexedVector<IR::StatOrDecl>> objDeclarations statOrDeclList parserStatements
302+ %type<IR::StatOrDecl*> declOrAssignmentOrMethodCallStatement
303+ %type<IR::IndexedVector<IR::StatOrDecl>> objDeclarations parserStatement
304+ statementOrDeclaration parserStatements statOrDeclList
302305 forInitStatements forInitStatementsNonEmpty
303306 forUpdateStatements forUpdateStatementsNonEmpty
304307%type<IR::SwitchCase*> switchCase
305308%type<IR::Vector<IR::SwitchCase>> switchCases
306309%type<IR::Vector<IR::Type>> typeArgumentList realTypeArgumentList
307310%type<IR::ParserState*> parserState
308- %type<IR::IndexedVector<IR::ParserState>> parserStates
309- %type<IR::Declaration*> constantDeclaration actionDeclaration
310- variableDeclaration variableDeclarationWithoutSemicolon instantiation functionDeclaration
311- objDeclaration tableDeclaration controlLocalDeclaration
312- parserLocalElement valueSetDeclaration
311+ %type<IR::IndexedVector<IR::ParserState>> parserStates
312+ %type<IR::IndexedVector<IR:: Declaration>> constantDeclaration variableDeclaration parserLocalElement controlLocalDeclaration
313+ %type<IR::Declaration*> actionDeclaration variableDeclarationWithoutSemicolon instantiation
314+ functionDeclaration objDeclaration tableDeclaration
315+ valueSetDeclaration
313316%type<IR::Type_Declaration*> headerTypeDeclaration structTypeDeclaration
314317 headerUnionDeclaration derivedTypeDeclaration
315318 parserDeclaration controlDeclaration enumDeclaration
@@ -321,8 +324,7 @@ using namespace P4;
321324%type<IR::Type_Parser*> parserTypeDeclaration
322325%type<IR::Type_Control*> controlTypeDeclaration
323326%type<IR::IndexedVector<IR::Declaration>> parserLocalElements controlLocalDeclarations
324- %type<IR::StructField*> structField
325- %type<IR::IndexedVector<IR::StructField>> structFieldList
327+ %type<IR::IndexedVector<IR::StructField>> structField structFieldList
326328%type<IR::IndexedVector<IR::SerEnumMember>> specifiedIdentifierList
327329%type<IR::SerEnumMember*> specifiedIdentifier
328330%type<IR::Method*> methodPrototype functionPrototype
@@ -479,14 +481,18 @@ p4rtControllerType
479481program : input END { YYACCEPT; };
480482
481483input
482- : %empty { driver.result = $$ = new IR::P4Program; }
483- | input declaration { if ($2) $1->objects.push_back($2->getNode());
484- $$ = $1; }
485- | input ";" { $$ = $1; } // empty declaration
484+ : %empty { driver.result = $$ = new IR::P4Program; }
485+ | input declaration { $$ = $1;
486+ if (!$2) { /* do nothing */ }
487+ else if (auto *v = $2->to<IR::VectorBase>())
488+ $$->objects.append(*v);
489+ else
490+ $$->objects.push_back($2); }
491+ | input ";" { $$ = $1; } // empty declaration
486492 ;
487493
488494declaration
489- : constantDeclaration { $$ = $1 ; }
495+ : constantDeclaration { $$ = new IR::IndexedVector<IR::Declaration>(std::move($1)) ; }
490496 | externDeclaration { $$ = $1; }
491497 | actionDeclaration { $$ = $1; }
492498 | parserDeclaration { $$ = $1; }
@@ -832,14 +838,14 @@ parserDeclaration
832838
833839parserLocalElements
834840 : %empty { $$ = {}; }
835- | parserLocalElements parserLocalElement { ($$ = std::move($1)).push_back ($2); $$.srcInfo = @1 + @2; }
841+ | parserLocalElements parserLocalElement { ($$ = std::move($1)).append ($2); $$.srcInfo = @1 + @2; }
836842 ;
837843
838844parserLocalElement
839- : constantDeclaration { $$ = $1 ; }
840- | instantiation { $$ = $1 ; }
841- | variableDeclaration { $$ = $1 ; }
842- | valueSetDeclaration { $$ = $1 ; }
845+ : constantDeclaration { $$ = std::move($1) ; }
846+ | instantiation { $$.push_back($1) ; }
847+ | variableDeclaration { $$ = std::move($1) ; }
848+ | valueSetDeclaration { $$.push_back($1) ; }
843849 ;
844850
845851parserTypeDeclaration
@@ -867,16 +873,16 @@ parserState
867873
868874parserStatements
869875 : %empty { $$ = {}; }
870- | parserStatements parserStatement { ($$ = std::move($1)).push_back ($2); $$.srcInfo = @1 + @2; }
876+ | parserStatements parserStatement { ($$ = std::move($1)).append ($2); $$.srcInfo = @1 + @2; }
871877 ;
872878
873879parserStatement
874- : assignmentOrMethodCallStatement { $$ = $1 ; }
875- | emptyStatement { $$ = $1 ; }
876- | variableDeclaration { $$ = $1 ; }
877- | constantDeclaration { $$ = $1 ; }
878- | parserBlockStatement { $$ = $1 ; }
879- | conditionalStatement { $$ = $1 ; }
880+ : assignmentOrMethodCallStatement { $$.push_back($1) ; }
881+ | emptyStatement { $$.push_back($1) ; }
882+ | variableDeclaration { for (auto *decl : $1) $$.push_back(decl) ; }
883+ | constantDeclaration { for (auto *decl : $1) $$.push_back(decl) ; }
884+ | parserBlockStatement { $$.push_back($1) ; }
885+ | conditionalStatement { $$.push_back($1) ; }
880886 ;
881887
882888parserBlockStatement
@@ -982,14 +988,16 @@ controlTypeDeclaration
982988
983989controlLocalDeclarations
984990 : %empty { $$ = {}; }
985- | controlLocalDeclarations controlLocalDeclaration { ($$ = std::move($1)).push_back($2); $$.srcInfo = @1 + @2; }
991+ | controlLocalDeclarations controlLocalDeclaration {
992+ ($$ = std::move($1)).append($2);
993+ $$.srcInfo = @1 + @2; }
986994 ;
987995
988996controlLocalDeclaration
989997 : constantDeclaration { $$ = $1; }
990- | actionDeclaration { $$ = $1 ; }
991- | tableDeclaration { $$ = $1 ; }
992- | instantiation { $$ = $1 ; }
998+ | actionDeclaration { $$.push_back($1) ; }
999+ | tableDeclaration { $$.push_back($1) ; }
1000+ | instantiation { $$.push_back($1) ; }
9931001 | variableDeclaration { $$ = $1; }
9941002 ;
9951003
@@ -1203,12 +1211,22 @@ headerUnionDeclaration
12031211
12041212structFieldList
12051213 : %empty { $$ = {}; }
1206- | structFieldList structField { ($$ = std::move($1)).push_back ($2); $$.srcInfo = @1 + @2; }
1214+ | structFieldList structField { ($$ = std::move($1)).append ($2); $$.srcInfo = @1 + @2; }
12071215 ;
12081216
12091217structField
1210- : optAnnotations typeRef declarator ";" {
1211- $$ = new IR::StructField(@3, $3.name, std::move($1), $3.type); }
1218+ : optAnnotations typeRef declaratorList ";" {
1219+ for (auto &decl : $3)
1220+ $$.push_back(new IR::StructField(decl.srcInfo, decl.name, std::move($1), decl.type)); }
1221+ ;
1222+
1223+ declaratorList
1224+ : declarator { $$.emplace_back($1); }
1225+ | declaratorList "," <ConstType*>{ $$ = $<ConstType*>0; } declarator {
1226+ if ($1.size() == 1)
1227+ warning(ErrorType::WARN_EXTENSION,
1228+ "%1%Multiple declarators is a non-standard extension", @4);
1229+ ($$=$1).emplace_back($4); }
12121230 ;
12131231
12141232enumDeclaration
@@ -1352,7 +1370,7 @@ blockStatement
13521370
13531371statOrDeclList
13541372 : %empty { $$ = {}; }
1355- | statOrDeclList statementOrDeclaration { ($$ = std::move($1)).push_back ($2);
1373+ | statOrDeclList statementOrDeclaration { ($$ = std::move($1)).append ($2);
13561374 $$.srcInfo = @1 + @2; }
13571375 ;
13581376
@@ -1377,14 +1395,14 @@ switchLabel
13771395 ;
13781396
13791397statementOrDeclaration
1380- : variableDeclaration { $$ = $1 ; }
1381- | constantDeclaration { $$ = $1 ; }
1382- | statement { $$ = $1 ; }
1398+ : variableDeclaration { for (auto *decl : $1) $$.push_back(decl) ; }
1399+ | constantDeclaration { for (auto *decl : $1) $$.push_back(decl) ; }
1400+ | statement { $$.push_back($1) ; }
13831401 // The transition to instantiation below is not required by the
13841402 // languge spec, but it does help p4c give a more clear error
13851403 // message if one erroneously attempts to perform an
13861404 // instantiation inside of a block.
1387- | instantiation { $$ = $1 ; }
1405+ | instantiation { $$.push_back($1) ; }
13881406 ;
13891407
13901408forStatement
@@ -1529,7 +1547,16 @@ actionDeclaration
15291547/************************* VARIABLES *****************************/
15301548
15311549variableDeclaration
1532- : variableDeclarationWithoutSemicolon ";" { $$ = $1; }
1550+ : annotations typeRef initDeclaratorList ";" {
1551+ for (auto &decl : $3) {
1552+ $$.push_back(new IR::Declaration_Variable(decl.srcInfo, decl.name, std::move($1),
1553+ decl.type, decl.init));
1554+ driver.structure->declareObject(decl.name, decl.type->toString()); } }
1555+ | typeRef initDeclaratorList ";" {
1556+ for (auto &decl : $2) {
1557+ $$.push_back(new IR::Declaration_Variable(decl.srcInfo, decl.name,
1558+ decl.type, decl.init));
1559+ driver.structure->declareObject(decl.name, decl.type->toString()); } }
15331560 ;
15341561
15351562variableDeclarationWithoutSemicolon
@@ -1542,15 +1569,26 @@ variableDeclarationWithoutSemicolon
15421569 ;
15431570
15441571constantDeclaration
1545- : optAnnotations CONST typeRef declarator "=" initializer ";" {
1546- $$ = new IR::Declaration_Constant(@4, $4.name, std::move($1), $4.type, $6);
1547- driver.structure->declareObject($4.name, $4.type->toString()); }
1572+ : optAnnotations CONST typeRef initDeclaratorList ";" {
1573+ for (auto &decl : $4) {
1574+ if (!decl.init)
1575+ P4::error(ErrorType::ERR_EXPECTED,
1576+ "Const %1% declaration requires an initializer", decl.name);
1577+ $$.push_back(new IR::Declaration_Constant(decl.srcInfo, decl.name, std::move($1),
1578+ decl.type, decl.init));
1579+ driver.structure->declareObject(decl.name, decl.type->toString()); } }
15481580 ;
15491581
15501582declarator
1551- : name { $$.name = $1; $$.type = $<ConstType *>0; }
1552- | declarator "[" expression "]"
1553- { $$ = $1; $$.type = new IR::Type_Array(@2+@4, $1.type, $3); }
1583+ : name { $$.srcInfo = @1;
1584+ $$.name = $1;
1585+ $$.type = $<ConstType *>0;
1586+ $$.init = nullptr; }
1587+ | declarator "[" expression "]" {
1588+ $$ = $1;
1589+ $$.srcInfo += @4;
1590+ $$.type = new IR::Type_Array(@2+@4, $1.type, $3);
1591+ $$.init = nullptr; }
15541592 ;
15551593
15561594optInitializer
@@ -1562,6 +1600,18 @@ initializer
15621600 : expression { $$ = $1; }
15631601 ;
15641602
1603+ initDeclaratorList
1604+ : declarator optInitializer {
1605+ $$.emplace_back($1);
1606+ $$.back().init = $2; }
1607+ | initDeclaratorList "," <ConstType*>{ $$ = $<ConstType*>0; } declarator optInitializer {
1608+ if ($1.size() == 1)
1609+ warning(ErrorType::WARN_EXTENSION,
1610+ "%1%Multiple declarators is a non-standard extension", @4);
1611+ ($$=$1).emplace_back($4);
1612+ $$.back().init = $5; }
1613+ ;
1614+
15651615/**************** Expressions ****************/
15661616
15671617functionDeclaration
0 commit comments