diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index 9c7fe7df1..4d705e1cf 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -330,6 +330,10 @@ 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::lexToken() { // called from lexToBison, has a "this" // Fetch next token from prefetch or real lexer @@ -476,8 +480,8 @@ void V3ParseImp::lexToken() { int V3ParseImp::lexToBison() { // Called as global since bison doesn't have our pointer lexToken(); // sets yylval - m_prevBisonVal = m_curBisonVal; - m_curBisonVal = yylval; + m_bisonValPrev = m_bisonValCur; + m_bisonValCur = yylval; // yylval.scp = NULL; // Symbol table not yet needed - no packages if (debugFlex() >= 6 || debugBison() >= 6) { // --debugi-flex and --debugi-bison diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index cef05f600..26841ba70 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -116,8 +116,8 @@ class V3ParseImp { int m_prevLexToken; // previous parsed token (for lexer) 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 + V3ParseBisonYYSType m_bisonValCur; // current token for error reporting + V3ParseBisonYYSType m_bisonValPrev; // previous token for error reporting std::deque m_stringps; // Created strings for later cleanup std::deque m_numberps; // Created numbers for later cleanup @@ -229,8 +229,9 @@ public: static int stateVerilogRecent(); // Parser -> lexer communication int prevLexToken() const { return m_prevLexToken; } // Parser -> lexer communication size_t flexPpInputToLex(char* buf, size_t max_size) { return ppInputToLex(buf, max_size); } - V3ParseBisonYYSType curBisonVal() const { return m_curBisonVal; } - V3ParseBisonYYSType prevBisonVal() const { return m_prevBisonVal; } + V3ParseBisonYYSType bisonValCur() const { return m_bisonValCur; } + V3ParseBisonYYSType bisonValPrev() const { return m_bisonValPrev; } + bool bisonValIdThenColon() const; //==== Symbol tables V3ParseSym* symp() { return m_symp; } @@ -249,8 +250,8 @@ public: m_lastVerilogState = stateVerilogRecent(); m_prevLexToken = 0; m_ahead = false; - m_curBisonVal.token = 0; - m_prevBisonVal.token = 0; + m_bisonValCur.token = 0; + m_bisonValPrev.token = 0; // m_aheadVal not used as m_ahead = false, and not all compilers support initing it m_tagNodep = NULL; m_timeLastUnit = v3Global.opt.timeDefaultUnit(); diff --git a/src/verilog.l b/src/verilog.l index 8baf30c9a..b49e67add 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -27,9 +27,6 @@ #include "V3ParseImp.h" // Defines YYTYPE; before including bison header #include "V3ParseBison.h" // Generated by bison -extern void yyerror(const char*); -extern void yyerrorf(const char* format, ...); - #define STATE_VERILOG_RECENT S17 // State name for most recent Verilog Version #define PARSEP V3ParseImp::parsep() @@ -61,38 +58,6 @@ extern void yyerrorf(const char* format, ...); //====================================================================== -void yyerror(const char* errmsg) { - PARSEP->fileline()->v3error(errmsg); - static const char* const colonmsg = "syntax error, unexpected ::, "; - // tokens; - if (0 == strncmp(errmsg, colonmsg, strlen(colonmsg)) - && PARSEP->prevBisonVal().token == yaID__ETC - && PARSEP->curBisonVal().token == yP_COLONCOLON) { - static int warned = false; - if (!warned++) { - std::cerr << PARSEP->fileline()->warnMore() - << ("... Perhaps '" + *PARSEP->prevBisonVal().strp - + "' is a package which needs to be predeclared? (IEEE 1800-2017 26.3)") - << std::endl; - } - } -} - -void yyerrorf(const char* format, ...) { - const int maxlen = 2000; - char msg[maxlen]; - - va_list ap; - va_start(ap, format); - VL_VSNPRINTF(msg, maxlen, format, ap); - msg[maxlen - 1] = '\0'; - va_end(ap); - - yyerror(msg); -} - -//====================================================================== - static double lexParseDouble(FileLine* fl, const char* textp, size_t length) { string text = std::string(textp, length); bool success = false; diff --git a/src/verilog.y b/src/verilog.y index cfaabf39f..df07fb93a 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -44,9 +44,6 @@ #define GATEUNSUP(fl, tok) \ { BBUNSUP((fl), "Unsupported: Verilog 1995 gate primitive: " << (tok)); } -extern void yyerror(const char* errmsg); -extern void yyerrorf(const char* format, ...); - //====================================================================== // Statics (for here only) @@ -293,6 +290,36 @@ static void UNSUPREAL(FileLine* fileline) { //====================================================================== +void yyerror(const char* errmsg) { + PARSEP->fileline()->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->fileline()->warnMore() + << ("... Perhaps '" + *PARSEP->bisonValPrev().strp + + "' is a package which needs to be predeclared? (IEEE 1800-2017 26.3)") + << std::endl; + } + } +} + +void yyerrorf(const char* format, ...) { + const int maxlen = 2000; + char msg[maxlen]; + + va_list ap; + va_start(ap, format); + VL_VSNPRINTF(msg, maxlen, format, ap); + msg[maxlen - 1] = '\0'; + va_end(ap); + + yyerror(msg); +} + +//====================================================================== + class AstSenTree; // clang-format off %}