Improve error to note common :: package errors
This commit is contained in:
parent
3862f2f022
commit
b3cf5c4f5f
|
|
@ -42,11 +42,13 @@ typedef enum { uniq_NONE, uniq_UNIQUE, uniq_UNIQUE0, uniq_PRIORITY } V3UniqState
|
||||||
typedef enum { iprop_NONE, iprop_CONTEXT, iprop_PURE } V3ImportProperty;
|
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
|
// We can't use bison's %union as we want to pass the fileline with all tokens
|
||||||
|
|
||||||
struct V3ParseBisonYYSType {
|
struct V3ParseBisonYYSType {
|
||||||
FileLine* fl;
|
FileLine* fl;
|
||||||
AstNode* scp; // Symbol table scope for future lookups
|
AstNode* scp; // Symbol table scope for future lookups
|
||||||
|
int token; // Read token, aka tok
|
||||||
union {
|
union {
|
||||||
V3Number* nump;
|
V3Number* nump;
|
||||||
string* strp;
|
string* strp;
|
||||||
|
|
@ -107,9 +109,10 @@ class V3ParseImp {
|
||||||
int m_lastVerilogState; // Last LEX state in `begin_keywords
|
int m_lastVerilogState; // Last LEX state in `begin_keywords
|
||||||
|
|
||||||
int m_prevLexToken; // previous parsed token (for lexer)
|
int m_prevLexToken; // previous parsed token (for lexer)
|
||||||
bool m_ahead; // aheadToken is valid
|
bool m_ahead; // aheadval is valid
|
||||||
int m_aheadToken; // Token we read ahead
|
V3ParseBisonYYSType m_aheadVal; // ahead token value
|
||||||
V3ParseBisonYYSType m_aheadVal; // aheadToken's value
|
V3ParseBisonYYSType m_curBisonVal; // current token for error reporting
|
||||||
|
V3ParseBisonYYSType m_prevBisonVal; // previous token for error reporting
|
||||||
|
|
||||||
deque<string*> m_stringps; // Created strings for later cleanup
|
deque<string*> m_stringps; // Created strings for later cleanup
|
||||||
deque<V3Number*> m_numberps; // Created numbers for later cleanup
|
deque<V3Number*> m_numberps; // Created numbers for later cleanup
|
||||||
|
|
@ -194,6 +197,8 @@ public:
|
||||||
static int stateVerilogRecent(); // Parser -> lexer communication
|
static int stateVerilogRecent(); // Parser -> lexer communication
|
||||||
int prevLexToken() { return m_prevLexToken; } // 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); }
|
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
|
//==== Symbol tables
|
||||||
V3ParseSym* symp() { return m_symp; }
|
V3ParseSym* symp() { return m_symp; }
|
||||||
|
|
@ -210,7 +215,8 @@ public:
|
||||||
m_lastVerilogState = stateVerilogRecent();
|
m_lastVerilogState = stateVerilogRecent();
|
||||||
m_prevLexToken = 0;
|
m_prevLexToken = 0;
|
||||||
m_ahead = false;
|
m_ahead = false;
|
||||||
m_aheadToken = 0;
|
m_curBisonVal.token = 0;
|
||||||
|
m_prevBisonVal.token = 0;
|
||||||
// m_aheadVal not used as m_ahead = false
|
// m_aheadVal not used as m_ahead = false
|
||||||
}
|
}
|
||||||
~V3ParseImp();
|
~V3ParseImp();
|
||||||
|
|
@ -227,7 +233,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void lexFile(const string& modname);
|
void lexFile(const string& modname);
|
||||||
int yylexReadTok();
|
int yylexReadTok();
|
||||||
int lexToken(); // Internal; called from lexToBison
|
void lexToken(); // Internal; called from lexToBison
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // Guard
|
#endif // Guard
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,14 @@ void V3ParseImp::verilatorCmtBad(const char* textp) {
|
||||||
|
|
||||||
void yyerror(const char* errmsg) {
|
void yyerror(const char* errmsg) {
|
||||||
PARSEP->fileline()->v3error(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, ...) {
|
void yyerrorf(const char* format, ...) {
|
||||||
|
|
@ -994,14 +1002,14 @@ double V3ParseImp::parseDouble(const char* textp, size_t length, bool* successp)
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
int V3ParseImp::lexToken() {
|
void V3ParseImp::lexToken() {
|
||||||
// called from lexToBison, has a "this"
|
// called from lexToBison, has a "this"
|
||||||
// Fetch next token from prefetch or real lexer
|
// Fetch next token from prefetch or real lexer
|
||||||
int token;
|
int token;
|
||||||
if (m_ahead) {
|
if (m_ahead) {
|
||||||
// We prefetched an extra token, give it back
|
// We prefetched an extra token, give it back
|
||||||
m_ahead = false;
|
m_ahead = false;
|
||||||
token = m_aheadToken;
|
token = m_aheadVal.token;
|
||||||
yylval = m_aheadVal;
|
yylval = m_aheadVal;
|
||||||
} else {
|
} else {
|
||||||
// Parse new token
|
// Parse new token
|
||||||
|
|
@ -1017,8 +1025,8 @@ int V3ParseImp::lexToken() {
|
||||||
V3ParseBisonYYSType curValue = yylval; // Remember value, as about to read ahead
|
V3ParseBisonYYSType curValue = yylval; // Remember value, as about to read ahead
|
||||||
int nexttok = yylexReadTok();
|
int nexttok = yylexReadTok();
|
||||||
m_ahead = true;
|
m_ahead = true;
|
||||||
m_aheadToken = nexttok;
|
|
||||||
m_aheadVal = yylval;
|
m_aheadVal = yylval;
|
||||||
|
m_aheadVal.token = nexttok;
|
||||||
yylval = curValue;
|
yylval = curValue;
|
||||||
// Now potentially munge the current token
|
// Now potentially munge the current token
|
||||||
if (token == yCONST__LEX) {
|
if (token == yCONST__LEX) {
|
||||||
|
|
@ -1060,21 +1068,25 @@ int V3ParseImp::lexToken() {
|
||||||
token = yaID__ETC;
|
token = yaID__ETC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return token;
|
yylval.token = token;
|
||||||
|
// effectively returns yylval
|
||||||
}
|
}
|
||||||
|
|
||||||
int V3ParseImp::lexToBison() {
|
int V3ParseImp::lexToBison() {
|
||||||
// Called as global since bison doesn't have our pointer
|
// 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
|
//yylval.scp = NULL; // Symbol table not yet needed - no packages
|
||||||
if (debugFlex()>=6 || debugBison()>=6) {
|
if (debugFlex()>=6 || debugBison()>=6) {
|
||||||
cout<<" {"<<yylval.fl->filenameLetters()<<yylval.fl->lineno()
|
cout<<" {"<<yylval.fl->filenameLetters()<<yylval.fl->lineno()
|
||||||
<<"} lexToBison TOKEN="<<tok<<" "<<tokenName(tok);
|
<<"} lexToBison TOKEN="<<yylval.token<<" "<<tokenName(yylval.token);
|
||||||
if (tok == yaID__ETC || tok == yaID__LEX || tok == yaID__aTYPE) {
|
if (yylval.token == yaID__ETC || yylval.token == yaID__LEX || yylval.token == yaID__aTYPE) {
|
||||||
cout<<" strp='"<<*(yylval.strp)<<"'";
|
cout<<" strp='"<<*(yylval.strp)<<"'";
|
||||||
}
|
}
|
||||||
cout<<endl;
|
cout<<endl;
|
||||||
}
|
}
|
||||||
return tok;
|
return yylval.token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2008 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
$Self->{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;
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in New Issue