Internals: Reindent and move parser code. No functional change.

This commit is contained in:
Wilson Snyder 2020-06-06 08:44:44 -04:00
parent aae2bf872c
commit d15e3d93c4
5 changed files with 856 additions and 775 deletions

View File

@ -425,6 +425,9 @@ CPPCHECK_CPP = $(wildcard \
CPPCHECK_H = $(wildcard \ CPPCHECK_H = $(wildcard \
$(srcdir)/include/*.h \ $(srcdir)/include/*.h \
$(srcdir)/src/*.h ) $(srcdir)/src/*.h )
CPPCHECK_YL = $(wildcard \
$(srcdir)/src/*.y \
$(srcdir)/src/*.l )
CPPCHECK = src/cppcheck_filtered CPPCHECK = src/cppcheck_filtered
CPPCHECK_FLAGS = --enable=all --inline-suppr \ CPPCHECK_FLAGS = --enable=all --inline-suppr \
--suppress=unusedScopedObject --suppress=cstyleCast --suppress=useInitializationList \ --suppress=unusedScopedObject --suppress=cstyleCast --suppress=useInitializationList \
@ -462,7 +465,7 @@ CLANGFORMAT_FLAGS = -i
clang-format: clang-format:
@$(CLANGFORMAT) --version | egrep 10.0 > /dev/null \ @$(CLANGFORMAT) --version | egrep 10.0 > /dev/null \
|| echo "*** You are not using clang-format 10.0, indents may differ from master's ***" || 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 ftp: info

View File

@ -34,6 +34,8 @@
#include "V3PreShell.h" #include "V3PreShell.h"
#include "V3LanguageWords.h" #include "V3LanguageWords.h"
#include "V3ParseBison.h" // Generated by bison
#include <sstream> #include <sstream>
//====================================================================== //======================================================================
@ -352,6 +354,151 @@ void V3ParseImp::lexFile(const string& modname) {
if (bisonParse()) v3fatal("Cannot continue\n"); 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 // V3Parse functions

View File

@ -1,8 +1,3 @@
%option noyywrap align interactive
%option stack
%option noc++
%option prefix="V3PreLex"
%{
/************************************************************************** /**************************************************************************
* DESCRIPTION: Verilator: Flex verilog preprocessor * DESCRIPTION: Verilator: Flex verilog preprocessor
* *
@ -20,6 +15,16 @@
* Do not use Flex in C++ mode. It has bugs with yyunput() which result in * Do not use Flex in C++ mode. It has bugs with yyunput() which result in
* lost characters. * 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 "V3PreProc.h"
#include "V3PreLex.h" #include "V3PreLex.h"
@ -27,17 +32,22 @@
# include <io.h> // for isatty # include <io.h> // for isatty
#endif #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 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) do { result = LEXP->inputToLex(buf, max_size); } while (false)
// Accessors, because flex keeps changing the type of yyleng // Accessors, because flex keeps changing the type of yyleng
char* yyourtext() { return yytext; } char* yyourtext() { return yytext; }
size_t yyourleng() { return yyleng; } 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 // FL_FWD only tracks columns; preproc uses linenoInc() to track lines, so
// insertion of a \n does not mess up line count // 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()) #define FL_BRK (LEXP->curFilelinep()->startToken())
// Prevent conflicts from perl version // Prevent conflicts from perl version
static void linenoInc() {LEXP->linenoInc();} static void linenoInc() { LEXP->linenoInc(); }
static bool pedantic() { return LEXP->m_pedantic; } static bool pedantic() { return LEXP->m_pedantic; }
static void yyerror(char* msg) { LEXP->curFilelinep()->v3error(msg); } static void yyerror(char* msg) { LEXP->curFilelinep()->v3error(msg); }
static void yyerrorf(const 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); } 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>[\r] { FL_FWDC; FL_BRK; }
<INITIAL>. { FL_FWDC; return VP_TEXT; } <INITIAL>. { FL_FWDC; return VP_TEXT; }
%% %%
// clang-format on
void V3PreLex::pushStateDefArg(int level) { void V3PreLex::pushStateDefArg(int level) {
// Enter define substitution argument state // Enter define substitution argument state
@ -336,12 +348,15 @@ void V3PreLex::pushStateIncFilename() {
yymore(); yymore();
} }
void V3PreLex::debug(int level) { yy_flex_debug = level; } void V3PreLex::debug(int level) {
int V3PreLex::debug() { return yy_flex_debug; } yy_flex_debug = level; }
int V3PreLex::debug() {
return yy_flex_debug; }
int V3PreLex::lex() { int V3PreLex::lex() {
V3PreLex::s_currentLexp = this; // Tell parser where to get/put data 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(); return yylex();
} }
@ -354,30 +369,32 @@ size_t V3PreLex::inputToLex(char* buf, size_t max_size) {
// //
VPreStream* streamp = curStreamp(); VPreStream* streamp = curStreamp();
if (debug() >= 10) { 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(); dumpStack();
} }
// For testing, use really small chunks // For testing, use really small chunks
//if (max_size > 13) max_size=13; // if (max_size > 13) max_size=13;
again: again:
size_t got = 0; size_t got = 0;
// Get from this stream // Get from this stream
while (got < max_size // Haven't got enough while (got < max_size // Haven't got enough
&& !streamp->m_buffers.empty()) { // And something buffered && !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(); size_t len = front.length();
if (len > (max_size-got)) { // Front string too big if (len > (max_size - got)) { // Front string too big
len = (max_size-got); len = (max_size - got);
string remainder = front.substr(len); string remainder = front.substr(len);
front = front.substr(0, len); front = front.substr(0, len);
streamp->m_buffers.push_front(remainder); // Put back remainder for next time 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; got += len;
} }
if (!got) { // end of stream; try "above" file if (!got) { // end of stream; try "above" file
bool again = false; bool again = false;
string forceOut = endOfStream(again/*ref*/); string forceOut = endOfStream(again /*ref*/);
streamp = curStreamp(); // May have been updated streamp = curStreamp(); // May have been updated
if (forceOut != "") { if (forceOut != "") {
if (forceOut.length() > max_size) { if (forceOut.length() > max_size) {
@ -388,13 +405,15 @@ size_t V3PreLex::inputToLex(char* buf, size_t max_size) {
} }
} else { } else {
if (streamp->m_eof) { 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. got = 0; // 0=EOF/EOS - although got was already 0.
if (again) goto again; 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; return got;
} }
@ -402,7 +421,7 @@ string V3PreLex::endOfStream(bool& againr) {
// Switch to file or next unputString // Switch to file or next unputString
againr = false; againr = false;
if (yy_flex_debug) { 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 if (curStreamp()->m_eof) return ""; // Don't delete the final "EOF" stream
bool exited_file = curStreamp()->m_file; bool exited_file = curStreamp()->m_file;
@ -424,18 +443,15 @@ string V3PreLex::endOfStream(bool& againr) {
// immediately. // immediately.
curStreamp()->m_termState = 1; curStreamp()->m_termState = 1;
return "\n"; // Exit old file 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 // Now the EOF - can't be sent with other characters
curStreamp()->m_termState = 2; curStreamp()->m_termState = 2;
return ""; // End of file return ""; // End of file
} } else if (curStreamp()->m_termState == 2) {
else if (curStreamp()->m_termState == 2) {
// Now ending `line // Now ending `line
curStreamp()->m_termState = 3; curStreamp()->m_termState = 3;
return curFilelinep()->lineDirectiveStrg(2); // Exit old file return curFilelinep()->lineDirectiveStrg(2); // Exit old file
} } else {
else {
// Final shutdown phase for a stream, we can finally change the // Final shutdown phase for a stream, we can finally change the
// current fileline to the new stream // current fileline to the new stream
curStreamp()->m_termState = 0; curStreamp()->m_termState = 0;
@ -518,7 +534,7 @@ void V3PreLex::scanBytesBack(const string& str) {
string V3PreLex::currentUnreadChars() { string V3PreLex::currentUnreadChars() {
// WARNING - Peeking at internals // 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 if (left > 0) { // left may be -1 at EOS
*(yy_c_buf_p) = (yy_hold_char); *(yy_c_buf_p) = (yy_hold_char);
return string(yy_c_buf_p, left); return string(yy_c_buf_p, left);
@ -536,25 +552,24 @@ int V3PreLex::currentStartState() const {
} }
void V3PreLex::lineDirective(const char* textp) { 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 // Make sure we have a dependency on whatever file was specified
V3File::addSrcDepend(curFilelinep()->filename()); V3File::addSrcDepend(curFilelinep()->filename());
} }
void V3PreLex::warnBackslashSpace() { void V3PreLex::warnBackslashSpace() {
// Make fileline highlight the specific backslash and space // 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() { 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 #ifdef FLEX_DEBUG // Else peeking at internals may cause portability issues
ssize_t left = (yy_n_chars ssize_t left = (yy_n_chars - (yy_c_buf_p - currentBuffer()->yy_ch_buf));
- (yy_c_buf_p cout << " left=" << std::dec << left;
-currentBuffer()->yy_ch_buf));
cout<<" left="<<std::dec<<left;
#endif #endif
cout<<endl; cout << endl;
} }
void V3PreLex::dumpStack() { void V3PreLex::dumpStack() {
@ -563,13 +578,10 @@ void V3PreLex::dumpStack() {
std::stack<VPreStream*> tmpstack = LEXP->m_streampStack; std::stack<VPreStream*> tmpstack = LEXP->m_streampStack;
while (!tmpstack.empty()) { while (!tmpstack.empty()) {
VPreStream* streamp = tmpstack.top(); VPreStream* streamp = tmpstack.top();
cout<<"- bufferStack["<<cvtToHex(streamp)<<"]: " cout << "- bufferStack[" << cvtToHex(streamp) << "]: "
<<" at="<<streamp->m_curFilelinep << " at=" << streamp->m_curFilelinep << " nBuf=" << streamp->m_buffers.size()
<<" nBuf="<<streamp->m_buffers.size() << " size0=" << (streamp->m_buffers.empty() ? 0 : streamp->m_buffers.front().length())
<<" size0="<<(streamp->m_buffers.empty() ? 0 : streamp->m_buffers.front().length()) << (streamp->m_eof ? " [EOF]" : "") << (streamp->m_file ? " [FILE]" : "") << endl;
<<(streamp->m_eof?" [EOF]":"")
<<(streamp->m_file?" [FILE]":"");
cout<<endl;
tmpstack.pop(); tmpstack.pop();
} }
} }

View File

@ -13,10 +13,15 @@
* SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 * SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
* *
*************************************************************************/ *************************************************************************/
/* clang-format off */
%option interactive c++ stack noyywrap %option interactive c++ stack noyywrap
%{ %{
/* %option nodefault */ /* %option nodefault */
#ifdef NEVER_JUST_FOR_CLANG_FORMAT
}
#endif
// clang-format on
#include "V3Number.h" #include "V3Number.h"
#include "V3ParseImp.h" // Defines YYTYPE; before including bison header #include "V3ParseImp.h" // Defines YYTYPE; before including bison header
@ -31,7 +36,7 @@ extern void yyerrorf(const char* format, ...);
#define SYMP PARSEP->symp() #define SYMP PARSEP->symp()
#define YY_INPUT(buf, result, max_size) \ #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 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) \ #define ERROR_RSVD_WORD(language) \
do { FL_FWD; \ do { \
yyerrorf("Unsupported: " language " reserved word not implemented: '%s'", yytext); \ FL_FWD; \
FL_BRK; } while(0) yyerrorf("Unsupported: " language " reserved word not implemented: '%s'", yytext); \
FL_BRK; \
} while (0)
//====================================================================== //======================================================================
@ -80,6 +91,7 @@ void yyerrorf(const char* format, ...) {
yyerror(msg); yyerror(msg);
} }
// clang-format off
/**********************************************************************/ /**********************************************************************/
%} %}
@ -1039,149 +1051,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
/* Catch all - absolutely last */ /* Catch all - absolutely last */
<*>.|\n { FL_FWD; yyerrorf("Missing verilog.l rule: Default rule invoked in state %d: %s", YY_START, yytext); FL_BRK; } <*>.|\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; } 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;
}

File diff suppressed because it is too large Load Diff