From 305448ea86f7d6a302e1c26baf89ea0d2e9bcb4f Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 7 Jun 2020 16:54:25 -0400 Subject: [PATCH] Cleanup parser errors to identify packages by :: instead of symbol table --- src/V3ParseImp.cpp | 42 +++++++++++----------- src/V3ParseImp.h | 7 ---- src/V3ParseSym.h | 4 +-- src/verilog.y | 23 ++++-------- test_regress/t/t_class_unsup_bad.out | 18 ---------- test_regress/t/t_lint_import_name2_bad.out | 3 ++ test_regress/t/t_lint_pkg_colon_bad.out | 11 +++--- 7 files changed, 38 insertions(+), 70 deletions(-) diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index 16e1e1d01..4642bae6b 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -332,10 +332,6 @@ void V3ParseImp::lexFile(const string& modname) { if (bisonParse()) v3fatal("Cannot continue\n"); } -bool V3ParseImp::bisonValIdThenColon() const { - return bisonValPrev().token == yaID__ETC && bisonValCur().token == yP_COLONCOLON; -} - void V3ParseImp::tokenPull() { // Pull token from lex into the pipeline // This corrupts yylval, must save/restore if required @@ -366,6 +362,7 @@ void V3ParseImp::tokenPipeline() { || token == ySTATIC__LEX // || token == yVIRTUAL__LEX // || token == yWITH__LEX // + || token == yaID__LEX // ) { if (debugFlex() >= 6) { cout << " tokenPipeline: reading ahead to find possible strength" << endl; @@ -435,6 +432,8 @@ void V3ParseImp::tokenPipeline() { } else { token = yWITH__ETC; } + } else if (token == yaID__LEX) { + if (nexttok == yP_COLONCOLON) { token = yaID__CC; } } // If add to above "else if", also add to "if (token" further above } @@ -447,7 +446,7 @@ void V3ParseImp::tokenPipelineSym() { // Note above sometimes converts yGLOBAL to a yaID__LEX tokenPipeline(); // sets yylval int token = yylval.token; - if (token == yaID__LEX) { + if (token == yaID__LEX || token == yaID__CC) { VSymEnt* foundp; if (VSymEnt* look_underp = V3ParseImp::parsep()->symp()->nextId()) { UINFO(7, " tokenPipelineSym: next id lookup forced under " << look_underp << endl); @@ -467,24 +466,29 @@ void V3ParseImp::tokenPipelineSym() { yylval.scp = scp; UINFO(7, " tokenPipelineSym: Found " << scp << endl); if (VN_IS(scp, Typedef)) { - token = yaID__aTYPE; + token = (token == yaID__CC) ? yaID__CC : yaID__aTYPE; } else if (VN_IS(scp, TypedefFwd)) { - token = yaID__aTYPE; + token = (token == yaID__CC) ? yaID__CC : yaID__aTYPE; } else if (VN_IS(scp, Class)) { - token = yaID__aTYPE; - } - // Packages (and class static references) we could - // alternatively determine by looking for an yaID__LEX followed - // by yP_COLONCOLON (but we can't lookahead after an yaID__LEX - // as described above.) - else if (VN_IS(scp, Package)) { - token = yaID__aPACKAGE; + token = (token == yaID__CC) ? yaID__aTYPE : yaID__aTYPE; + } else if (VN_IS(scp, Package)) { + token = (token == yaID__CC) ? yaID__CC : yaID__ETC; } else { - token = yaID__ETC; + token = (token == yaID__CC) ? yaID__CC : yaID__ETC; } } else { // Not found yylval.scp = NULL; - token = yaID__ETC; + 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)"); + } + } } } yylval.token = token; @@ -494,8 +498,6 @@ void V3ParseImp::tokenPipelineSym() { int V3ParseImp::tokenToBison() { // Called as global since bison doesn't have our pointer tokenPipelineSym(); // sets yylval - m_bisonValPrev = m_bisonValCur; - m_bisonValCur = yylval; m_bisonLastFileline = yylval.fl; // yylval.scp = NULL; // Symbol table not yet needed - no packages @@ -513,7 +515,7 @@ std::ostream& operator<<(std::ostream& os, const V3ParseBisonYYSType& rhs) { os << " {" << rhs.fl->filenameLetters() << rhs.fl->asciiLineCol() << "}"; if (rhs.token == yaID__ETC // || rhs.token == yaID__LEX // - || rhs.token == yaID__aPACKAGE // + || rhs.token == yaID__CC // || rhs.token == yaID__aTYPE) { os << " strp='" << *(rhs.strp) << "'"; } diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 2603c4e96..4f8c3e55a 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -116,8 +116,6 @@ class V3ParseImp { VOptionBool m_unconnectedDrive; // Last unconnected drive int m_lexPrevToken; // previous parsed token (for lexer) - V3ParseBisonYYSType m_bisonValCur; // current token for error reporting - V3ParseBisonYYSType m_bisonValPrev; // previous token for error reporting std::deque m_tokensAhead; // Tokens we parsed ahead of parser std::deque m_stringps; // Created strings for later cleanup @@ -233,9 +231,6 @@ public: static int stateVerilogRecent(); // Parser -> lexer communication int lexPrevToken() const { return m_lexPrevToken; } // Parser -> lexer communication size_t flexPpInputToLex(char* buf, size_t max_size) { return ppInputToLex(buf, max_size); } - V3ParseBisonYYSType bisonValCur() const { return m_bisonValCur; } - V3ParseBisonYYSType bisonValPrev() const { return m_bisonValPrev; } - bool bisonValIdThenColon() const; //==== Symbol tables V3ParseSym* symp() { return m_symp; } @@ -252,8 +247,6 @@ public: m_lexKwdDepth = 0; m_lexKwdLast = stateVerilogRecent(); m_lexPrevToken = 0; - m_bisonValCur.token = 0; - m_bisonValPrev.token = 0; m_tagNodep = NULL; m_timeLastUnit = v3Global.opt.timeDefaultUnit(); } diff --git a/src/V3ParseSym.h b/src/V3ParseSym.h index dbe9bebc5..b9bdd13fd 100644 --- a/src/V3ParseSym.h +++ b/src/V3ParseSym.h @@ -142,7 +142,7 @@ public: // Import from package::id_or_star to this VSymEnt* symp = getTable(packagep); UASSERT_OBJ(symp, packagep, - // Internal problem, because we earlier found pkg to label it an ID__aPACKAGE + // Internal problem, because we earlier found pkg in parsing "Import package not found"); // Walk old sym table and reinsert into current table // We let V3LinkDot report the error instead of us @@ -152,7 +152,7 @@ public: // Export from this the remote package::id_or_star VSymEnt* symp = getTable(packagep); UASSERT_OBJ(symp, packagep, - // Internal problem, because we earlier found pkg to label it an ID__aPACKAGE + // Internal problem, because we earlier found pkg in parsing "Export package not found"); symCurrentp()->exportFromPackage(&m_syms, symp, id_or_star); } diff --git a/src/verilog.y b/src/verilog.y index 9049e1b79..50b257847 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -292,17 +292,7 @@ static void UNSUPREAL(FileLine* fileline) { void yyerror(const char* errmsg) { PARSEP->bisonLastFileline()->v3error(errmsg); - static const char* const colonmsg = "syntax error, unexpected ::, "; - // tokens; - if (0 == strncmp(errmsg, colonmsg, strlen(colonmsg)) && PARSEP->bisonValIdThenColon()) { - static int warned = false; - if (!warned++) { - std::cerr << PARSEP->bisonLastFileline()->warnMore() - << ("... Perhaps '" + *PARSEP->bisonValPrev().strp - + "' is a package which needs to be predeclared? (IEEE 1800-2017 26.3)") - << std::endl; - } - } + static const char* const colonmsg = "syntax error, unexpected"; } void yyerrorf(const char* format, ...) { @@ -336,8 +326,8 @@ class AstSenTree; // enum_identifier, interface_identifier, interface_instance_identifier, // package_identifier, type_identifier, variable_identifier, %token yaID__ETC "IDENTIFIER" +%token yaID__CC "IDENTIFIER-::" %token yaID__LEX "IDENTIFIER-in-lex" -%token yaID__aPACKAGE "PACKAGE-IDENTIFIER" %token yaID__aTYPE "TYPE-IDENTIFIER" // Can't predecode aFUNCTION, can declare after use // Can't predecode aINTERFACE, can declare after use @@ -1111,7 +1101,7 @@ package_import_itemList: ; package_import_item: // ==IEEE: package_import_item - idAny/*package_identifier*/ yP_COLONCOLON package_import_itemObj + yaID__CC/*package_identifier*/ yP_COLONCOLON package_import_itemObj { if (!VN_CAST($1, Package)) { $$ = NULL; @@ -1138,7 +1128,7 @@ package_export_itemList: ; package_export_item: // ==IEEE: package_export_item - idAny yP_COLONCOLON package_import_itemObj + yaID__CC yP_COLONCOLON package_import_itemObj { $$ = new AstPackageExport($3, VN_CAST($1, Package), *$3); SYMP->exportItem($1,*$3); } ; @@ -4682,9 +4672,8 @@ id: ; idAny: // Any kind of identifier - yaID__aPACKAGE { $$ = $1; $$=$1; } + yaID__ETC { $$ = $1; $$=$1; } | yaID__aTYPE { $$ = $1; $$=$1; } - | yaID__ETC { $$ = $1; $$=$1; } | idRandomize { $$ = $1; $$=$1; } ; @@ -5916,7 +5905,7 @@ package_scopeIdFollows: // IEEE: package_scope // // IMPORTANT: The lexer will parse the following ID to be in the found package // // Also see class_typeExtImpOne which has these rules too // //vv mid rule action needed otherwise we might not have NextId in time to parse the id token - yaID__aPACKAGE { SYMP->nextId($1); } + yaID__CC { SYMP->nextId($1); } /*cont*/ yP_COLONCOLON { $$ = VN_CAST($1, Package); } | yD_UNIT yP_COLONCOLON diff --git a/test_regress/t/t_class_unsup_bad.out b/test_regress/t/t_class_unsup_bad.out index a2c32713b..e58a257ca 100644 --- a/test_regress/t/t_class_unsup_bad.out +++ b/test_regress/t/t_class_unsup_bad.out @@ -28,22 +28,4 @@ %Error: t/t_class_unsup_bad.v:42:4: Unsupported: virtual class member qualifier 42 | virtual function uvm_root get_root(); | ^~~~~~~ -%Error: t/t_class_unsup_bad.v:43:15: Unsupported: Hierarchical class references - 43 | uvm_root::m_forward_task_call(); - | ^~ -%Error: t/t_class_unsup_bad.v:43:17: Unsupported: scoped class reference - 43 | uvm_root::m_forward_task_call(); - | ^~~~~~~~~~~~~~~~~~~ -%Error: t/t_class_unsup_bad.v:43:17: Unsupported: Class-scoped tasks - 43 | uvm_root::m_forward_task_call(); - | ^~~~~~~~~~~~~~~~~~~ -%Error: t/t_class_unsup_bad.v:44:22: Unsupported: Hierarchical class references - 44 | return uvm_root::m_uvm_get_root(); - | ^~ -%Error: t/t_class_unsup_bad.v:44:24: Unsupported: scoped class reference - 44 | return uvm_root::m_uvm_get_root(); - | ^~~~~~~~~~~~~~ -%Error: t/t_class_unsup_bad.v:44:24: Unsupported: Class-scoped functions - 44 | return uvm_root::m_uvm_get_root(); - | ^~~~~~~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_lint_import_name2_bad.out b/test_regress/t/t_lint_import_name2_bad.out index b95efdba7..21eace02e 100644 --- a/test_regress/t/t_lint_import_name2_bad.out +++ b/test_regress/t/t_lint_import_name2_bad.out @@ -1,3 +1,6 @@ +%Error: t/t_lint_import_name2_bad.v:7:8: Package/class 'missing' not found, and needs to be predeclared (IEEE 1800-2017 26.3) + 7 | import missing::sigs; + | ^~~~~~~ %Error: t/t_lint_import_name2_bad.v:7:8: Importing from missing package 'missing' 7 | import missing::sigs; | ^~~~~~~ diff --git a/test_regress/t/t_lint_pkg_colon_bad.out b/test_regress/t/t_lint_pkg_colon_bad.out index 9af5556c8..51ef13962 100644 --- a/test_regress/t/t_lint_pkg_colon_bad.out +++ b/test_regress/t/t_lint_pkg_colon_bad.out @@ -1,8 +1,7 @@ -%Error: t/t_lint_pkg_colon_bad.v:7:23: syntax error, unexpected ::, expecting ')' or ',' +%Error: t/t_lint_pkg_colon_bad.v:7:17: Package/class 'mispkg' not found, and needs to be predeclared (IEEE 1800-2017 26.3) 7 | module t (input mispkg::foo_t a); - | ^~ - : ... Perhaps 'mispkg' is a package which needs to be predeclared? (IEEE 1800-2017 26.3) -%Error: t/t_lint_pkg_colon_bad.v:8:15: syntax error, unexpected ::, expecting ',' or ';' - 8 | reg mispkgb::bar_t b; - | ^~ + | ^~~~~~ +%Error: t/t_lint_pkg_colon_bad.v:7:25: syntax error, unexpected IDENTIFIER, expecting TYPE-IDENTIFIER + 7 | module t (input mispkg::foo_t a); + | ^~~~~ %Error: Exiting due to