diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index aad0958a7..f532cacc5 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -347,11 +347,13 @@ const V3ParseBisonYYSType* V3ParseImp::tokenPeekp(size_t depth) { return &m_tokensAhead.at(depth); } -bool V3ParseImp::tokenPipeScanParam() { +size_t V3ParseImp::tokenPipeScanParam(size_t depth) { // Search around IEEE parameter_value_assignment to see if :: follows - if (tokenPeekp(0)->token != '#') return false; - if (tokenPeekp(1)->token != '(') return false; - int depth = 2; // Past the ( + // Return location of following token, or input if not found + // yaID [ '#(' ... ')' ] + if (tokenPeekp(depth)->token != '#') return depth; + if (tokenPeekp(depth + 1)->token != '(') return depth; + depth += 2; // Past the ( int parens = 1; // Count first ( while (true) { int tok = tokenPeekp(depth)->token; @@ -369,7 +371,7 @@ bool V3ParseImp::tokenPipeScanParam() { } ++depth; } - return tokenPeekp(depth)->token == yP_COLONCOLON; + return depth; } void V3ParseImp::tokenPipeline() { @@ -463,7 +465,8 @@ void V3ParseImp::tokenPipeline() { } else if (nexttok == '#') { V3ParseBisonYYSType curValue = yylval; // Remember value, as about to read ahead { - if (tokenPipeScanParam()) { token = yaID__CC; } + size_t depth = tokenPipeScanParam(0); + if (tokenPeekp(depth)->token == yP_COLONCOLON) { token = yaID__CC; } } yylval = curValue; } @@ -499,29 +502,36 @@ void V3ParseImp::tokenPipelineSym() { AstNode* scp = foundp->nodep(); yylval.scp = scp; UINFO(7, " tokenPipelineSym: Found " << scp << endl); - if (VN_IS(scp, Typedef)) { - token = (token == yaID__CC) ? yaID__CC : yaID__aTYPE; - } else if (VN_IS(scp, TypedefFwd)) { - token = (token == yaID__CC) ? yaID__CC : yaID__aTYPE; - } else if (VN_IS(scp, Class)) { - token = (token == yaID__CC) ? yaID__CC : yaID__aTYPE; - } else if (VN_IS(scp, Package)) { - token = (token == yaID__CC) ? yaID__CC : yaID__ETC; - } else { - token = (token == yaID__CC) ? yaID__CC : yaID__ETC; + if (token == yaID__LEX) { // i.e. not yaID__CC + if (VN_IS(scp, Typedef)) { + token = yaID__aTYPE; + } else if (VN_IS(scp, TypedefFwd)) { + token = yaID__aTYPE; + } else if (VN_IS(scp, Class)) { + token = yaID__aTYPE; + } else if (VN_IS(scp, Package)) { + token = yaID__ETC; + } else { + token = yaID__ETC; + } } } else { // Not found yylval.scp = NULL; - token = (token == yaID__CC) ? yaID__CC : yaID__ETC; if (token == yaID__CC) { - // We'll get a parser error eventually but might not be obvious - // is missing package, and this confuses people - static int warned = false; - if (!warned++) { - yylval.fl->v3error( - "Package/class '" + *yylval.strp - + "' not found, and needs to be predeclared (IEEE 1800-2017 26.3)"); + // IEEE does require this, but we may relax this as UVM breaks it, so allow bbox + // for today + if (!v3Global.opt.bboxUnsup()) { + // We'll get a parser error eventually but might not be obvious + // is missing package, and this confuses people + static int warned = false; + if (!warned++) { + yylval.fl->v3error( + "Package/class '" + *yylval.strp + + "' not found, and needs to be predeclared (IEEE 1800-2017 26.3)"); + } } + } else if (token == yaID__LEX) { + token = yaID__ETC; } } } @@ -548,8 +558,8 @@ std::ostream& operator<<(std::ostream& os, const V3ParseBisonYYSType& rhs) { os << "TOKEN {" << rhs.fl->filenameLetters() << rhs.fl->asciiLineCol() << "}"; os << "=" << rhs.token << " " << V3ParseImp::tokenName(rhs.token); if (rhs.token == yaID__ETC // - || rhs.token == yaID__LEX // || rhs.token == yaID__CC // + || rhs.token == yaID__LEX // || rhs.token == yaID__aTYPE) { os << " strp='" << *(rhs.strp) << "'"; } diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index bb46a747e..0be03568d 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -274,7 +274,7 @@ private: void tokenPull(); void tokenPipeline(); // Internal; called from tokenToBison void tokenPipelineSym(); - bool tokenPipeScanParam(); + size_t tokenPipeScanParam(size_t depth); const V3ParseBisonYYSType* tokenPeekp(size_t depth); void preprocDumps(std::ostream& os); }; diff --git a/src/verilog.y b/src/verilog.y index 248b78b32..d0a3f567b 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1112,7 +1112,7 @@ package_import_itemList: ; package_import_item: // ==IEEE: package_import_item - yaID__CC/*package_identifier*/ yP_COLONCOLON package_import_itemObj + idCC/*package_identifier*/ yP_COLONCOLON package_import_itemObj { if (!VN_CAST($1, Package)) { $$ = NULL; @@ -1139,7 +1139,7 @@ package_export_itemList: ; package_export_item: // ==IEEE: package_export_item - yaID__CC yP_COLONCOLON package_import_itemObj + idCC yP_COLONCOLON package_import_itemObj { $$ = new AstPackageExport($3, VN_CAST($1, Package), *$3); SYMP->exportItem($1,*$3); } ; @@ -2679,6 +2679,9 @@ etcInst: // IEEE: module_instantiation + gate_instantiation + udp_insta ; instDecl: + // // Currently disambiguated from data_declaration based on + // // VARs being type, and cells non-type. + // // IEEE requires a '(' to disambiguate, we need TODO force this id parameter_value_assignmentE {INSTPREP($1,*$1,$2);} instnameList ';' { $$ = $4; GRAMMARP->m_impliedDecl=false; if (GRAMMARP->m_instParamp) { @@ -4686,6 +4689,11 @@ idType: // IEEE: class_identifier or other type identifier yaID__aTYPE { $$ = $1; $$=$1; } ; +idCC: // IEEE: class/package then :: + // lexer matches this: yaID_LEX [ '#' '(' ... ')' ] yP_COLONCOLON + yaID__CC { $$ = $1; $$=$1; } + ; + idRandomize: // Keyword as an identifier yRANDOMIZE { static string s = "randomize"; $$ = &s; $$ = $1; } ; @@ -5906,13 +5914,13 @@ packageClassScopeItem: // IEEE: package_scope or [package_scope]::[cla // // if not needed must use packageClassScopeNoId // // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE // //vv mid rule action needed otherwise we might not have NextId in time to parse the id token - yaID__CC + idCC /*mid*/ { SYMP->nextId($1); } /*cont*/ yP_COLONCOLON { $$ = VN_CAST($1, Package); } // UNSUP classes // - | yaID__CC parameter_value_assignment - /*mid*/ { SYMP->nextId($1); } // Change next *after* we handle parameters, not before + | idCC parameter_value_assignment + /*mid*/ { SYMP->nextId($1); } // Change next *after* we handle parameters, not before /*cont*/ yP_COLONCOLON { $$ = VN_CAST($1, Package); // UNSUP classes if ($2) BBUNSUP($2->fileline(), "Unsupported: Parameterized classes"); }