Cleanup parser errors to identify packages by :: instead of symbol table

This commit is contained in:
Wilson Snyder 2020-06-07 16:54:25 -04:00
parent 4a1d18f0e9
commit 305448ea86
7 changed files with 38 additions and 70 deletions

View File

@ -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) << "'";
}

View File

@ -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<V3ParseBisonYYSType> m_tokensAhead; // Tokens we parsed ahead of parser
std::deque<string*> 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();
}

View File

@ -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);
}

View File

@ -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<strp> yaID__ETC "IDENTIFIER"
%token<strp> yaID__CC "IDENTIFIER-::"
%token<strp> yaID__LEX "IDENTIFIER-in-lex"
%token<strp> yaID__aPACKAGE "PACKAGE-IDENTIFIER"
%token<strp> 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<nodep>:
;
package_import_item<nodep>: // ==IEEE: package_import_item
idAny/*package_identifier*/ yP_COLONCOLON package_import_itemObj
yaID__CC/*package_identifier*/ yP_COLONCOLON package_import_itemObj
{
if (!VN_CAST($<scp>1, Package)) {
$$ = NULL;
@ -1138,7 +1128,7 @@ package_export_itemList<nodep>:
;
package_export_item<nodep>: // ==IEEE: package_export_item
idAny yP_COLONCOLON package_import_itemObj
yaID__CC yP_COLONCOLON package_import_itemObj
{ $$ = new AstPackageExport($<fl>3, VN_CAST($<scp>1, Package), *$3);
SYMP->exportItem($<scp>1,*$3); }
;
@ -4682,9 +4672,8 @@ id<strp>:
;
idAny<strp>: // Any kind of identifier
yaID__aPACKAGE { $$ = $1; $<fl>$=$<fl>1; }
yaID__ETC { $$ = $1; $<fl>$=$<fl>1; }
| yaID__aTYPE { $$ = $1; $<fl>$=$<fl>1; }
| yaID__ETC { $$ = $1; $<fl>$=$<fl>1; }
| idRandomize { $$ = $1; $<fl>$=$<fl>1; }
;
@ -5916,7 +5905,7 @@ package_scopeIdFollows<packagep>: // 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($<scp>1); }
yaID__CC { SYMP->nextId($<scp>1); }
/*cont*/ yP_COLONCOLON
{ $$ = VN_CAST($<scp>1, Package); }
| yD_UNIT yP_COLONCOLON

View File

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

View File

@ -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;
| ^~~~~~~

View File

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