Skip to content

Commit 1deb5a0

Browse files
committed
Allow multiple declarators in a declaration
Signed-off-by: Chris Dodd <cdodd@nvidia.com>
1 parent 39e5c45 commit 1deb5a0

3 files changed

Lines changed: 113 additions & 53 deletions

File tree

frontends/parsers/p4/p4parser.ypp

Lines changed: 108 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
9090
typedef 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
485487
program : input END { YYACCEPT; };
486488

487489
input
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

494500
declaration
@@ -841,14 +847,14 @@ parserDeclaration
841847

842848
parserLocalElements
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

847853
parserLocalElement
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

854860
parserTypeDeclaration
@@ -876,17 +882,17 @@ parserState
876882

877883
parserStatements
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

882888
parserStatement
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

892898
parserBlockStatement
@@ -992,14 +998,16 @@ controlTypeDeclaration
992998

993999
controlLocalDeclarations
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

9981006
controlLocalDeclaration
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

12131221
structFieldList
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

12181226
structField
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

12221242
enumDeclaration
@@ -1349,15 +1369,15 @@ continueStatement
13491369
// To support direct invocation of a control or parser without instantiation
13501370
directApplication
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

13631383
statement
@@ -1382,7 +1402,7 @@ blockStatement
13821402

13831403
statOrDeclList
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

13881408
switchStatement
@@ -1406,14 +1426,14 @@ switchLabel
14061426
;
14071427

14081428
statementOrDeclaration
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

14191439
forStatement
@@ -1566,7 +1586,18 @@ actionDeclaration
15661586
/************************* VARIABLES *****************************/
15671587

15681588
variableDeclaration
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

15721603
variableDeclarationWithoutSemicolon
@@ -1579,15 +1610,27 @@ variableDeclarationWithoutSemicolon
15791610
;
15801611

15811612
constantDeclaration
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

15871624
declarator
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

15931636
optInitializer
@@ -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

16041659
functionDeclaration

lib/error_catalog.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ std::map<int, cstring> ErrorCatalog::errorCatalog = {
7777
{ErrorType::WARN_DUPLICATE, "duplicate"_cs},
7878
{ErrorType::WARN_BRANCH_HINT, "branch"_cs},
7979
{ErrorType::WARN_TABLE_KEYS, "keys"_cs},
80+
{ErrorType::WARN_EXTENSION, "extension"_cs},
8081

8182
// Info messages
8283
{ErrorType::INFO_INFERRED, "inferred"_cs},
@@ -87,6 +88,9 @@ void ErrorCatalog::initReporter(ErrorReporter &reporter) {
8788
// by default, ignore warnings about branch hints -- user can turn them
8889
// on with --Wwarn=branch
8990
reporter.setDiagnosticAction("branch"_cs, DiagnosticAction::Ignore);
91+
// by default, ignore warnings about extensions -- user can turn them
92+
// on with --Wwarn=extension
93+
reporter.setDiagnosticAction("extension"_cs, DiagnosticAction::Ignore);
9094
}
9195

9296
} // namespace P4

lib/error_catalog.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class ErrorType {
9191
static constexpr int WARN_DUPLICATE = 1025; // duplicate objects
9292
static constexpr int WARN_BRANCH_HINT = 1026; // branch frequency/likely hints
9393
static constexpr int WARN_TABLE_KEYS = 1027; // something is wrong with a table key
94+
static constexpr int WARN_EXTENSION = 1028; // non-standard extension
9495
// Backends should extend this class with additional warnings in the range 1500-2141.
9596
static constexpr int WARN_MIN_BACKEND = 1500; // first allowed backend warning code
9697
static constexpr int WARN_MAX = 2141; // last allowed warning code

0 commit comments

Comments
 (0)