Internals: Reindent and move parser code. No functional change.
This commit is contained in:
parent
aae2bf872c
commit
d15e3d93c4
|
|
@ -425,6 +425,9 @@ CPPCHECK_CPP = $(wildcard \
|
|||
CPPCHECK_H = $(wildcard \
|
||||
$(srcdir)/include/*.h \
|
||||
$(srcdir)/src/*.h )
|
||||
CPPCHECK_YL = $(wildcard \
|
||||
$(srcdir)/src/*.y \
|
||||
$(srcdir)/src/*.l )
|
||||
CPPCHECK = src/cppcheck_filtered
|
||||
CPPCHECK_FLAGS = --enable=all --inline-suppr \
|
||||
--suppress=unusedScopedObject --suppress=cstyleCast --suppress=useInitializationList \
|
||||
|
|
@ -462,7 +465,7 @@ CLANGFORMAT_FLAGS = -i
|
|||
clang-format:
|
||||
@$(CLANGFORMAT) --version | egrep 10.0 > /dev/null \
|
||||
|| echo "*** You are not using clang-format 10.0, indents may differ from master's ***"
|
||||
$(CLANGFORMAT) $(CLANGFORMAT_FLAGS) $(CPPCHECK_CPP) $(CPPCHECK_H)
|
||||
$(CLANGFORMAT) $(CLANGFORMAT_FLAGS) $(CPPCHECK_CPP) $(CPPCHECK_H) $(CPPCHECK_YL)
|
||||
|
||||
ftp: info
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
#include "V3PreShell.h"
|
||||
#include "V3LanguageWords.h"
|
||||
|
||||
#include "V3ParseBison.h" // Generated by bison
|
||||
|
||||
#include <sstream>
|
||||
|
||||
//======================================================================
|
||||
|
|
@ -352,6 +354,151 @@ void V3ParseImp::lexFile(const string& modname) {
|
|||
if (bisonParse()) v3fatal("Cannot continue\n");
|
||||
}
|
||||
|
||||
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_aheadVal.token;
|
||||
yylval = m_aheadVal;
|
||||
} else {
|
||||
// Parse new token
|
||||
token = yylexReadTok();
|
||||
// yylval // Set by yylexReadTok()
|
||||
}
|
||||
// If a paren, read another
|
||||
if (token == '(' //
|
||||
|| token == yCONST__LEX //
|
||||
|| token == yGLOBAL__LEX //
|
||||
|| token == yLOCAL__LEX //
|
||||
|| token == yNEW__LEX //
|
||||
|| token == yVIRTUAL__LEX
|
||||
// Never put yID_* here; below symbol table resolution would break
|
||||
) {
|
||||
if (debugFlex() >= 6) {
|
||||
cout << " lexToken: reading ahead to find possible strength" << endl;
|
||||
}
|
||||
V3ParseBisonYYSType curValue = yylval; // Remember value, as about to read ahead
|
||||
int nexttok = yylexReadTok();
|
||||
m_ahead = true;
|
||||
m_aheadVal = yylval;
|
||||
m_aheadVal.token = nexttok;
|
||||
yylval = curValue;
|
||||
// Now potentially munge the current token
|
||||
if (token == '('
|
||||
&& (nexttok == ygenSTRENGTH || nexttok == ySUPPLY0 || nexttok == ySUPPLY1)) {
|
||||
token = yP_PAR__STRENGTH;
|
||||
} else if (token == yCONST__LEX) {
|
||||
if (nexttok == yREF) {
|
||||
token = yCONST__REF;
|
||||
} else {
|
||||
token = yCONST__ETC;
|
||||
}
|
||||
} else if (token == yGLOBAL__LEX) {
|
||||
if (nexttok == yCLOCKING) {
|
||||
token = yGLOBAL__CLOCKING;
|
||||
} else if (v3Global.opt.pedantic()) {
|
||||
token = yGLOBAL__ETC;
|
||||
}
|
||||
// Avoid 2009 "global" conflicting with old code when we can
|
||||
else {
|
||||
token = yaID__LEX;
|
||||
yylval.strp = V3ParseImp::parsep()->newString("global");
|
||||
}
|
||||
} else if (token == yLOCAL__LEX) {
|
||||
if (nexttok == yP_COLONCOLON) {
|
||||
token = yLOCAL__COLONCOLON;
|
||||
} else {
|
||||
token = yLOCAL__ETC;
|
||||
}
|
||||
} else if (token == yNEW__LEX) {
|
||||
if (nexttok == '(') {
|
||||
token = yNEW__PAREN;
|
||||
} else {
|
||||
token = yNEW__ETC;
|
||||
}
|
||||
} else if (token == yVIRTUAL__LEX) {
|
||||
if (nexttok == yCLASS) {
|
||||
token = yVIRTUAL__CLASS;
|
||||
} else if (nexttok == yINTERFACE) {
|
||||
token = yVIRTUAL__INTERFACE;
|
||||
} else if (nexttok == yaID__ETC //
|
||||
|| nexttok == yaID__LEX) {
|
||||
// || nexttok == yaID__aINTERFACE // but we may not know interfaces yet.
|
||||
token = yVIRTUAL__anyID;
|
||||
} else {
|
||||
token = yVIRTUAL__ETC;
|
||||
}
|
||||
}
|
||||
// If add to above "else if", also add to "if (token" further above
|
||||
}
|
||||
// If an id, change the type based on symbol table
|
||||
// Note above sometimes converts yGLOBAL to a yaID__LEX
|
||||
if (token == yaID__LEX) {
|
||||
VSymEnt* foundp;
|
||||
if (VSymEnt* look_underp = V3ParseImp::parsep()->symp()->nextId()) {
|
||||
UINFO(7, " lexToken: next id lookup forced under " << look_underp << endl);
|
||||
foundp = look_underp->findIdFallback(*(yylval.strp));
|
||||
// "consume" it. Must set again if want another token under temp scope
|
||||
V3ParseImp::parsep()->symp()->nextId(NULL);
|
||||
} else {
|
||||
UINFO(7, " lexToken: find upward " << V3ParseImp::parsep()->symp()->symCurrentp()
|
||||
<< " for '" << *(yylval.strp) << "'" << endl);
|
||||
// if (debug()>=9) V3ParseImp::parsep()->symp()->symCurrentp()->dump(cout," -findtree:
|
||||
// ", true);
|
||||
foundp = V3ParseImp::parsep()->symp()->symCurrentp()->findIdFallback(*(yylval.strp));
|
||||
}
|
||||
if (foundp) {
|
||||
AstNode* scp = foundp->nodep();
|
||||
yylval.scp = scp;
|
||||
UINFO(7, " lexToken: Found " << scp << endl);
|
||||
if (VN_IS(scp, Typedef)) {
|
||||
token = yaID__aTYPE;
|
||||
} else if (VN_IS(scp, TypedefFwd)) {
|
||||
token = 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;
|
||||
} else {
|
||||
token = yaID__ETC;
|
||||
}
|
||||
} else { // Not found
|
||||
yylval.scp = NULL;
|
||||
token = yaID__ETC;
|
||||
}
|
||||
}
|
||||
yylval.token = token;
|
||||
// effectively returns yylval
|
||||
}
|
||||
|
||||
int V3ParseImp::lexToBison() {
|
||||
// Called as global since bison doesn't have our pointer
|
||||
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) { // --debugi-flex and --debugi-bison
|
||||
cout << " {" << yylval.fl->filenameLetters() << yylval.fl->asciiLineCol()
|
||||
<< "} lexToBison TOKEN=" << yylval.token << " " << tokenName(yylval.token);
|
||||
if (yylval.token == yaID__ETC //
|
||||
|| yylval.token == yaID__LEX //
|
||||
|| yylval.token == yaID__aTYPE) {
|
||||
cout << " strp='" << *(yylval.strp) << "'";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return yylval.token;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// V3Parse functions
|
||||
|
||||
|
|
|
|||
102
src/V3PreLex.l
102
src/V3PreLex.l
|
|
@ -1,8 +1,3 @@
|
|||
%option noyywrap align interactive
|
||||
%option stack
|
||||
%option noc++
|
||||
%option prefix="V3PreLex"
|
||||
%{
|
||||
/**************************************************************************
|
||||
* DESCRIPTION: Verilator: Flex verilog preprocessor
|
||||
*
|
||||
|
|
@ -20,6 +15,16 @@
|
|||
* Do not use Flex in C++ mode. It has bugs with yyunput() which result in
|
||||
* lost characters.
|
||||
**************************************************************************/
|
||||
/* clang-format off */
|
||||
|
||||
%option noyywrap align interactive
|
||||
%option stack
|
||||
%option noc++
|
||||
%option prefix="V3PreLex"
|
||||
%{
|
||||
#ifdef NEVER_JUST_FOR_CLANG_FORMAT
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "V3PreProc.h"
|
||||
#include "V3PreLex.h"
|
||||
|
|
@ -27,17 +32,22 @@
|
|||
# include <io.h> // for isatty
|
||||
#endif
|
||||
|
||||
V3PreLex* V3PreLex::s_currentLexp = NULL; // Current lexing point
|
||||
/* clang-format on */
|
||||
|
||||
V3PreLex* V3PreLex::s_currentLexp = NULL; // Current lexing point
|
||||
|
||||
#define LEXP V3PreLex::s_currentLexp
|
||||
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
#define YY_INPUT(buf, result, max_size) \
|
||||
do { result = LEXP->inputToLex(buf, max_size); } while (false)
|
||||
|
||||
// Accessors, because flex keeps changing the type of yyleng
|
||||
char* yyourtext() { return yytext; }
|
||||
size_t yyourleng() { return yyleng; }
|
||||
void yyourtext(const char* textp, size_t size) { yytext=(char*)textp; yyleng=size; }
|
||||
void yyourtext(const char* textp, size_t size) {
|
||||
yytext = (char*)textp;
|
||||
yyleng = size;
|
||||
}
|
||||
|
||||
// FL_FWD only tracks columns; preproc uses linenoInc() to track lines, so
|
||||
// insertion of a \n does not mess up line count
|
||||
|
|
@ -46,12 +56,13 @@ void yyourtext(const char* textp, size_t size) { yytext=(char*)textp; yyleng=siz
|
|||
#define FL_BRK (LEXP->curFilelinep()->startToken())
|
||||
|
||||
// Prevent conflicts from perl version
|
||||
static void linenoInc() {LEXP->linenoInc();}
|
||||
static void linenoInc() { LEXP->linenoInc(); }
|
||||
static bool pedantic() { return LEXP->m_pedantic; }
|
||||
static void yyerror(char* msg) { LEXP->curFilelinep()->v3error(msg); }
|
||||
static void yyerrorf(const char* msg) { LEXP->curFilelinep()->v3error(msg); }
|
||||
static void appendDefValue(const char* t, size_t l) { LEXP->appendDefValue(t, l); }
|
||||
|
||||
/* clang-format off */
|
||||
/**********************************************************************/
|
||||
%}
|
||||
|
||||
|
|
@ -308,6 +319,7 @@ bom [\357\273\277]
|
|||
<INITIAL>[\r] { FL_FWDC; FL_BRK; }
|
||||
<INITIAL>. { FL_FWDC; return VP_TEXT; }
|
||||
%%
|
||||
// clang-format on
|
||||
|
||||
void V3PreLex::pushStateDefArg(int level) {
|
||||
// Enter define substitution argument state
|
||||
|
|
@ -336,12 +348,15 @@ void V3PreLex::pushStateIncFilename() {
|
|||
yymore();
|
||||
}
|
||||
|
||||
void V3PreLex::debug(int level) { yy_flex_debug = level; }
|
||||
int V3PreLex::debug() { return yy_flex_debug; }
|
||||
void V3PreLex::debug(int level) {
|
||||
yy_flex_debug = level; }
|
||||
int V3PreLex::debug() {
|
||||
return yy_flex_debug; }
|
||||
|
||||
int V3PreLex::lex() {
|
||||
V3PreLex::s_currentLexp = this; // Tell parser where to get/put data
|
||||
m_tokFilelinep = curFilelinep(); // Remember token start location, may be updated by the lexer later
|
||||
// Remember token start location, may be updated by the lexer later
|
||||
m_tokFilelinep = curFilelinep();
|
||||
return yylex();
|
||||
}
|
||||
|
||||
|
|
@ -354,30 +369,32 @@ size_t V3PreLex::inputToLex(char* buf, size_t max_size) {
|
|||
//
|
||||
VPreStream* streamp = curStreamp();
|
||||
if (debug() >= 10) {
|
||||
cout<<"- pp:inputToLex ITL s="<<max_size<<" bs="<<streamp->m_buffers.size()<<endl;
|
||||
cout << "- pp:inputToLex ITL s=" << max_size << " bs=" << streamp->m_buffers.size()
|
||||
<< endl;
|
||||
dumpStack();
|
||||
}
|
||||
// For testing, use really small chunks
|
||||
//if (max_size > 13) max_size=13;
|
||||
again:
|
||||
// if (max_size > 13) max_size=13;
|
||||
again:
|
||||
size_t got = 0;
|
||||
// Get from this stream
|
||||
while (got < max_size // Haven't got enough
|
||||
&& !streamp->m_buffers.empty()) { // And something buffered
|
||||
string front = curStreamp()->m_buffers.front(); streamp->m_buffers.pop_front();
|
||||
string front = curStreamp()->m_buffers.front();
|
||||
streamp->m_buffers.pop_front();
|
||||
size_t len = front.length();
|
||||
if (len > (max_size-got)) { // Front string too big
|
||||
len = (max_size-got);
|
||||
if (len > (max_size - got)) { // Front string too big
|
||||
len = (max_size - got);
|
||||
string remainder = front.substr(len);
|
||||
front = front.substr(0, len);
|
||||
streamp->m_buffers.push_front(remainder); // Put back remainder for next time
|
||||
}
|
||||
strncpy(buf+got, front.c_str(), len);
|
||||
strncpy(buf + got, front.c_str(), len);
|
||||
got += len;
|
||||
}
|
||||
if (!got) { // end of stream; try "above" file
|
||||
bool again = false;
|
||||
string forceOut = endOfStream(again/*ref*/);
|
||||
string forceOut = endOfStream(again /*ref*/);
|
||||
streamp = curStreamp(); // May have been updated
|
||||
if (forceOut != "") {
|
||||
if (forceOut.length() > max_size) {
|
||||
|
|
@ -388,13 +405,15 @@ size_t V3PreLex::inputToLex(char* buf, size_t max_size) {
|
|||
}
|
||||
} else {
|
||||
if (streamp->m_eof) {
|
||||
if (yy_flex_debug) cout<<"- EOF\n";
|
||||
if (yy_flex_debug) cout << "- EOF\n";
|
||||
}
|
||||
got = 0; // 0=EOF/EOS - although got was already 0.
|
||||
if (again) goto again;
|
||||
}
|
||||
}
|
||||
if (debug() >= 10) { cout<<"- pp::inputToLex got="<<got<<" '"<<string(buf, got)<<"'"<<endl; }
|
||||
if (debug() >= 10) {
|
||||
cout << "- pp::inputToLex got=" << got << " '" << string(buf, got) << "'" << endl;
|
||||
}
|
||||
return got;
|
||||
}
|
||||
|
||||
|
|
@ -402,7 +421,7 @@ string V3PreLex::endOfStream(bool& againr) {
|
|||
// Switch to file or next unputString
|
||||
againr = false;
|
||||
if (yy_flex_debug) {
|
||||
cout<<"-EOS state="<<curStreamp()->m_termState<<" at "<<curFilelinep()<<endl;
|
||||
cout << "-EOS state=" << curStreamp()->m_termState << " at " << curFilelinep() << endl;
|
||||
}
|
||||
if (curStreamp()->m_eof) return ""; // Don't delete the final "EOF" stream
|
||||
bool exited_file = curStreamp()->m_file;
|
||||
|
|
@ -424,18 +443,15 @@ string V3PreLex::endOfStream(bool& againr) {
|
|||
// immediately.
|
||||
curStreamp()->m_termState = 1;
|
||||
return "\n"; // Exit old file
|
||||
}
|
||||
else if (curStreamp()->m_termState == 1) {
|
||||
} else if (curStreamp()->m_termState == 1) {
|
||||
// Now the EOF - can't be sent with other characters
|
||||
curStreamp()->m_termState = 2;
|
||||
return ""; // End of file
|
||||
}
|
||||
else if (curStreamp()->m_termState == 2) {
|
||||
} else if (curStreamp()->m_termState == 2) {
|
||||
// Now ending `line
|
||||
curStreamp()->m_termState = 3;
|
||||
return curFilelinep()->lineDirectiveStrg(2); // Exit old file
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Final shutdown phase for a stream, we can finally change the
|
||||
// current fileline to the new stream
|
||||
curStreamp()->m_termState = 0;
|
||||
|
|
@ -518,7 +534,7 @@ void V3PreLex::scanBytesBack(const string& str) {
|
|||
|
||||
string V3PreLex::currentUnreadChars() {
|
||||
// WARNING - Peeking at internals
|
||||
ssize_t left = (yy_n_chars - (yy_c_buf_p -currentBuffer()->yy_ch_buf));
|
||||
ssize_t left = (yy_n_chars - (yy_c_buf_p - currentBuffer()->yy_ch_buf));
|
||||
if (left > 0) { // left may be -1 at EOS
|
||||
*(yy_c_buf_p) = (yy_hold_char);
|
||||
return string(yy_c_buf_p, left);
|
||||
|
|
@ -536,25 +552,24 @@ int V3PreLex::currentStartState() const {
|
|||
}
|
||||
|
||||
void V3PreLex::lineDirective(const char* textp) {
|
||||
curFilelinep()->lineDirective(textp, m_enterExit/*ref*/);
|
||||
curFilelinep()->lineDirective(textp, m_enterExit /*ref*/);
|
||||
// Make sure we have a dependency on whatever file was specified
|
||||
V3File::addSrcDepend(curFilelinep()->filename());
|
||||
}
|
||||
|
||||
void V3PreLex::warnBackslashSpace() {
|
||||
// Make fileline highlight the specific backslash and space
|
||||
curFilelinep()->v3warn(BSSPACE, "Backslash followed by whitespace, perhaps the whitespace is accidental?");
|
||||
curFilelinep()->v3warn(
|
||||
BSSPACE, "Backslash followed by whitespace, perhaps the whitespace is accidental?");
|
||||
}
|
||||
|
||||
void V3PreLex::dumpSummary() {
|
||||
cout<<"- pp::dumpSummary curBuf="<<cvtToHex(currentBuffer());
|
||||
cout << "- pp::dumpSummary curBuf=" << cvtToHex(currentBuffer());
|
||||
#ifdef FLEX_DEBUG // Else peeking at internals may cause portability issues
|
||||
ssize_t left = (yy_n_chars
|
||||
- (yy_c_buf_p
|
||||
-currentBuffer()->yy_ch_buf));
|
||||
cout<<" left="<<std::dec<<left;
|
||||
ssize_t left = (yy_n_chars - (yy_c_buf_p - currentBuffer()->yy_ch_buf));
|
||||
cout << " left=" << std::dec << left;
|
||||
#endif
|
||||
cout<<endl;
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void V3PreLex::dumpStack() {
|
||||
|
|
@ -563,13 +578,10 @@ void V3PreLex::dumpStack() {
|
|||
std::stack<VPreStream*> tmpstack = LEXP->m_streampStack;
|
||||
while (!tmpstack.empty()) {
|
||||
VPreStream* streamp = tmpstack.top();
|
||||
cout<<"- bufferStack["<<cvtToHex(streamp)<<"]: "
|
||||
<<" at="<<streamp->m_curFilelinep
|
||||
<<" nBuf="<<streamp->m_buffers.size()
|
||||
<<" size0="<<(streamp->m_buffers.empty() ? 0 : streamp->m_buffers.front().length())
|
||||
<<(streamp->m_eof?" [EOF]":"")
|
||||
<<(streamp->m_file?" [FILE]":"");
|
||||
cout<<endl;
|
||||
cout << "- bufferStack[" << cvtToHex(streamp) << "]: "
|
||||
<< " at=" << streamp->m_curFilelinep << " nBuf=" << streamp->m_buffers.size()
|
||||
<< " size0=" << (streamp->m_buffers.empty() ? 0 : streamp->m_buffers.front().length())
|
||||
<< (streamp->m_eof ? " [EOF]" : "") << (streamp->m_file ? " [FILE]" : "") << endl;
|
||||
tmpstack.pop();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
168
src/verilog.l
168
src/verilog.l
|
|
@ -13,10 +13,15 @@
|
|||
* SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
*
|
||||
*************************************************************************/
|
||||
/* clang-format off */
|
||||
|
||||
%option interactive c++ stack noyywrap
|
||||
%{
|
||||
/* %option nodefault */
|
||||
#ifdef NEVER_JUST_FOR_CLANG_FORMAT
|
||||
}
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
#include "V3Number.h"
|
||||
#include "V3ParseImp.h" // Defines YYTYPE; before including bison header
|
||||
|
|
@ -31,7 +36,7 @@ extern void yyerrorf(const char* format, ...);
|
|||
#define SYMP PARSEP->symp()
|
||||
|
||||
#define YY_INPUT(buf, result, max_size) \
|
||||
do { result = PARSEP->flexPpInputToLex(buf, max_size); } while (false)
|
||||
do { result = PARSEP->flexPpInputToLex(buf, max_size); } while (false)
|
||||
|
||||
//======================================================================
|
||||
|
||||
|
|
@ -41,12 +46,18 @@ extern void yyerrorf(const char* format, ...);
|
|||
|
||||
#define CRELINE() (PARSEP->copyOrSameFileLine())
|
||||
|
||||
#define FL do { FL_FWD; yylval.fl = CRELINE(); } while (false)
|
||||
#define FL \
|
||||
do { \
|
||||
FL_FWD; \
|
||||
yylval.fl = CRELINE(); \
|
||||
} while (false)
|
||||
|
||||
#define ERROR_RSVD_WORD(language) \
|
||||
do { FL_FWD; \
|
||||
yyerrorf("Unsupported: " language " reserved word not implemented: '%s'", yytext); \
|
||||
FL_BRK; } while(0)
|
||||
do { \
|
||||
FL_FWD; \
|
||||
yyerrorf("Unsupported: " language " reserved word not implemented: '%s'", yytext); \
|
||||
FL_BRK; \
|
||||
} while (0)
|
||||
|
||||
//======================================================================
|
||||
|
||||
|
|
@ -80,6 +91,7 @@ void yyerrorf(const char* format, ...) {
|
|||
yyerror(msg);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/**********************************************************************/
|
||||
%}
|
||||
|
||||
|
|
@ -1039,149 +1051,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
|||
/* Catch all - absolutely last */
|
||||
<*>.|\n { FL_FWD; yyerrorf("Missing verilog.l rule: Default rule invoked in state %d: %s", YY_START, yytext); FL_BRK; }
|
||||
%%
|
||||
// Avoid code here as cl format misindents
|
||||
// For implementation functions see V3ParseImp.cpp
|
||||
|
||||
int V3ParseImp::stateVerilogRecent() { return STATE_VERILOG_RECENT; }
|
||||
|
||||
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_aheadVal.token;
|
||||
yylval = m_aheadVal;
|
||||
} else {
|
||||
// Parse new token
|
||||
token = yylexReadTok();
|
||||
// yylval // Set by yylexReadTok()
|
||||
}
|
||||
// If a paren, read another
|
||||
if (token == '(' //
|
||||
|| token == yCONST__LEX //
|
||||
|| token == yGLOBAL__LEX //
|
||||
|| token == yLOCAL__LEX //
|
||||
|| token == yNEW__LEX //
|
||||
|| token == yVIRTUAL__LEX
|
||||
// Never put yID_* here; below symbol table resolution would break
|
||||
) {
|
||||
if (debugFlex() >= 6) {
|
||||
cout << " lexToken: reading ahead to find possible strength" << endl;
|
||||
}
|
||||
V3ParseBisonYYSType curValue = yylval; // Remember value, as about to read ahead
|
||||
int nexttok = yylexReadTok();
|
||||
m_ahead = true;
|
||||
m_aheadVal = yylval;
|
||||
m_aheadVal.token = nexttok;
|
||||
yylval = curValue;
|
||||
// Now potentially munge the current token
|
||||
if (token == '('
|
||||
&& (nexttok == ygenSTRENGTH || nexttok == ySUPPLY0 || nexttok == ySUPPLY1)) {
|
||||
token = yP_PAR__STRENGTH;
|
||||
} else if (token == yCONST__LEX) {
|
||||
if (nexttok == yREF) {
|
||||
token = yCONST__REF;
|
||||
} else {
|
||||
token = yCONST__ETC;
|
||||
}
|
||||
} else if (token == yGLOBAL__LEX) {
|
||||
if (nexttok == yCLOCKING) {
|
||||
token = yGLOBAL__CLOCKING;
|
||||
} else if (v3Global.opt.pedantic()) {
|
||||
token = yGLOBAL__ETC;
|
||||
}
|
||||
// Avoid 2009 "global" conflicting with old code when we can
|
||||
else {
|
||||
token = yaID__LEX;
|
||||
yylval.strp = PARSEP->newString("global");
|
||||
}
|
||||
} else if (token == yLOCAL__LEX) {
|
||||
if (nexttok == yP_COLONCOLON) {
|
||||
token = yLOCAL__COLONCOLON;
|
||||
} else {
|
||||
token = yLOCAL__ETC;
|
||||
}
|
||||
} else if (token == yNEW__LEX) {
|
||||
if (nexttok == '(') {
|
||||
token = yNEW__PAREN;
|
||||
} else {
|
||||
token = yNEW__ETC;
|
||||
}
|
||||
} else if (token == yVIRTUAL__LEX) {
|
||||
if (nexttok == yCLASS) {
|
||||
token = yVIRTUAL__CLASS;
|
||||
} else if (nexttok == yINTERFACE) {
|
||||
token = yVIRTUAL__INTERFACE;
|
||||
} else if (nexttok == yaID__ETC //
|
||||
|| nexttok == yaID__LEX) {
|
||||
// || nexttok == yaID__aINTERFACE // but we may not know interfaces yet.
|
||||
token = yVIRTUAL__anyID;
|
||||
} else {
|
||||
token = yVIRTUAL__ETC;
|
||||
}
|
||||
}
|
||||
// If add to above "else if", also add to "if (token" further above
|
||||
}
|
||||
// If an id, change the type based on symbol table
|
||||
// Note above sometimes converts yGLOBAL to a yaID__LEX
|
||||
if (token == yaID__LEX) {
|
||||
VSymEnt* foundp;
|
||||
if (VSymEnt* look_underp = SYMP->nextId()) {
|
||||
UINFO(7, " lexToken: next id lookup forced under " << look_underp << endl);
|
||||
foundp = look_underp->findIdFallback(*(yylval.strp));
|
||||
// "consume" it. Must set again if want another token under temp scope
|
||||
SYMP->nextId(NULL);
|
||||
} else {
|
||||
UINFO(7, " lexToken: find upward " << SYMP->symCurrentp() << " for '"
|
||||
<< *(yylval.strp) << "'" << endl);
|
||||
// if (debug()>=9) SYMP->symCurrentp()->dump(cout," -findtree: ", true);
|
||||
foundp = SYMP->symCurrentp()->findIdFallback(*(yylval.strp));
|
||||
}
|
||||
if (foundp) {
|
||||
AstNode* scp = foundp->nodep();
|
||||
yylval.scp = scp;
|
||||
UINFO(7, " lexToken: Found " << scp << endl);
|
||||
if (VN_IS(scp, Typedef)) {
|
||||
token = yaID__aTYPE;
|
||||
} else if (VN_IS(scp, TypedefFwd)) {
|
||||
token = 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;
|
||||
} else {
|
||||
token = yaID__ETC;
|
||||
}
|
||||
} else { // Not found
|
||||
yylval.scp = NULL;
|
||||
token = yaID__ETC;
|
||||
}
|
||||
}
|
||||
yylval.token = token;
|
||||
// effectively returns yylval
|
||||
}
|
||||
|
||||
int V3ParseImp::lexToBison() {
|
||||
// Called as global since bison doesn't have our pointer
|
||||
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) { // --debugi-flex and --debugi-bison
|
||||
cout << " {" << yylval.fl->filenameLetters() << yylval.fl->asciiLineCol()
|
||||
<< "} lexToBison TOKEN=" << yylval.token << " " << tokenName(yylval.token);
|
||||
if (yylval.token == yaID__ETC //
|
||||
|| yylval.token == yaID__LEX //
|
||||
|| yylval.token == yaID__aTYPE) {
|
||||
cout << " strp='" << *(yylval.strp) << "'";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return yylval.token;
|
||||
}
|
||||
|
|
|
|||
1209
src/verilog.y
1209
src/verilog.y
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue