From b3cf5c4f5fb3d8635f1a89c40f72a58861da6dcc Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 18 Sep 2017 22:54:54 -0400 Subject: [PATCH] Improve error to note common :: package errors --- src/V3ParseImp.h | 16 ++++++++++----- src/verilog.l | 28 ++++++++++++++++++-------- test_regress/t/t_lint_pkg_colon_bad.pl | 27 +++++++++++++++++++++++++ test_regress/t/t_lint_pkg_colon_bad.v | 8 ++++++++ 4 files changed, 66 insertions(+), 13 deletions(-) create mode 100755 test_regress/t/t_lint_pkg_colon_bad.pl create mode 100644 test_regress/t/t_lint_pkg_colon_bad.v diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 6e5d50ba7..4ba76543a 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -42,11 +42,13 @@ typedef enum { uniq_NONE, uniq_UNIQUE, uniq_UNIQUE0, uniq_PRIORITY } V3UniqState typedef enum { iprop_NONE, iprop_CONTEXT, iprop_PURE } V3ImportProperty; //============================================================================ +// Parser YYSType, e.g. for parser's yylval // We can't use bison's %union as we want to pass the fileline with all tokens struct V3ParseBisonYYSType { FileLine* fl; AstNode* scp; // Symbol table scope for future lookups + int token; // Read token, aka tok union { V3Number* nump; string* strp; @@ -107,9 +109,10 @@ class V3ParseImp { int m_lastVerilogState; // Last LEX state in `begin_keywords int m_prevLexToken; // previous parsed token (for lexer) - bool m_ahead; // aheadToken is valid - int m_aheadToken; // Token we read ahead - V3ParseBisonYYSType m_aheadVal; // aheadToken's value + bool m_ahead; // aheadval is valid + V3ParseBisonYYSType m_aheadVal; // ahead token value + V3ParseBisonYYSType m_curBisonVal; // current token for error reporting + V3ParseBisonYYSType m_prevBisonVal; // previous token for error reporting deque m_stringps; // Created strings for later cleanup deque m_numberps; // Created numbers for later cleanup @@ -194,6 +197,8 @@ public: static int stateVerilogRecent(); // Parser -> lexer communication int prevLexToken() { return m_prevLexToken; } // Parser -> lexer communication size_t flexPpInputToLex(char* buf, size_t max_size) { return ppInputToLex(buf,max_size); } + const V3ParseBisonYYSType curBisonVal() const { return m_curBisonVal; } + const V3ParseBisonYYSType prevBisonVal() const { return m_prevBisonVal; } //==== Symbol tables V3ParseSym* symp() { return m_symp; } @@ -210,7 +215,8 @@ public: m_lastVerilogState = stateVerilogRecent(); m_prevLexToken = 0; m_ahead = false; - m_aheadToken = 0; + m_curBisonVal.token = 0; + m_prevBisonVal.token = 0; // m_aheadVal not used as m_ahead = false } ~V3ParseImp(); @@ -227,7 +233,7 @@ public: private: void lexFile(const string& modname); int yylexReadTok(); - int lexToken(); // Internal; called from lexToBison + void lexToken(); // Internal; called from lexToBison }; #endif // Guard diff --git a/src/verilog.l b/src/verilog.l index dae0d6a43..5786abbf3 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -109,6 +109,14 @@ void V3ParseImp::verilatorCmtBad(const char* textp) { void yyerror(const char* errmsg) { PARSEP->fileline()->v3error(errmsg); + static const char* colonmsg = "syntax error, unexpected ::, "; + //tokens; + if (0==strncmp(errmsg, colonmsg, strlen(colonmsg)) + && PARSEP->prevBisonVal().token == yaID__ETC + && PARSEP->curBisonVal().token == yP_COLONCOLON) { + PARSEP->fileline()->v3error("Perhaps '"+*PARSEP->prevBisonVal().strp + +"' is a package which needs to be predeclared? (IEEE 2012 26.3)"); + } } void yyerrorf(const char* format, ...) { @@ -994,14 +1002,14 @@ double V3ParseImp::parseDouble(const char* textp, size_t length, bool* successp) return d; } -int V3ParseImp::lexToken() { +void V3ParseImp::lexToken() { // called from lexToBison, has a "this" // Fetch next token from prefetch or real lexer int token; if (m_ahead) { // We prefetched an extra token, give it back m_ahead = false; - token = m_aheadToken; + token = m_aheadVal.token; yylval = m_aheadVal; } else { // Parse new token @@ -1017,8 +1025,8 @@ int V3ParseImp::lexToken() { V3ParseBisonYYSType curValue = yylval; // Remember value, as about to read ahead int nexttok = yylexReadTok(); m_ahead = true; - m_aheadToken = nexttok; m_aheadVal = yylval; + m_aheadVal.token = nexttok; yylval = curValue; // Now potentially munge the current token if (token == yCONST__LEX) { @@ -1060,21 +1068,25 @@ int V3ParseImp::lexToken() { token = yaID__ETC; } } - return token; + yylval.token = token; + // effectively returns yylval } int V3ParseImp::lexToBison() { // Called as global since bison doesn't have our pointer - int tok = lexToken(); + lexToken(); // sets yylval + m_prevBisonVal = m_curBisonVal; + m_curBisonVal = yylval; + //yylval.scp = NULL; // Symbol table not yet needed - no packages if (debugFlex()>=6 || debugBison()>=6) { cout<<" {"<filenameLetters()<lineno() - <<"} lexToBison TOKEN="<{vlt} or $Self->skip("Verilator only test"); + +compile ( + v_flags2 => ["--lint-only"], + fails=>1, + verilator_make_gcc => 0, + make_top_shell => 0, + make_main => 0, + expect=> quotemeta( +qq{%Error: t/t_lint_pkg_colon_bad.v:6: syntax error, unexpected ::, expecting ')' or ',' +%Error: t/t_lint_pkg_colon_bad.v:6: Perhaps 'mispkg' is a package which needs to be predeclared? (IEEE 2012 26.3) +%Error: t/t_lint_pkg_colon_bad.v:7: syntax error, unexpected ::, expecting ',' or ';' +%Error: t/t_lint_pkg_colon_bad.v:7: Perhaps 'mispkgb' is a package which needs to be predeclared? (IEEE 2012 26.3) +}).'%Error: Exiting due to.*' + ); + +ok(1); +1; diff --git a/test_regress/t/t_lint_pkg_colon_bad.v b/test_regress/t/t_lint_pkg_colon_bad.v new file mode 100644 index 000000000..1f813e869 --- /dev/null +++ b/test_regress/t/t_lint_pkg_colon_bad.v @@ -0,0 +1,8 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2017 by Wilson Snyder. + +module t (input mispkg::foo_t a); + reg mispkgb::bar_t b; +endmodule