Internals: Clean up the main flex/bison files to have some sanity.

(Hopefully) no functional change.
	. V3Parse.h		External consumer interface to V3ParseImp
	. V3ParseImp		Internals to parser, common to across flex & bison
	... V3ParseGrammar	Wrapper that includes V3ParseBison
	..... V3ParseBison	Bison output
	... V3ParseLex		Wrapper that includes lex output
	..... V3Lexer.yy.cpp	Flex output
This commit is contained in:
Wilson Snyder 2009-10-31 10:08:38 -04:00
parent 7b4d2118ea
commit f7efae93d5
19 changed files with 852 additions and 655 deletions

View File

@ -208,9 +208,10 @@ RAW_OBJS = \
# Non-concatable
OBJS += \
V3Parse.o \
V3ParseImp.o \
V3ParseGrammar.o \
V3ParseLex.o \
V3PreProc.o \
V3Read.o \
#### Linking
@ -245,10 +246,13 @@ V3Number_test: V3Number_test.o
%.o: %.c
$(OBJCACHE) ${CC} ${CPPFLAGS} -c $<
V3Read.o: V3Read.cpp V3Lexer.yy.cpp V3ParseBison.c
V3ParseLex.o: V3ParseLex.cpp V3Lexer.yy.cpp V3ParseBison.c
$(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
V3Parse.o: V3Parse.cpp V3ParseBison.c
V3ParseGrammar.o: V3ParseGrammar.cpp V3ParseBison.c
$(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
V3ParseImp.o: V3ParseImp.cpp V3ParseBison.c
$(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp

View File

@ -1152,7 +1152,7 @@ public:
// op3 = Statements/Ports/Vars
virtual void name(const string& name) { m_name = name; }
AstNode* stmtsp() const { return op3p()->castNode(); } // op1 = List of statements
void addStmtsp(AstNode* nodep) { addOp3p(nodep); }
void addStmtsp(AstNode* nodep) { addNOp3p(nodep); }
void taskPublic(bool flag) { m_taskPublic=flag; }
bool taskPublic() const { return m_taskPublic; }
};

View File

@ -731,7 +731,7 @@ public:
virtual void name(const string& name) { m_name = name; }
// op1 = Statements
AstNode* stmtsp() const { return op1p()->castNode(); } // op1 = List of statements
void addStmtp(AstNode* nodep) { addOp1p(nodep); }
void addStmtp(AstNode* nodep) { addNOp1p(nodep); }
bool unnamed() const { return m_unnamed; }
};
@ -804,7 +804,7 @@ public:
ASTNODE_NODE_FUNCS(Func, FUNC)
// op1 = Range output variable (functions only)
AstNode* fvarp() const { return op1p()->castNode(); }
void addFvarp(AstNode* nodep) { addOp1p(nodep); }
void addFvarp(AstNode* nodep) { addNOp1p(nodep); }
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
};

View File

@ -35,7 +35,6 @@
#include "V3Global.h"
#include "V3Const.h"
#include "V3Read.h"
#include "V3Ast.h"
#include "V3Width.h"
#include "V3Signed.h"

View File

@ -228,7 +228,7 @@ class FileLine {
protected:
// User routines should never need to change line numbers
// We are storing pointers, so we CAN'T change them after initial reading.
friend class V3Read;
friend class V3ParseImp;
friend class V3PreLex;
void lineno(int num) { m_lineno = num; }
void filename(const string& name) { m_filename = name; }

View File

@ -37,7 +37,7 @@
#include "V3Global.h"
#include "V3LinkCells.h"
#include "V3SymTable.h"
#include "V3Read.h"
#include "V3Parse.h"
#include "V3Ast.h"
#include "V3Graph.h"
@ -169,8 +169,8 @@ private:
AstModule* modp = m_mods.findIdUpward(nodep->modName())->castModule();
if (!modp) {
// Read-subfile
V3Read reader (v3Global.rootp());
reader.readFile(nodep->fileline(), nodep->modName(), false);
V3Parse parser (v3Global.rootp());
parser.parseFile(nodep->fileline(), nodep->modName(), false);
V3Error::abortIfErrors();
// We've read new modules, grab new pointers to their names
readModNames();
@ -200,7 +200,7 @@ private:
if (nodep->modp() && pinStar) {
// Note what pins exist
UINFO(9," CELL .* connect "<<nodep<<endl);
V3SymTable ports; // Symbol table of all connected port names
V3SymTable ports; // Symbol table of all connected port names
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
if (pinp->name()=="") pinp->v3error("Connect by position is illegal in .* connected cells");
if (!ports.findIdFlat(pinp->name())) {
@ -254,6 +254,7 @@ private:
m_mods.insert(nodep->name(), nodep);
}
}
//if (debug()>=9) m_mods.dump(cout, "-syms: ");
}
public:

View File

@ -39,7 +39,6 @@
#include "V3Global.h"
#include "V3Param.h"
#include "V3Read.h"
#include "V3Ast.h"
#include "V3Case.h"
#include "V3Const.h"

53
src/V3Parse.h Normal file
View File

@ -0,0 +1,53 @@
// -*- C++ -*-
//*************************************************************************
// DESCRIPTION: Verilator: Reading of Verilog files
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2009 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
#ifndef _V3PARSE_H_
#define _V3PARSE_H_ 1
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Global.h"
class AstNetlist;
class V3ParseImp;
//============================================================================
class V3Parse {
private:
V3ParseImp* m_impp;
public:
// CONSTRUCTORS
// We must allow reading multiple files into one parser
V3Parse(AstNetlist* rootp);
~V3Parse();
// METHODS
// Preprocess and read the Verilog file specified into the netlist database
void parseFile(FileLine* fileline, const string& modname, bool inLibrary);
// Push preprocessed text to the lexer
static void ppPushText(V3ParseImp* impp, const string& text);
};
#endif // Guard

View File

@ -18,6 +18,14 @@
// GNU General Public License for more details.
//
//*************************************************************************
// Overview of files involved in parsing
// V3Parse.h External consumer interface to V3ParseImp
// V3ParseImp Internals to parser, common to across flex & bison
// V3ParseGrammar Wrapper that includes V3ParseBison
// V3ParseBison Bison output
// V3ParseLex Wrapper that includes lex output
// V3Lexer.yy.cpp Flex output
//*************************************************************************
#include "config_build.h"
#include "verilatedos.h"
@ -30,55 +38,18 @@
#include "V3Global.h"
#include "V3Ast.h"
#include "V3File.h"
#include "V3Read.h"
#include "V3ParseImp.h"
#include "V3PreShell.h"
//======================================================================
// Build in LEX script
#define yyFlexLexer V3LexerBase
#include "V3Lexer.yy.cpp"
#undef yyFlexLexer
//YYSTYPE yylval;
//======================================================================
// Globals
V3Read* V3Read::s_readp = NULL;
extern bool yyparse();
extern int yydebug;
//######################################################################
// Lex-derived class
/// Override the base lexer class so we can add some access functions
class V3Lexer : public V3LexerBase {
public:
// CONSTRUCTORS
V3Lexer() : V3LexerBase(NULL) {}
~V3Lexer() {}
// METHODS
void stateExitPsl() {
if (YY_START != PSL) yyerrorf("Internal error: Exiting PSL state when not in PSL state");
yy_pop_state();
}
void statePushVlg() {
yy_push_state(STATE_VERILOG_RECENT);
}
void statePop() {
yy_pop_state();
}
};
void V3Read::stateExitPsl() { s_readp->m_lexerp->stateExitPsl(); }
void V3Read::statePushVlg() { s_readp->m_lexerp->stateExitPsl(); }
void V3Read::statePop() { s_readp->m_lexerp->statePop(); }
V3ParseImp* V3ParseImp::s_parsep = NULL;
//######################################################################
// Read class functions
V3Read::~V3Read() {
V3ParseImp::~V3ParseImp() {
for (deque<string*>::iterator it = m_stringps.begin(); it != m_stringps.end(); ++it) {
delete (*it);
}
@ -87,11 +58,11 @@ V3Read::~V3Read() {
delete (*it);
}
m_numberps.clear();
if (m_lexerp) { delete m_lexerp; m_lexerp = NULL; }
lexDestroy();
parserClear();
}
int V3Read::ppInputToLex(char* buf, int max_size) {
int V3ParseImp::ppInputToLex(char* buf, int max_size) {
int got = 0;
while (got < max_size // Haven't got enough
&& !m_ppBuffers.empty()) { // And something buffered
@ -114,7 +85,7 @@ int V3Read::ppInputToLex(char* buf, int max_size) {
return got;
}
void V3Read::readFile(FileLine* fileline, const string& modfilename, bool inLibrary) {
void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool inLibrary) {
string modname = V3Options::filenameNonExt(modfilename);
UINFO(2,__FUNCTION__<<": "<<modname<<(inLibrary?" [LIB]":"")<<endl);
@ -161,38 +132,30 @@ void V3Read::readFile(FileLine* fileline, const string& modfilename, bool inLibr
}
}
void V3Read::lexFile(const string& modname) {
void V3ParseImp::lexFile(const string& modname) {
// Prepare for lexing
UINFO(3,"Lexing "<<modname<<endl);
V3Read::s_readp = this;
V3Read::fileline()->warnResetDefault(); // Reenable warnings on each file
if (m_lexerp) delete m_lexerp; // Restart from clean slate.
m_lexerp = new V3Lexer();
// if (debug()) { m_lexerp->set_debug(~0); }
// if (debug()) yydebug = 1;
UINFO(4,"Lexing Done "<<modname<<endl);
s_parsep = this;
fileline()->warnResetDefault(); // Reenable warnings on each file
lexDestroy(); // Restart from clean slate.
lexNew(debugFlex()>=9);
// Lex it
if (yyparse()) v3fatal("Cannot continue\n");
if (bisonParse()) v3fatal("Cannot continue\n");
}
//======================================================================
// Lex accessors
// V3Parse functions
bool V3Read::optPsl() {
return v3Global.opt.psl();
V3Parse::V3Parse(AstNetlist* rootp) {
m_impp = new V3ParseImp (rootp);
}
bool V3Read::optFuture(const string& flag) {
return v3Global.opt.isFuture(flag);
V3Parse::~V3Parse() {
delete m_impp; m_impp = NULL;
}
//======================================================================
// Lex internal functions
int V3Read::yylexThis() {
int token = m_lexerp->yylex();
// Match verilog-perl names
if (token == yaID__LEX) { token = yaID__ETC; }
UINFO(5,m_fileline<<" TOKEN="<<dec<<token<<" "<<endl);
return (token);
void V3Parse::parseFile(FileLine* fileline, const string& modname, bool inLibrary) {
m_impp->parseFile(fileline, modname, inLibrary);
}
void V3Parse::ppPushText(V3ParseImp* impp, const string& text) {
impp->ppPushText(text);
}

198
src/V3ParseImp.h Normal file
View File

@ -0,0 +1,198 @@
// -*- C++ -*-
//*************************************************************************
// DESCRIPTION: Verilator: Common header between parser and lex
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2009-2009 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
#ifndef _V3PARSEIMP_H_
#define _V3PARSEIMP_H_ 1
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Global.h"
#include "V3Parse.h"
#include "V3SymTable.h"
#include <deque>
class V3Lexer;
// IMPORTANT: Don't include this file other than in the bison and flex,
// as it's definitions will confuse other parsers
//======================================================================
// Types (between parser & lexer)
typedef enum { uniq_NONE, uniq_UNIQUE, uniq_PRIORITY } V3UniqState;
//============================================================================
// We can't use bison's %union as we want to pass the fileline with all tokens
struct V3ParseBisonYYSType {
FileLine* fl;
union {
V3Number* nump;
string* strp;
int cint;
double cdouble;
V3UniqState uniqstate;
AstNode* nodep;
AstBegin* beginp;
AstCase* casep;
AstCaseItem* caseitemp;
AstConst* constp;
AstFunc* funcp;
AstModule* modulep;
AstNodeSenItem* senitemp;
AstNodeVarRef* varnodep;
AstParseRef* parserefp;
AstPin* pinp;
AstRange* rangep;
AstSenTree* sentreep;
AstTask* taskp;
AstVar* varp;
};
};
#define YYSTYPE V3ParseBisonYYSType
//######################################################################
class V3ParseImp {
// MEMBERS
AstNetlist* m_rootp; // Root of the design
V3Lexer* m_lexerp; // Current FlexLexer
static V3ParseImp* s_parsep; // Current THIS, bison() isn't class based
FileLine* m_fileline; // Filename/linenumber currently active
bool m_inCellDefine; // Inside a `celldefine
bool m_inLibrary; // Currently reading a library vs. regular file
int m_inBeginKwd; // Inside a `begin_keywords
int m_lastVerilogState; // Last LEX state in `begin_keywords
deque<string*> m_stringps; // Created strings for later cleanup
deque<V3Number*> m_numberps; // Created numbers for later cleanup
deque<FileLine> m_lintState; // Current lint state for save/restore
deque<string> m_ppBuffers; // Preprocessor->lex buffer of characters to process
public:
// Note these are an exception to using the filename as the debug type
static int debugBison() {
static int level = -1;
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel("bison");
return level;
}
static int debugFlex() {
static int level = -1;
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel("flex");
return level;
}
static int debug() { return debugBison() ? debugFlex() : 0; }
// Functions called by lex rules:
int yylexThis();
static bool optPsl() { return v3Global.opt.psl(); }
static bool optFuture(const string& flag) { return v3Global.opt.isFuture(flag); }
void ppline (const char* text);
void incLineno() { fileline()->incLineno(); }
void verilatorCmtLint(const char* text, bool on);
void verilatorCmtLintSave();
void verilatorCmtLintRestore();
void verilatorCmtBad(const char* text);
void pushBeginKeywords(int state) { m_inBeginKwd++; m_lastVerilogState=state; }
bool popBeginKeywords() { if (m_inBeginKwd) { m_inBeginKwd--; return true; } else return false; }
int lastVerilogState() { return m_lastVerilogState; }
static const char* tokenName(int tok);
void ppPushText(const string& text) { m_ppBuffers.push_back(text); }
int ppInputToLex(char* buf, int max_size);
static V3ParseImp* parsep() { return s_parsep; }
// TODO: Many of these functions are the old interface; they'd be better as non-static
// and called as READP->newString(...) etc.
string* newString(const string& text) {
// Allocate a string, remembering it so we can reclaim storage at lex end
string* strp = new string (text);
m_stringps.push_back(strp);
return strp;
}
string* newString(const char* text) {
// Allocate a string, remembering it so we can reclaim storage at lex end
string* strp = new string (text);
m_stringps.push_back(strp);
return strp;
}
string* newString(const char* text, int length) {
string* strp = new string (text, length);
m_stringps.push_back(strp);
return strp;
}
V3Number* newNumber(FileLine* fl, const char* text) {
V3Number* nump = new V3Number (fl, text);
m_numberps.push_back(nump);
return nump;
}
// Return next token, for bison, since bison isn't class based, use a global THIS
FileLine* fileline() { return m_fileline; }
AstNetlist* rootp() { return m_rootp; }
FileLine* copyOrSameFileLine() { return fileline()->copyOrSameFileLine(); }
bool inCellDefine() { return m_inCellDefine; }
void inCellDefine(bool flag) { m_inCellDefine = flag; }
bool inLibrary() { return m_inLibrary; }
// Interactions with parser
int bisonParse();
// Interactions with lexer
void lexNew(int debug);
void lexDestroy();
void stateExitPsl(); // Parser -> lexer communication
void statePushVlg(); // Parser -> lexer communication
void statePop(); // Parser -> lexer communication
int stateVerilogRecent(); // Parser -> lexer communication
int flexPpInputToLex(char* buf, int max_size) { return ppInputToLex(buf,max_size); }
public:
// CREATORS
V3ParseImp(AstNetlist* rootp) {
m_rootp = rootp; m_lexerp = NULL;
m_inCellDefine = false;
m_inLibrary = false;
m_inBeginKwd = 0;
m_lastVerilogState = stateVerilogRecent();
}
~V3ParseImp();
void parserClear();
// METHODS
// Preprocess and read the Verilog file specified into the netlist database
int lexToBison(); // Pass token to bison
void parseFile(FileLine* fileline, const string& modfilename, bool inLibrary);
private:
void lexFile(const string& modname);
int lexToken(); // Internal; called from lexToBison
};
#endif // Guard

78
src/V3ParseLex.cpp Normal file
View File

@ -0,0 +1,78 @@
//*************************************************************************
// DESCRIPTION: Verilator: Netlist (top level) functions
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2009 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
#include "config_build.h"
#include "verilatedos.h"
#include <cstdio>
#include <cstdarg>
#include <unistd.h>
#include <fstream>
#include "V3Error.h"
#include "V3Global.h"
#include "V3File.h"
#include "V3ParseImp.h"
//======================================================================
// Build in LEX script
#define yyFlexLexer V3LexerBase
#include "V3Lexer.yy.cpp"
#undef yyFlexLexer
//######################################################################
// Lex-derived class
/// Override the base lexer class so we can add some access functions
class V3Lexer : public V3LexerBase {
public:
// CONSTRUCTORS
V3Lexer() : V3LexerBase(NULL) {}
~V3Lexer() {}
// METHODS
void stateExitPsl() {
if (YY_START != PSL) yyerrorf("Internal error: Exiting PSL state when not in PSL state");
yy_pop_state();
}
void statePushVlg() {
yy_push_state(STATE_VERILOG_RECENT);
}
void statePop() {
yy_pop_state();
}
};
void V3ParseImp::stateExitPsl() { parsep()->m_lexerp->stateExitPsl(); }
void V3ParseImp::statePushVlg() { parsep()->m_lexerp->stateExitPsl(); }
void V3ParseImp::statePop() { parsep()->m_lexerp->statePop(); }
int V3ParseImp::yylexThis() { parsep()->m_lexerp->yylex(); }
//######################################################################
// Read class functions
void V3ParseImp::lexNew(int debug) {
if (m_lexerp) delete m_lexerp; // Restart from clean slate.
m_lexerp = new V3Lexer();
if (debugFlex()>=9) { m_lexerp->set_debug(~0); }
}
void V3ParseImp::lexDestroy() {
if (m_lexerp) { delete m_lexerp; m_lexerp = NULL; }
}

View File

@ -33,7 +33,7 @@
#include "V3PreShell.h"
#include "V3PreProc.h"
#include "V3File.h"
#include "V3Read.h"
#include "V3Parse.h"
//######################################################################
@ -69,7 +69,7 @@ protected:
}
}
void preproc (FileLine* fl, const string& modname, V3Read* readerp) {
void preproc (FileLine* fl, const string& modname, V3ParseImp* parsep) {
// Preprocess the given module, putting output in vppFilename
UINFONL(1," Preprocessing "<<modname<<endl);
@ -77,7 +77,7 @@ protected:
preprocOpen(fl, modname, "Cannot find file containing module: ");
while (!s_preprocp->isEof()) {
string line = s_preprocp->getline();
readerp->ppPushText(line);
V3Parse::ppPushText(parsep, line);
}
}
@ -111,8 +111,8 @@ V3PreProc* V3PreShellImp::s_preprocp = NULL;
void V3PreShell::boot(char** env) {
V3PreShellImp::s_preImp.boot(env);
}
void V3PreShell::preproc(FileLine* fl, const string& modname, V3Read* readerp) {
V3PreShellImp::s_preImp.preproc(fl, modname, readerp);
void V3PreShell::preproc(FileLine* fl, const string& modname, V3ParseImp* parsep) {
V3PreShellImp::s_preImp.preproc(fl, modname, parsep);
}
void V3PreShell::preprocInclude(FileLine* fl, const string& modname) {
V3PreShellImp::s_preImp.preprocInclude(fl, modname);

View File

@ -27,7 +27,7 @@
#include "verilatedos.h"
#include "V3Error.h"
class V3Read;
class V3ParseImp;
//============================================================================
@ -35,7 +35,7 @@ class V3PreShell {
// Static class for calling preprocessor
public:
static void boot(char** env);
static void preproc(FileLine* fileline, const string& module, V3Read* readerp);
static void preproc(FileLine* fileline, const string& module, V3ParseImp* parsep);
static void preprocInclude(FileLine* fileline, const string& module);
static string dependFiles() { return ""; } // Perl only
static void define(const string& name, const string& value);

View File

@ -1,139 +0,0 @@
// -*- C++ -*-
//*************************************************************************
// DESCRIPTION: Verilator: Reading of Verilog files
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2009 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
#ifndef _V3READ_H_
#define _V3READ_H_ 1
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include <deque>
class AstNetlist;
class V3Lexer;
class V3Number;
class AstNode;
//======================================================================
// Types (between parser & lexer)
typedef enum { uniq_NONE, uniq_UNIQUE, uniq_PRIORITY } V3UniqState;
//============================================================================
class V3Read {
AstNetlist* m_rootp; // Root of the design
V3Lexer* m_lexerp; // Current FlexLexer
static V3Read* s_readp; // Current THIS, bison() isn't class based
FileLine* m_fileline; // Filename/linenumber currently active
bool m_inCellDefine; // Inside a `celldefine
bool m_inLibrary; // Currently reading a library vs. regular file
int m_inBeginKwd; // Inside a `begin_keywords
int m_lastVerilogState; // Last LEX state in `begin_keywords
deque<string*> m_stringps; // Created strings for later cleanup
deque<V3Number*> m_numberps; // Created numbers for later cleanup
deque<FileLine> m_lintState; // Current lint state for save/restore
deque<string> m_ppBuffers; // Preprocessor->lex buffer of characters to process
// Options isn't visible, so not using debugSrcLevel
//int debug() { return 9; }
protected:
// Functions called by lex rules:
friend class V3Lexer;
friend class V3LexerBase;
friend class FileLine;
friend class V3PreShellImp;
int yylexThis();
static bool optPsl();
static bool optFuture(const string& flag);
static void ppline (const char* text);
static void incLineno() { s_readp->fileline()->incLineno(); }
static void verilatorCmtLint(const char* text, bool on);
static void verilatorCmtLintSave();
static void verilatorCmtLintRestore();
static void verilatorCmtBad(const char* text);
static void pushBeginKeywords(int state) { s_readp->m_inBeginKwd++; s_readp->m_lastVerilogState=state; }
static bool popBeginKeywords() { if (s_readp->m_inBeginKwd) { s_readp->m_inBeginKwd--; return true; } else return false; }
static int lastVerilogState() { return s_readp->m_lastVerilogState; }
void ppPushText(const string& text) { m_ppBuffers.push_back(text); }
int ppInputToLex(char* buf, int max_size);
public: // But for internal use only
static string* newString(const string& text) {
// Allocate a string, remembering it so we can reclaim storage at lex end
string* strp = new string (text);
s_readp->m_stringps.push_back(strp);
return strp;
}
static string* newString(const char* text) {
// Allocate a string, remembering it so we can reclaim storage at lex end
string* strp = new string (text);
s_readp->m_stringps.push_back(strp);
return strp;
}
static string* newString(const char* text, int length) {
string* strp = new string (text, length);
s_readp->m_stringps.push_back(strp);
return strp;
}
static V3Number* newNumber(FileLine* fl, const char* text) {
V3Number* nump = new V3Number (fl, text);
s_readp->m_numberps.push_back(nump);
return nump;
}
// Return next token, for bison, since bison isn't class based, use a global THIS
static int yylex() { return s_readp->yylexThis(); }
static FileLine* fileline() { return s_readp->m_fileline; }
static AstNetlist* rootp() { return s_readp->m_rootp; }
static FileLine* copyOrSameFileLine() { return s_readp->fileline()->copyOrSameFileLine(); }
static bool inCellDefine() { return s_readp->m_inCellDefine; }
static void inCellDefine(bool flag) { s_readp->m_inCellDefine = flag; }
static bool inLibrary() { return s_readp->m_inLibrary; }
static void stateExitPsl(); // Parser -> lexer communication
static void statePushVlg(); // Parser -> lexer communication
static void statePop(); // Parser -> lexer communication
static int stateVerilogRecent(); // Parser -> lexer communication
static int flexPpInputToLex(char* buf, int max_size) { return s_readp->ppInputToLex(buf,max_size); }
public:
// CREATORS
V3Read(AstNetlist* rootp) {
m_rootp = rootp; m_lexerp = NULL;
m_inCellDefine = false;
m_inLibrary = false;
m_inBeginKwd = 0;
m_lastVerilogState = stateVerilogRecent();
}
~V3Read();
void parserClear();
// METHODS
// Preprocess and read the Verilog file specified into the netlist database
void readFile(FileLine* fileline, const string& modname, bool inLibrary);
private:
void lexFile(const string& modname);
};
#endif // Guard

View File

@ -44,6 +44,8 @@
#include "V3Ast.h"
#include "V3Width.h"
#include <deque>
//============================================================================
//######################################################################

View File

@ -68,9 +68,9 @@
#include "V3Name.h"
#include "V3Order.h"
#include "V3Param.h"
#include "V3Parse.h"
#include "V3PreShell.h"
#include "V3Premit.h"
#include "V3Read.h"
#include "V3Scope.h"
#include "V3Signed.h"
#include "V3Split.h"
@ -92,12 +92,12 @@ V3Global v3Global;
// V3 Class -- top level
void V3Global::readFiles() {
V3Read reader (m_rootp);
V3Parse parser (v3Global.rootp());
// Read top module
for (V3StringList::const_iterator it = v3Global.opt.vFiles().begin();
it != v3Global.opt.vFiles().end(); ++it) {
string filename = *it;
reader.readFile(new FileLine("CommandLine",0), filename, false);
parser.parseFile(new FileLine("CommandLine",0), filename, false);
}
// Read libraries
@ -106,16 +106,21 @@ void V3Global::readFiles() {
for (V3StringSet::const_iterator it = v3Global.opt.libraryFiles().begin();
it != v3Global.opt.libraryFiles().end(); ++it) {
string filename = *it;
reader.readFile(new FileLine("CommandLine",0), filename, true);
parser.parseFile(new FileLine("CommandLine",0), filename, true);
}
//v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("parse.tree"));
V3Error::abortIfErrors();
if (!v3Global.opt.preprocOnly()) {
// Resolve all modules cells refer to
V3LinkCells::link(v3Global.rootp());
}
}
//######################################################################
void process () {
// Resolve all modules cells refer to
V3LinkCells::link(v3Global.rootp());
// Sort modules by level so later algorithms don't need to care
V3LinkLevel::modSortByLevel();
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("cells.tree"));
V3Error::abortIfErrors();
@ -566,7 +571,6 @@ int main(int argc, char** argv, char** env) {
// Read first filename
v3Global.readFiles();
//v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("parse.tree"));
// Link, etc, if needed
if (!v3Global.opt.preprocOnly()) {

View File

@ -25,8 +25,8 @@
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include "V3Read.h"
#include "V3Number.h"
#include "V3ParseImp.h" // Defines YYTYPE; before including bison header
#include "V3ParseBison.h" // Generated by bison
extern void yyerror(const char*);
@ -34,52 +34,55 @@ extern void yyerrorf(const char* format, ...);
#define STATE_VERILOG_RECENT S05 // State name for most recent Verilog Version
#define PARSEP V3ParseImp::parsep()
#define YY_INPUT(buf,result,max_size) \
result = V3Read::flexPpInputToLex(buf,max_size);
result = PARSEP->flexPpInputToLex(buf,max_size);
//======================================================================
#define NEXTLINE() {V3Read::incLineno();}
#define CRELINE() (V3Read::copyOrSameFileLine())
#define NEXTLINE() {PARSEP->incLineno();}
#define CRELINE() (PARSEP->copyOrSameFileLine())
#define FL { yylval.fileline = CRELINE(); }
#define FL { yylval.fl = CRELINE(); }
#define RETURN_BBOX_SYS_OR_MSG(msg,yytext) { \
if (v3Global.opt.bboxSys()) return yD_aIGNORE; \
else yyerrorf(msg,yytext); }
void V3Read::ppline (const char* textp) {
void V3ParseImp::ppline (const char* textp) {
// Handle `line directive
fileline()->lineDirective(textp);
}
void V3Read::verilatorCmtLint(const char* textp, bool warnOff) {
void V3ParseImp::verilatorCmtLint(const char* textp, bool warnOff) {
const char* sp = textp;
while (*sp && !isspace(*sp)) sp++; while (*sp && isspace(*sp)) sp++;
while (*sp && !isspace(*sp)) sp++; while (*sp && isspace(*sp)) sp++;
string msg = sp;
string::size_type pos;
if ((pos=msg.find("*")) != string::npos) { msg.erase(pos); }
if (!(V3Read::fileline()->warnOff(msg, warnOff))) {
if (!V3Read::optFuture(msg)) {
if (!(PARSEP->fileline()->warnOff(msg, warnOff))) {
if (!PARSEP->optFuture(msg)) {
yyerrorf("Unknown verilator lint message code: %s, in %s",msg.c_str(), textp);
}
}
}
void V3Read::verilatorCmtLintSave() {
s_readp->m_lintState.push_back(*V3Read::fileline());
void V3ParseImp::verilatorCmtLintSave() {
m_lintState.push_back(*PARSEP->fileline());
}
void V3Read::verilatorCmtLintRestore() {
if (s_readp->m_lintState.empty()) {
void V3ParseImp::verilatorCmtLintRestore() {
if (m_lintState.empty()) {
yyerrorf("/*verilator lint_restore*/ without matching save.");
return;
}
V3Read::fileline()->warnStateFrom(s_readp->m_lintState.back());
s_readp->m_lintState.pop_back();
PARSEP->fileline()->warnStateFrom(m_lintState.back());
m_lintState.pop_back();
}
void V3Read::verilatorCmtBad(const char* textp) {
void V3ParseImp::verilatorCmtBad(const char* textp) {
string cmtparse = textp;
if (cmtparse.substr(0,strlen("/*verilator")) == "/*verilator") {
cmtparse.replace(0,strlen("/*verilator"), "");
@ -91,20 +94,20 @@ void V3Read::verilatorCmtBad(const char* textp) {
for (int i=0; isalnum(cmtparse[i]); i++) {
cmtname += cmtparse[i];
}
if (!V3Read::optFuture(cmtname)) {
if (!PARSEP->optFuture(cmtname)) {
yyerrorf("Unknown verilator comment: %s",textp);
}
}
// See V3Read.cpp
//void V3Read::stateExitPsl() { BEGIN VLG; }
//void V3Read::statePushVlg() { yy_push_state(VLG); }
//void V3Read::statePop() { yy_pop_state(); }
//void V3ParseImp::stateExitPsl() { BEGIN VLG; }
//void V3ParseImp::statePushVlg() { yy_push_state(VLG); }
//void V3ParseImp::statePop() { yy_pop_state(); }
//======================================================================
void yyerror(const char* errmsg) {
V3Read::fileline()->v3error(errmsg);
PARSEP->fileline()->v3error(errmsg);
}
void yyerrorf(const char* format, ...) {
@ -577,16 +580,16 @@ escid \\[^ \t\f\r\n]+
"/*verilator public_module*/" { FL; return yVL_PUBLIC_MODULE; }
"/*verilator sc_clock*/" { FL; return yVL_CLOCK; }
"/*verilator systemc_clock*/" { FL; return yVL_CLOCK; }
"/*verilator tracing_off*/" {V3Read::fileline()->tracingOn(false); }
"/*verilator tracing_on*/" {V3Read::fileline()->tracingOn(true); }
"/*verilator coverage_off*/" {V3Read::fileline()->coverageOn(false); }
"/*verilator coverage_on*/" {V3Read::fileline()->coverageOn(true); }
"/*verilator lint_off"[^*]*"*/" {V3Read::verilatorCmtLint(yytext, true); }
"/*verilator lint_on"[^*]*"*/" {V3Read::verilatorCmtLint(yytext, false); }
"/*verilator lint_restore*/" {V3Read::verilatorCmtLintRestore(); }
"/*verilator lint_save*/" {V3Read::verilatorCmtLintSave(); }
"/*verilator tracing_off*/" {PARSEP->fileline()->tracingOn(false); }
"/*verilator tracing_on*/" {PARSEP->fileline()->tracingOn(true); }
"/*verilator coverage_off*/" {PARSEP->fileline()->coverageOn(false); }
"/*verilator coverage_on*/" {PARSEP->fileline()->coverageOn(true); }
"/*verilator lint_off"[^*]*"*/" {PARSEP->verilatorCmtLint(yytext, true); }
"/*verilator lint_on"[^*]*"*/" {PARSEP->verilatorCmtLint(yytext, false); }
"/*verilator lint_restore*/" {PARSEP->verilatorCmtLintRestore(); }
"/*verilator lint_save*/" {PARSEP->verilatorCmtLintSave(); }
"/*"[^*]*"*/" {V3Read::verilatorCmtBad(yytext); }
"/*"[^*]*"*/" {PARSEP->verilatorCmtBad(yytext); }
}
/************************************************************************/
@ -710,41 +713,41 @@ escid \\[^ \t\f\r\n]+
/* Identifiers and numbers */
<V95,V01,V05,S05,PSL>{
{escid} { FL; yylval.strp = V3Read::newString
{escid} { FL; yylval.strp = PARSEP->newString
(AstNode::encodeName(string(yytext+1))); // +1 to skip the backslash
return yaID__LEX;
}
{id} { FL; yylval.strp = V3Read::newString(AstNode::encodeName(string(yytext)));
{id} { FL; yylval.strp = PARSEP->newString(AstNode::encodeName(string(yytext)));
return yaID__LEX;
}
\"[^\"\\]*\" { FL; yylval.strp = V3Read::newString(yytext+1,yyleng-2);
\"[^\"\\]*\" { FL; yylval.strp = PARSEP->newString(yytext+1,yyleng-2);
return yaSTRING;
}
\" { yy_push_state(STRING); yymore(); }
[0-9]*?['']s?[bcodhBCODH][ \t]*[A-Fa-f0-9xXzZ_?]* {
FL; yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext);
FL; yylval.nump = PARSEP->newNumber(PARSEP->fileline(),(char*)yytext);
return yaINTNUM;
}
[0-9]*?['']s?[01xXzZ] { /* SystemVerilog */
FL; yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext);
FL; yylval.nump = PARSEP->newNumber(PARSEP->fileline(),(char*)yytext);
return yaINTNUM;
}
/* Note below is constructed to not match the ' that begins a '( or '{ */
[0-9][_0-9]*[ \t]*['']s?[bcodhBCODH]?[ \t]*[A-Fa-f0-9xXzZ_?]+ {
FL; yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext);
FL; yylval.nump = PARSEP->newNumber(PARSEP->fileline(),(char*)yytext);
return yaINTNUM;
}
[0-9][_0-9]*[ \t]*['']s?[bcodhBCODH] {
FL; yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext);
FL; yylval.nump = PARSEP->newNumber(PARSEP->fileline(),(char*)yytext);
return yaINTNUM;
}
[0-9][_0-9]*[ \t]*['']s {
FL; yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext);
FL; yylval.nump = PARSEP->newNumber(PARSEP->fileline(),(char*)yytext);
return yaINTNUM;
}
[0-9][_0-9]* {
FL; yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext);
FL; yylval.nump = PARSEP->newNumber(PARSEP->fileline(),(char*)yytext);
return yaINTNUM;
}
[0-9][_0-9]*(\.[_0-9]+)([eE][-+]?[_0-9]+)? {
@ -768,7 +771,7 @@ escid \\[^ \t\f\r\n]+
<STRING>\\{crnl} { yymore(); NEXTLINE(); }
<STRING>\\. { yymore(); }
<STRING>\" { yy_pop_state();
FL; yylval.strp = V3Read::newString(yytext+1,yyleng-2);
FL; yylval.strp = PARSEP->newString(yytext+1,yyleng-2);
return yaSTRING; }
<STRING>. { yymore(); }
@ -793,7 +796,7 @@ escid \\[^ \t\f\r\n]+
<V95,V01,V05,S05,PSL,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{
"`accelerate" { } // Verilog-XL compatibility
"`autoexpand_vectornets" { } // Verilog-XL compatibility
"`celldefine" { V3Read::inCellDefine(true); }
"`celldefine" { PARSEP->inCellDefine(true); }
"`default_decay_time"{ws}+[^\n\r]* { } // Verilog spec - delays only
"`default_nettype"{ws}+[a-zA-Z0-9]* { yyerrorf("Unsupported: Verilog 2001 directive not implemented: %s",yytext); } // Verilog 2001
"`delay_mode_distributed" { } // Verilog spec - delays only
@ -802,11 +805,11 @@ escid \\[^ \t\f\r\n]+
"`delay_mode_zero" { } // Verilog spec - delays only
"`disable_portfaults" { } // Verilog-XL compatibility
"`enable_portfaults" { } // Verilog-XL compatibility
"`endcelldefine" { V3Read::inCellDefine(false); }
"`endcelldefine" { PARSEP->inCellDefine(false); }
"`endprotect" { }
"`expand_vectornets" { } // Verilog-XL compatibility
"`inline" { }
"`line"{ws}+[^\n\r]*{crnl} { V3Read::ppline(yytext); }
"`line"{ws}+[^\n\r]*{crnl} { PARSEP->ppline(yytext); }
"`noaccelerate" { } // Verilog-XL compatibility
"`noexpand_vectornets" { } // Verilog-XL compatibility
"`noremove_gatenames" { } // Verilog-XL compatibility
@ -816,7 +819,7 @@ escid \\[^ \t\f\r\n]+
"`portcoerce" { }
"`pragma"{ws}+[^\n\r]* { } // Verilog 2005
"`protect" { }
"`psl" { if (V3Read::optPsl()) { BEGIN PSL; } else { BEGIN IGNORE; } }
"`psl" { if (PARSEP->optPsl()) { BEGIN PSL; } else { BEGIN IGNORE; } }
"`remove_gatenames" { } // Verilog-XL compatibility
"`remove_netnames" { } // Verilog-XL compatibility
"`resetall" { }
@ -824,12 +827,12 @@ escid \\[^ \t\f\r\n]+
"`timescale"{ws}+[^\n\r]* { } // Verilog spec - not supported
/* See also setLanguage below */
"`begin_keywords"[ \t]*\"1364-1995\" { yy_push_state(V95); V3Read::pushBeginKeywords(YY_START); }
"`begin_keywords"[ \t]*\"1364-2001\" { yy_push_state(V01); V3Read::pushBeginKeywords(YY_START); }
"`begin_keywords"[ \t]*\"1364-2001-noconfig\" { yy_push_state(V01); V3Read::pushBeginKeywords(YY_START); }
"`begin_keywords"[ \t]*\"1364-2005\" { yy_push_state(V05); V3Read::pushBeginKeywords(YY_START); }
"`begin_keywords"[ \t]*\"1800-2005\" { yy_push_state(S05); V3Read::pushBeginKeywords(YY_START); }
"`end_keywords" { yy_pop_state(); if (!V3Read::popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); }
"`begin_keywords"[ \t]*\"1364-1995\" { yy_push_state(V95); PARSEP->pushBeginKeywords(YY_START); }
"`begin_keywords"[ \t]*\"1364-2001\" { yy_push_state(V01); PARSEP->pushBeginKeywords(YY_START); }
"`begin_keywords"[ \t]*\"1364-2001-noconfig\" { yy_push_state(V01); PARSEP->pushBeginKeywords(YY_START); }
"`begin_keywords"[ \t]*\"1364-2005\" { yy_push_state(V05); PARSEP->pushBeginKeywords(YY_START); }
"`begin_keywords"[ \t]*\"1800-2005\" { yy_push_state(S05); PARSEP->pushBeginKeywords(YY_START); }
"`end_keywords" { yy_pop_state(); if (!PARSEP->popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); }
/* Verilator */
"`systemc_ctor" { BEGIN SYSCCTOR; }
@ -838,15 +841,15 @@ escid \\[^ \t\f\r\n]+
"`systemc_imp_header" { BEGIN SYSCIMPH; }
"`systemc_implementation" { BEGIN SYSCIMP; }
"`systemc_interface" { BEGIN SYSCINT; }
"`verilog" { BEGIN V3Read::lastVerilogState(); }
"`verilog" { BEGIN PARSEP->lastVerilogState(); }
}
<SYSCHDR>[ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCHDR; }
<SYSCINT>[ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCINT; }
<SYSCIMP>[ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCIMP; }
<SYSCIMPH>[ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCIMPH; }
<SYSCCTOR>[ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCCTOR; }
<SYSCDTOR>[ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCDTOR; }
<SYSCHDR>[ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCHDR; }
<SYSCINT>[ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCINT; }
<SYSCIMP>[ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCIMP; }
<SYSCIMPH>[ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCIMPH; }
<SYSCCTOR>[ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCCTOR; }
<SYSCDTOR>[ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCDTOR; }
<IGNORE>[ \t]*[^` \t\n\r][^\n\r]*{crnl} { NEXTLINE(); }
/* Pick up text-type data */
@ -867,4 +870,24 @@ escid \\[^ \t\f\r\n]+
/* Catch all - absolutely last */
<*>.|\n { yyerrorf("Missing verilog.l rule: Default rule invoked in state %d: %s", YY_START, yytext); }
%%
int V3Read::stateVerilogRecent() { return STATE_VERILOG_RECENT; }
int V3ParseImp::stateVerilogRecent() { return STATE_VERILOG_RECENT; }
int V3ParseImp::lexToken() {
// called from lexToBison, has a "this"
// yylvalp is global
int token = yylexThis();
if (token == yaID__LEX) { token = yaID__ETC; }
return token;
}
int V3ParseImp::lexToBison() {
// Called as global since bison doesn't have our pointer
int tok = lexToken();
//yylval.scp = NULL; // Symbol table not yet needed - no packages
if (debugFlex()>=6 || debugBison()>=6) {
cout<<" lexToBison TOKEN="<<tok<<" "<<tokenName(tok);
cout<<endl;
}
return tok;
}

View File

@ -26,16 +26,16 @@
#include <cstdarg>
#include <cstring>
#include "V3Read.h"
#include "V3Ast.h"
#include "V3Global.h"
#include "V3ParseImp.h" // Defines YYTYPE; before including bison header
#define YYERROR_VERBOSE 1
#define YYINITDEPTH 10000 // Older bisons ignore YYMAXDEPTH
#define YYMAXDEPTH 10000
// Pick up new lexer
#define yylex V3Read::yylex
#define yylex PARSEP->lexToBison
#define PSLUNSUP(what) NULL; yyerrorf("Unsupported: PSL language feature not implemented");
extern void yyerror(const char* errmsg);
@ -44,74 +44,84 @@ extern void yyerrorf(const char* format, ...);
//======================================================================
// Statics (for here only)
class V3Parse {
class V3ParseGrammar {
public:
static bool s_impliedDecl; // Allow implied wire declarations
static AstVarType s_varDecl; // Type for next signal declaration (reg/wire/etc)
static AstVarType s_varIO; // Type for next signal declaration (input/output/etc)
static bool s_varSigned; // Signed state for next signal declaration
static AstVar* s_varAttrp; // Current variable for attribute adding
static AstCase* s_caseAttrp; // Current case statement for attribute adding
static AstRange* s_varRangep; // Pointer to range for next signal declaration
static int s_pinNum; // Pin number currently parsing
static string s_instModule; // Name of module referenced for instantiations
static AstPin* s_instParamp; // Parameters for instantiations
static int s_uniqueAttr; // Bitmask of unique/priority keywords
bool m_impliedDecl; // Allow implied wire declarations
AstVarType m_varDecl; // Type for next signal declaration (reg/wire/etc)
AstVarType m_varIO; // Type for next signal declaration (input/output/etc)
bool m_varSigned; // Signed state for next signal declaration
AstVar* m_varAttrp; // Current variable for attribute adding
AstCase* m_caseAttrp; // Current case statement for attribute adding
AstRange* m_varRangep; // Pointer to range for next signal declaration
int m_pinNum; // Pin number currently parsing
string m_instModule; // Name of module referenced for instantiations
AstPin* m_instParamp; // Parameters for instantiations
int m_uniqueAttr; // Bitmask of unique/priority keywords
static AstVar* createVariable(FileLine* fileline, string name, AstRange* arrayp, AstNode* attrsp);
static AstNode* createSupplyExpr(FileLine* fileline, string name, int value);
static AstText* createTextQuoted(FileLine* fileline, string text);
static AstDisplay* createDisplayError(FileLine* fileline) {
// CONSTRUCTORS
V3ParseGrammar() {
m_impliedDecl = false;
m_varDecl = AstVarType::UNKNOWN;
m_varIO = AstVarType::UNKNOWN;
m_varSigned = false;
m_varRangep = NULL;
m_pinNum = -1;
m_instModule;
m_instParamp = NULL;
m_varAttrp = NULL;
m_caseAttrp = NULL;
}
static V3ParseGrammar* singletonp() {
static V3ParseGrammar singleton;
return &singleton;
}
// METHODS
AstVar* createVariable(FileLine* fileline, string name, AstRange* arrayp, AstNode* attrsp);
AstNode* createSupplyExpr(FileLine* fileline, string name, int value);
AstText* createTextQuoted(FileLine* fileline, string text) {
string newtext = deQuote(fileline, text);
return new AstText(fileline, newtext);
}
AstDisplay* createDisplayError(FileLine* fileline) {
AstDisplay* nodep = new AstDisplay(fileline,AstDisplayType::ERROR, "", NULL,NULL);
nodep->addNext(new AstStop(fileline));
return nodep;
}
static void setRange(AstRange* rangep) {
if (s_varRangep) { s_varRangep->deleteTree(); s_varRangep=NULL; } // It was cloned, so this is safe.
s_varRangep = rangep;
}
static string deQuote(FileLine* fileline, string text);
};
bool V3Parse::s_impliedDecl = false;
AstVarType V3Parse::s_varDecl = AstVarType::UNKNOWN;
AstVarType V3Parse::s_varIO = AstVarType::UNKNOWN;
bool V3Parse::s_varSigned = false;
AstRange* V3Parse::s_varRangep = NULL;
int V3Parse::s_pinNum = -1;
string V3Parse::s_instModule;
AstPin* V3Parse::s_instParamp = NULL;
AstVar* V3Parse::s_varAttrp = NULL;
AstCase* V3Parse::s_caseAttrp = NULL;
//======================================================================
// Utility functions
static AstNode* newVarInit(FileLine* fileline, AstNode* varp, AstNode* initp) {
AstNode* newVarInit(FileLine* fileline, AstNode* varp, AstNode* initp) {
return new AstInitial(fileline, new AstAssign(fileline,
new AstVarRef(fileline, varp->name(),true),
initp));
}
}
void setRange(AstRange* rangep) {
if (m_varRangep) { m_varRangep->deleteTree(); m_varRangep=NULL; } // It was cloned, so this is safe.
m_varRangep = rangep;
}
string deQuote(FileLine* fileline, string text);
};
#define PARSEP V3ParseImp::parsep()
#define GRAMMARP V3ParseGrammar::singletonp()
//======================================================================
// Macro functions
#define CRELINE() (V3Read::copyOrSameFileLine())
#define CRELINE() (PARSEP->copyOrSameFileLine())
#define VARRESET_LIST(decl) { V3Parse::s_pinNum=1; VARRESET(); VARDECL(decl); } // Start of pinlist
#define VARRESET_NONLIST(decl) { V3Parse::s_pinNum=0; VARRESET(); VARDECL(decl); } // Not in a pinlist
#define VARRESET_LIST(decl) { GRAMMARP->m_pinNum=1; VARRESET(); VARDECL(decl); } // Start of pinlist
#define VARRESET_NONLIST(decl) { GRAMMARP->m_pinNum=0; VARRESET(); VARDECL(decl); } // Not in a pinlist
#define VARRESET() { VARDECL(UNKNOWN); VARIO(UNKNOWN); VARSIGNED(false); VARRANGE(NULL); }
#define VARDECL(type) { V3Parse::s_varDecl = AstVarType::type; }
#define VARIO(type) { V3Parse::s_varIO = AstVarType::type; }
#define VARSIGNED(value) { V3Parse::s_varSigned = value; }
#define VARRANGE(rangep) { V3Parse::setRange(rangep); }
#define VARDECL(type) { GRAMMARP->m_varDecl = AstVarType::type; }
#define VARIO(type) { GRAMMARP->m_varIO = AstVarType::type; }
#define VARSIGNED(value) { GRAMMARP->m_varSigned = value; }
#define VARRANGE(rangep) { GRAMMARP->setRange(rangep); }
#define VARTYPE(typep) { VARRANGE(typep); } // Temp until other data types supported
#define VARDONEA(name,array,attrs) V3Parse::createVariable(CRELINE(),(name),(array),(attrs))
#define VARDONEP(portp,array,attrs) V3Parse::createVariable((portp)->fileline(),(portp)->name(),(array),(attrs))
#define PINNUMINC() (V3Parse::s_pinNum++)
#define VARDONEA(name,array,attrs) GRAMMARP->createVariable(CRELINE(),(name),(array),(attrs))
#define VARDONEP(portp,array,attrs) GRAMMARP->createVariable((portp)->fileline(),(portp)->name(),(array),(attrs))
#define PINNUMINC() (GRAMMARP->m_pinNum++)
#define INSTPREP(modname,paramsp) { V3Parse::s_impliedDecl = true; V3Parse::s_instModule = modname; V3Parse::s_instParamp = paramsp; }
#define INSTPREP(modname,paramsp) { GRAMMARP->m_impliedDecl = true; GRAMMARP->m_instModule = modname; GRAMMARP->m_instParamp = paramsp; }
static void ERRSVKWD(FileLine* fileline, const string& tokname) {
static int toldonce = 0;
@ -124,30 +134,6 @@ static void ERRSVKWD(FileLine* fileline, const string& tokname) {
class AstSenTree;
%}
%union {
FileLine* fileline;
V3Number* nump;
string* strp;
int cint;
double cdouble;
V3UniqState uniqstate;
AstNode* nodep;
AstCase* casep;
AstCaseItem* caseitemp;
AstConst* constp;
AstFunc* funcp;
AstModule* modulep;
AstNodeVarRef* varnodep;
AstParseRef* parserefp;
AstPin* pinp;
AstRange* rangep;
AstNodeSenItem* senitemp;
AstSenTree* sentreep;
AstVar* varp;
}
// When writing Bison patterns we use yTOKEN instead of "token",
// so Bison will error out on unknown "token"s.
@ -170,7 +156,7 @@ class AstSenTree;
%token<strp> yaSTRING "STRING"
%token<strp> yaSTRING__IGNORE "STRING-ignored" // Used when expr:string not allowed
%token<fileline> yaTIMINGSPEC "TIMING SPEC ELEMENT"
%token<fl> yaTIMINGSPEC "TIMING SPEC ELEMENT"
%token<strp> yaSCHDR "`systemc_header BLOCK"
%token<strp> yaSCINT "`systemc_ctor BLOCK"
@ -179,32 +165,33 @@ class AstSenTree;
%token<strp> yaSCCTOR "`systemc_implementation BLOCK"
%token<strp> yaSCDTOR "`systemc_imp_header BLOCK"
%token<fileline> '!'
%token<fileline> '#'
%token<fileline> '%'
%token<fileline> '&'
%token<fileline> '('
%token<fileline> ')'
%token<fileline> '*'
%token<fileline> '+'
%token<fileline> ','
%token<fileline> '-'
%token<fileline> '.'
%token<fileline> '/'
%token<fileline> ':'
%token<fileline> ';'
%token<fileline> '<'
%token<fileline> '='
%token<fileline> '>'
%token<fileline> '?'
%token<fileline> '@'
%token<fileline> '['
%token<fileline> ']'
%token<fileline> '^'
%token<fileline> '{'
%token<fileline> '|'
%token<fileline> '}'
%token<fileline> '~'
// <fl> is the fileline, abbreviated to shorten "$<fl>1" references
%token<fl> '!'
%token<fl> '#'
%token<fl> '%'
%token<fl> '&'
%token<fl> '('
%token<fl> ')'
%token<fl> '*'
%token<fl> '+'
%token<fl> ','
%token<fl> '-'
%token<fl> '.'
%token<fl> '/'
%token<fl> ':'
%token<fl> ';'
%token<fl> '<'
%token<fl> '='
%token<fl> '>'
%token<fl> '?'
%token<fl> '@'
%token<fl> '['
%token<fl> ']'
%token<fl> '^'
%token<fl> '{'
%token<fl> '|'
%token<fl> '}'
%token<fl> '~'
// Specific keywords
// yKEYWORD means match "keyword"
@ -212,195 +199,195 @@ class AstSenTree;
// for example yP_ for punctuation based operators.
// Double underscores "yX__Y" means token X followed by Y,
// and "yX__ETC" means X folled by everything but Y(s).
%token<fileline> yALWAYS "always"
%token<fileline> yAND "and"
%token<fileline> yASSERT "assert"
%token<fileline> yASSIGN "assign"
%token<fileline> yAUTOMATIC "automatic"
%token<fileline> yBEGIN "begin"
%token<fileline> yBUF "buf"
%token<fileline> yBUFIF0 "bufif0"
%token<fileline> yBUFIF1 "bufif1"
%token<fileline> yCASE "case"
%token<fileline> yCASEX "casex"
%token<fileline> yCASEZ "casez"
%token<fileline> yCLOCKING "clocking"
%token<fileline> yCOVER "cover"
%token<fileline> yDEFAULT "default"
%token<fileline> yDEFPARAM "defparam"
%token<fileline> yDISABLE "disable"
%token<fileline> yDO "do"
%token<fileline> yELSE "else"
%token<fileline> yEND "end"
%token<fileline> yENDCASE "endcase"
%token<fileline> yENDCLOCKING "endclocking"
%token<fileline> yENDFUNCTION "endfunction"
%token<fileline> yENDGENERATE "endgenerate"
%token<fileline> yENDMODULE "endmodule"
%token<fileline> yENDPROPERTY "endproperty"
%token<fileline> yENDSPECIFY "endspecify"
%token<fileline> yENDTASK "endtask"
%token<fileline> yFINAL "final"
%token<fileline> yFOR "for"
%token<fileline> yFOREVER "forever"
%token<fileline> yFUNCTION "function"
%token<fileline> yGENERATE "generate"
%token<fileline> yGENVAR "genvar"
%token<fileline> yIF "if"
%token<fileline> yIFF "iff"
%token<fileline> yLOGIC "logic"
%token<fileline> yINITIAL "initial"
%token<fileline> yINOUT "inout"
%token<fileline> yINPUT "input"
%token<fileline> yINTEGER "integer"
%token<fileline> yLOCALPARAM "localparam"
%token<fileline> yMODULE "module"
%token<fileline> yNAND "nand"
%token<fileline> yNEGEDGE "negedge"
%token<fileline> yNOR "nor"
%token<fileline> yNOT "not"
%token<fileline> yNOTIF0 "notif0"
%token<fileline> yNOTIF1 "notif1"
%token<fileline> yOR "or"
%token<fileline> yOUTPUT "output"
%token<fileline> yPARAMETER "parameter"
%token<fileline> yPOSEDGE "posedge"
%token<fileline> yPRIORITY "priority"
%token<fileline> yPROPERTY "property"
%token<fileline> yPULLDOWN "pulldown"
%token<fileline> yPULLUP "pullup"
%token<fileline> yREG "reg"
%token<fileline> yREPEAT "repeat"
%token<fileline> ySCALARED "scalared"
%token<fileline> ySIGNED "signed"
%token<fileline> ySPECIFY "specify"
%token<fileline> ySPECPARAM "specparam"
%token<fileline> ySTATIC "static"
%token<fileline> ySUPPLY0 "supply0"
%token<fileline> ySUPPLY1 "supply1"
%token<fileline> yTASK "task"
%token<fileline> yTIMEPRECISION "timeprecision"
%token<fileline> yTIMEUNIT "timeunit"
%token<fileline> yTRI "tri"
%token<fileline> yTRUE "true"
%token<fileline> yUNIQUE "unique"
%token<fileline> yUNSIGNED "unsigned"
%token<fileline> yVECTORED "vectored"
%token<fileline> yWHILE "while"
%token<fileline> yWIRE "wire"
%token<fileline> yXNOR "xnor"
%token<fileline> yXOR "xor"
%token<fl> yALWAYS "always"
%token<fl> yAND "and"
%token<fl> yASSERT "assert"
%token<fl> yASSIGN "assign"
%token<fl> yAUTOMATIC "automatic"
%token<fl> yBEGIN "begin"
%token<fl> yBUF "buf"
%token<fl> yBUFIF0 "bufif0"
%token<fl> yBUFIF1 "bufif1"
%token<fl> yCASE "case"
%token<fl> yCASEX "casex"
%token<fl> yCASEZ "casez"
%token<fl> yCLOCKING "clocking"
%token<fl> yCOVER "cover"
%token<fl> yDEFAULT "default"
%token<fl> yDEFPARAM "defparam"
%token<fl> yDISABLE "disable"
%token<fl> yDO "do"
%token<fl> yELSE "else"
%token<fl> yEND "end"
%token<fl> yENDCASE "endcase"
%token<fl> yENDCLOCKING "endclocking"
%token<fl> yENDFUNCTION "endfunction"
%token<fl> yENDGENERATE "endgenerate"
%token<fl> yENDMODULE "endmodule"
%token<fl> yENDPROPERTY "endproperty"
%token<fl> yENDSPECIFY "endspecify"
%token<fl> yENDTASK "endtask"
%token<fl> yFINAL "final"
%token<fl> yFOR "for"
%token<fl> yFOREVER "forever"
%token<fl> yFUNCTION "function"
%token<fl> yGENERATE "generate"
%token<fl> yGENVAR "genvar"
%token<fl> yIF "if"
%token<fl> yIFF "iff"
%token<fl> yLOGIC "logic"
%token<fl> yINITIAL "initial"
%token<fl> yINOUT "inout"
%token<fl> yINPUT "input"
%token<fl> yINTEGER "integer"
%token<fl> yLOCALPARAM "localparam"
%token<fl> yMODULE "module"
%token<fl> yNAND "nand"
%token<fl> yNEGEDGE "negedge"
%token<fl> yNOR "nor"
%token<fl> yNOT "not"
%token<fl> yNOTIF0 "notif0"
%token<fl> yNOTIF1 "notif1"
%token<fl> yOR "or"
%token<fl> yOUTPUT "output"
%token<fl> yPARAMETER "parameter"
%token<fl> yPOSEDGE "posedge"
%token<fl> yPRIORITY "priority"
%token<fl> yPROPERTY "property"
%token<fl> yPULLDOWN "pulldown"
%token<fl> yPULLUP "pullup"
%token<fl> yREG "reg"
%token<fl> yREPEAT "repeat"
%token<fl> ySCALARED "scalared"
%token<fl> ySIGNED "signed"
%token<fl> ySPECIFY "specify"
%token<fl> ySPECPARAM "specparam"
%token<fl> ySTATIC "static"
%token<fl> ySUPPLY0 "supply0"
%token<fl> ySUPPLY1 "supply1"
%token<fl> yTASK "task"
%token<fl> yTIMEPRECISION "timeprecision"
%token<fl> yTIMEUNIT "timeunit"
%token<fl> yTRI "tri"
%token<fl> yTRUE "true"
%token<fl> yUNIQUE "unique"
%token<fl> yUNSIGNED "unsigned"
%token<fl> yVECTORED "vectored"
%token<fl> yWHILE "while"
%token<fl> yWIRE "wire"
%token<fl> yXNOR "xnor"
%token<fl> yXOR "xor"
%token<fileline> yD_BITS "$bits"
%token<fileline> yD_C "$c"
%token<fileline> yD_CLOG2 "$clog2"
%token<fileline> yD_COUNTONES "$countones"
%token<fileline> yD_DISPLAY "$display"
%token<fileline> yD_ERROR "$error"
%token<fileline> yD_FATAL "$fatal"
%token<fileline> yD_FCLOSE "$fclose"
%token<fileline> yD_FDISPLAY "$fdisplay"
%token<fileline> yD_FEOF "$feof"
%token<fileline> yD_FFLUSH "$fflush"
%token<fileline> yD_FGETC "$fgetc"
%token<fileline> yD_FGETS "$fgets"
%token<fileline> yD_FINISH "$finish"
%token<fileline> yD_FOPEN "$fopen"
%token<fileline> yD_FSCANF "$fscanf"
%token<fileline> yD_FWRITE "$fwrite"
%token<fileline> yD_INFO "$info"
%token<fileline> yD_ISUNKNOWN "$isunknown"
%token<fileline> yD_ONEHOT "$onehot"
%token<fileline> yD_ONEHOT0 "$onehot0"
%token<fileline> yD_RANDOM "$random"
%token<fileline> yD_READMEMB "$readmemb"
%token<fileline> yD_READMEMH "$readmemh"
%token<fileline> yD_SIGNED "$signed"
%token<fileline> yD_SSCANF "$sscanf"
%token<fileline> yD_STIME "$stime"
%token<fileline> yD_STOP "$stop"
%token<fileline> yD_TIME "$time"
%token<fileline> yD_UNSIGNED "$unsigned"
%token<fileline> yD_WARNING "$warning"
%token<fileline> yD_WRITE "$write"
%token<fileline> yD_aIGNORE "${ignored-bbox-sys}"
%token<fl> yD_BITS "$bits"
%token<fl> yD_C "$c"
%token<fl> yD_CLOG2 "$clog2"
%token<fl> yD_COUNTONES "$countones"
%token<fl> yD_DISPLAY "$display"
%token<fl> yD_ERROR "$error"
%token<fl> yD_FATAL "$fatal"
%token<fl> yD_FCLOSE "$fclose"
%token<fl> yD_FDISPLAY "$fdisplay"
%token<fl> yD_FEOF "$feof"
%token<fl> yD_FFLUSH "$fflush"
%token<fl> yD_FGETC "$fgetc"
%token<fl> yD_FGETS "$fgets"
%token<fl> yD_FINISH "$finish"
%token<fl> yD_FOPEN "$fopen"
%token<fl> yD_FSCANF "$fscanf"
%token<fl> yD_FWRITE "$fwrite"
%token<fl> yD_INFO "$info"
%token<fl> yD_ISUNKNOWN "$isunknown"
%token<fl> yD_ONEHOT "$onehot"
%token<fl> yD_ONEHOT0 "$onehot0"
%token<fl> yD_RANDOM "$random"
%token<fl> yD_READMEMB "$readmemb"
%token<fl> yD_READMEMH "$readmemh"
%token<fl> yD_SIGNED "$signed"
%token<fl> yD_SSCANF "$sscanf"
%token<fl> yD_STIME "$stime"
%token<fl> yD_STOP "$stop"
%token<fl> yD_TIME "$time"
%token<fl> yD_UNSIGNED "$unsigned"
%token<fl> yD_WARNING "$warning"
%token<fl> yD_WRITE "$write"
%token<fl> yD_aIGNORE "${ignored-bbox-sys}"
%token<fileline> yPSL "psl"
%token<fileline> yPSL_ASSERT "PSL assert"
%token<fileline> yPSL_CLOCK "PSL clock"
%token<fileline> yPSL_COVER "PSL cover"
%token<fileline> yPSL_REPORT "PSL report"
%token<fl> yPSL "psl"
%token<fl> yPSL_ASSERT "PSL assert"
%token<fl> yPSL_CLOCK "PSL clock"
%token<fl> yPSL_COVER "PSL cover"
%token<fl> yPSL_REPORT "PSL report"
%token<fileline> yVL_CLOCK "/*verilator sc_clock*/"
%token<fileline> yVL_CLOCK_ENABLE "/*verilator clock_enable*/"
%token<fileline> yVL_COVERAGE_BLOCK_OFF "/*verilator coverage_block_off*/"
%token<fileline> yVL_FULL_CASE "/*verilator full_case*/"
%token<fileline> yVL_INLINE_MODULE "/*verilator inline_module*/"
%token<fileline> yVL_ISOLATE_ASSIGNMENTS "/*verilator isolate_assignments*/"
%token<fileline> yVL_NO_INLINE_MODULE "/*verilator no_inline_module*/"
%token<fileline> yVL_NO_INLINE_TASK "/*verilator no_inline_task*/"
%token<fileline> yVL_PARALLEL_CASE "/*verilator parallel_case*/"
%token<fileline> yVL_PUBLIC "/*verilator public*/"
%token<fileline> yVL_PUBLIC_FLAT "/*verilator public_flat*/"
%token<fileline> yVL_PUBLIC_MODULE "/*verilator public_module*/"
%token<fl> yVL_CLOCK "/*verilator sc_clock*/"
%token<fl> yVL_CLOCK_ENABLE "/*verilator clock_enable*/"
%token<fl> yVL_COVERAGE_BLOCK_OFF "/*verilator coverage_block_off*/"
%token<fl> yVL_FULL_CASE "/*verilator full_case*/"
%token<fl> yVL_INLINE_MODULE "/*verilator inline_module*/"
%token<fl> yVL_ISOLATE_ASSIGNMENTS "/*verilator isolate_assignments*/"
%token<fl> yVL_NO_INLINE_MODULE "/*verilator no_inline_module*/"
%token<fl> yVL_NO_INLINE_TASK "/*verilator no_inline_task*/"
%token<fl> yVL_PARALLEL_CASE "/*verilator parallel_case*/"
%token<fl> yVL_PUBLIC "/*verilator public*/"
%token<fl> yVL_PUBLIC_FLAT "/*verilator public_flat*/"
%token<fl> yVL_PUBLIC_MODULE "/*verilator public_module*/"
%token<fileline> yP_TICK "'"
%token<fileline> yP_TICKBRA "'{"
%token<fileline> yP_OROR "||"
%token<fileline> yP_ANDAND "&&"
%token<fileline> yP_NOR "~|"
%token<fileline> yP_XNOR "^~"
%token<fileline> yP_NAND "~&"
%token<fileline> yP_EQUAL "=="
%token<fileline> yP_NOTEQUAL "!="
%token<fileline> yP_CASEEQUAL "==="
%token<fileline> yP_CASENOTEQUAL "!=="
%token<fileline> yP_WILDEQUAL "==?"
%token<fileline> yP_WILDNOTEQUAL "!=?"
%token<fileline> yP_GTE ">="
%token<fileline> yP_LTE "<="
%token<fileline> yP_SLEFT "<<"
%token<fileline> yP_SRIGHT ">>"
%token<fileline> yP_SSRIGHT ">>>"
%token<fileline> yP_POW "**"
%token<fl> yP_TICK "'"
%token<fl> yP_TICKBRA "'{"
%token<fl> yP_OROR "||"
%token<fl> yP_ANDAND "&&"
%token<fl> yP_NOR "~|"
%token<fl> yP_XNOR "^~"
%token<fl> yP_NAND "~&"
%token<fl> yP_EQUAL "=="
%token<fl> yP_NOTEQUAL "!="
%token<fl> yP_CASEEQUAL "==="
%token<fl> yP_CASENOTEQUAL "!=="
%token<fl> yP_WILDEQUAL "==?"
%token<fl> yP_WILDNOTEQUAL "!=?"
%token<fl> yP_GTE ">="
%token<fl> yP_LTE "<="
%token<fl> yP_SLEFT "<<"
%token<fl> yP_SRIGHT ">>"
%token<fl> yP_SSRIGHT ">>>"
%token<fl> yP_POW "**"
%token<fileline> yP_PLUSCOLON "+:"
%token<fileline> yP_MINUSCOLON "-:"
%token<fileline> yP_MINUSGT "->"
%token<fileline> yP_MINUSGTGT "->>"
%token<fileline> yP_EQGT "=>"
%token<fileline> yP_ASTGT "*>"
%token<fileline> yP_ANDANDAND "&&&"
%token<fileline> yP_POUNDPOUND "##"
%token<fileline> yP_DOTSTAR ".*"
%token<fl> yP_PLUSCOLON "+:"
%token<fl> yP_MINUSCOLON "-:"
%token<fl> yP_MINUSGT "->"
%token<fl> yP_MINUSGTGT "->>"
%token<fl> yP_EQGT "=>"
%token<fl> yP_ASTGT "*>"
%token<fl> yP_ANDANDAND "&&&"
%token<fl> yP_POUNDPOUND "##"
%token<fl> yP_DOTSTAR ".*"
%token<fileline> yP_ATAT "@@"
%token<fileline> yP_COLONCOLON "::"
%token<fileline> yP_COLONEQ ":="
%token<fileline> yP_COLONDIV ":/"
%token<fileline> yP_ORMINUSGT "|->"
%token<fileline> yP_OREQGT "|=>"
%token<fileline> yP_BRASTAR "[*"
%token<fileline> yP_BRAEQ "[="
%token<fileline> yP_BRAMINUSGT "[->"
%token<fl> yP_ATAT "@@"
%token<fl> yP_COLONCOLON "::"
%token<fl> yP_COLONEQ ":="
%token<fl> yP_COLONDIV ":/"
%token<fl> yP_ORMINUSGT "|->"
%token<fl> yP_OREQGT "|=>"
%token<fl> yP_BRASTAR "[*"
%token<fl> yP_BRAEQ "[="
%token<fl> yP_BRAMINUSGT "[->"
%token<fileline> yP_PLUSPLUS "++"
%token<fileline> yP_MINUSMINUS "--"
%token<fileline> yP_PLUSEQ "+="
%token<fileline> yP_MINUSEQ "-="
%token<fileline> yP_TIMESEQ "*="
%token<fileline> yP_DIVEQ "/="
%token<fileline> yP_MODEQ "%="
%token<fileline> yP_ANDEQ "&="
%token<fileline> yP_OREQ "|="
%token<fileline> yP_XOREQ "^="
%token<fileline> yP_SLEFTEQ "<<="
%token<fileline> yP_SRIGHTEQ ">>="
%token<fileline> yP_SSRIGHTEQ ">>>="
%token<fl> yP_PLUSPLUS "++"
%token<fl> yP_MINUSMINUS "--"
%token<fl> yP_PLUSEQ "+="
%token<fl> yP_MINUSEQ "-="
%token<fl> yP_TIMESEQ "*="
%token<fl> yP_DIVEQ "/="
%token<fl> yP_MODEQ "%="
%token<fl> yP_ANDEQ "&="
%token<fl> yP_OREQ "|="
%token<fl> yP_XOREQ "^="
%token<fl> yP_SLEFTEQ "<<="
%token<fl> yP_SRIGHTEQ ">>="
%token<fl> yP_SSRIGHTEQ ">>>="
%token<fileline> yPSL_BRA "{"
%token<fileline> yPSL_KET "}"
%token<fileline> yP_LOGIFF
%token<fl> yPSL_BRA "{"
%token<fl> yPSL_KET "}"
%token<fl> yP_LOGIFF
// [* is not a operator, as "[ * ]" is legal
// [= and [-> could be repitition operators, but to match [* we don't add them.
@ -410,7 +397,7 @@ class AstSenTree;
// PSL op precedence
%right yP_MINUSGT yP_LOGIFF
%right yP_ORMINUSGT yP_OREQGT
%left<fileline> prPSLCLK
%left<fl> prPSLCLK
// Verilog op precedence
%right '?' ':'
@ -464,13 +451,13 @@ class AstSenTree;
// Note we read a parenthesis ahead, so this may not change the lexer at the right point.
stateExitPsl: // For PSL lexing, return from PSL state
/* empty */ { V3Read::stateExitPsl(); }
/* empty */ { PARSEP->stateExitPsl(); }
;
statePushVlg: // For PSL lexing, escape current state into Verilog state
/* empty */ { V3Read::statePushVlg(); }
/* empty */ { PARSEP->statePushVlg(); }
;
statePop: // Return to previous lexing state
/* empty */ { V3Read::statePop(); }
/* empty */ { PARSEP->statePop(); }
;
//**********************************************************************
@ -533,17 +520,21 @@ module_declaration: // ==IEEE: module_declaration
module_itemListE yENDMODULE endLabelE
{ $1->modTrace(v3Global.opt.trace() && $1->fileline()->tracingOn()); // Stash for implicit wires, etc
if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3);
if ($5) $1->addStmtp($5); }
if ($5) $1->addStmtp($5);
}
//
//UNSUP yEXTERN modFront parameter_port_listE portsStarE ';'
//UNSUP { UNSUP }
;
modFront<modulep>:
// // General note: all *Front functions must call symPushNew before
// // any formal arguments, as the arguments must land in the new scope.
yMODULE lifetimeE idAny
{ $$ = new AstModule($1,*$3); $$->inLibrary(V3Read::inLibrary()||V3Read::inCellDefine());
{ $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine());
$$->modTrace(v3Global.opt.trace());
V3Read::rootp()->addModulep($$); }
PARSEP->rootp()->addModulep($$);
}
;
parameter_value_assignmentE<pinp>: // IEEE: [ parameter_value_assignment ]
@ -638,10 +629,10 @@ port<nodep>: // ==IEEE: port
| portDirNetE signingE rangeList portSig variable_dimensionListE sigAttrListE { $$=$4; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE { $$=$2; /*VARTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); }
//
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); $$->addNextNull(newVarInit($6,$$,$7)); }
//UNSUP portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(newVarInit($7,$$,$8)); }
//UNSUP portDirNetE yVAR implicit_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(newVarInit($7,$$,$8)); }
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; /*VARTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); $$->addNextNull(newVarInit($5,$$,$6)); }
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); $$->addNextNull(GRAMMARP->newVarInit($6,$$,$7)); }
//UNSUP portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(GRAMMARP->newVarInit($7,$$,$8)); }
//UNSUP portDirNetE yVAR implicit_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(GRAMMARP->newVarInit($7,$$,$8)); }
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; /*VARTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); $$->addNextNull(GRAMMARP->newVarInit($5,$$,$6)); }
;
portDirNetE: // IEEE: part of port, optional net type and/or direction
@ -981,12 +972,12 @@ non_port_module_item<nodep>: // ==IEEE: non_port_module_item
//UNSUP interface_declaration { $$ = $1; }
| timeunits_declaration { $$ = NULL; }
// // Verilator specific
| yaSCHDR { $$ = new AstScHdr(CRELINE(),*$1); }
| yaSCINT { $$ = new AstScInt(CRELINE(),*$1); }
| yaSCIMP { $$ = new AstScImp(CRELINE(),*$1); }
| yaSCIMPH { $$ = new AstScImpHdr(CRELINE(),*$1); }
| yaSCCTOR { $$ = new AstScCtor(CRELINE(),*$1); }
| yaSCDTOR { $$ = new AstScDtor(CRELINE(),*$1); }
| yaSCHDR { $$ = new AstScHdr($<fl>1,*$1); }
| yaSCINT { $$ = new AstScInt($<fl>1,*$1); }
| yaSCIMP { $$ = new AstScImp($<fl>1,*$1); }
| yaSCIMPH { $$ = new AstScImpHdr($<fl>1,*$1); }
| yaSCCTOR { $$ = new AstScCtor($<fl>1,*$1); }
| yaSCDTOR { $$ = new AstScDtor($<fl>1,*$1); }
| yVL_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::INLINE_MODULE); }
| yVL_NO_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_MODULE); }
| yVL_PUBLIC_MODULE { $$ = new AstPragma($1,AstPragmaType::PUBLIC_MODULE); }
@ -1153,7 +1144,7 @@ delayE:
| delay_control { } /* ignored */
;
delay_control<fileline>: //== IEEE: delay_control
delay_control<fl>: //== IEEE: delay_control
'#' delay_value { $$ = $1; } /* ignored */
| '#' '(' minTypMax ')' { $$ = $1; } /* ignored */
| '#' '(' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */
@ -1287,7 +1278,7 @@ etcInst<nodep>: // IEEE: module_instantiation + gate_instantiation + udp_insta
instDecl<nodep>:
id parameter_value_assignmentE {INSTPREP(*$1,$2);} instnameList ';'
{ $$ = $4; V3Parse::s_impliedDecl=false;}
{ $$ = $4; GRAMMARP->m_impliedDecl=false;}
//UNSUP: strengthSpecE for udp_instantiations
;
@ -1297,8 +1288,8 @@ instnameList<nodep>:
;
instnameParen<nodep>:
id instRangeE '(' cellpinList ')' { $$ = new AstCell($3, *$1,V3Parse::s_instModule,$4, V3Parse::s_instParamp,$2); }
| id instRangeE { $$ = new AstCell(CRELINE(),*$1,V3Parse::s_instModule,NULL,V3Parse::s_instParamp,$2); }
id instRangeE '(' cellpinList ')' { $$ = new AstCell($3, *$1,GRAMMARP->m_instModule,$4, GRAMMARP->m_instParamp,$2); }
| id instRangeE { $$ = new AstCell(CRELINE(),*$1,GRAMMARP->m_instModule,NULL,GRAMMARP->m_instParamp,$2); }
//UNSUP instRangeE '(' cellpinList ')' { UNSUP } // UDP
;
@ -1392,14 +1383,13 @@ stmtBlock<nodep>: // IEEE: statement + seq_block + par_block
seq_block<nodep>: // ==IEEE: seq_block
// // IEEE doesn't allow declarations in unnamed blocks, but several simulators do.
// // So need begin's even if unnamed to scope variables down
yBEGIN blockDeclStmtList yEND { $$ = new AstBegin($1,"",$2); }
| yBEGIN /**/ yEND { $$ = NULL; }
| yBEGIN ':' seq_blockId blockDeclStmtList yEND endLabelE { $$ = new AstBegin($2,*$3,$4); }
| yBEGIN ':' seq_blockId /**/ yEND endLabelE { $$ = new AstBegin($2,*$3,NULL); }
seq_blockFront blockDeclStmtList yEND endLabelE { $$=$1; $1->addStmtp($2); }
| seq_blockFront /**/ yEND endLabelE { $$=$1; }
;
seq_blockId<strp>: // IEEE: part of seq_block
idAny/*new-block_identifier*/ { $$ = $1; }
seq_blockFront<beginp>: // IEEE: part of par_block
yBEGIN { $$ = new AstBegin($1,"",NULL); }
| yBEGIN ':' idAny/*new-block_identifier*/ { $$ = new AstBegin($1,*$3,NULL); }
;
blockDeclStmtList<nodep>: // IEEE: { block_item_declaration } { statement or null }
@ -1581,15 +1571,15 @@ unique_priorityE<uniqstate>: // IEEE: unique_priority + empty
;
caseStart<casep>: // IEEE: part of case_statement
yCASE '(' expr ')' { $$ = V3Parse::s_caseAttrp = new AstCase($1,AstCaseType::CASE,$3,NULL); }
| yCASEX '(' expr ')' { $$ = V3Parse::s_caseAttrp = new AstCase($1,AstCaseType::CASEX,$3,NULL); $1->v3warn(CASEX,"Suggest casez (with ?'s) in place of casex (with X's)\n"); }
| yCASEZ '(' expr ')' { $$ = V3Parse::s_caseAttrp = new AstCase($1,AstCaseType::CASEZ,$3,NULL); }
yCASE '(' expr ')' { $$ = GRAMMARP->m_caseAttrp = new AstCase($1,AstCaseType::CASE,$3,NULL); }
| yCASEX '(' expr ')' { $$ = GRAMMARP->m_caseAttrp = new AstCase($1,AstCaseType::CASEX,$3,NULL); $1->v3warn(CASEX,"Suggest casez (with ?'s) in place of casex (with X's)\n"); }
| yCASEZ '(' expr ')' { $$ = GRAMMARP->m_caseAttrp = new AstCase($1,AstCaseType::CASEZ,$3,NULL); }
;
caseAttrE:
/*empty*/ { }
| caseAttrE yVL_FULL_CASE { V3Parse::s_caseAttrp->fullPragma(true); }
| caseAttrE yVL_PARALLEL_CASE { V3Parse::s_caseAttrp->parallelPragma(true); }
| caseAttrE yVL_FULL_CASE { GRAMMARP->m_caseAttrp->fullPragma(true); }
| caseAttrE yVL_PARALLEL_CASE { GRAMMARP->m_caseAttrp->parallelPragma(true); }
;
case_itemListE<caseitemp>: // IEEE: [ { case_item } ]
@ -1682,7 +1672,7 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
| yD_INFO '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::INFO, *$3,NULL,$4); }
| yD_WARNING parenE { $$ = new AstDisplay($1,AstDisplayType::WARNING,"", NULL,NULL); }
| yD_WARNING '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::WARNING,*$3,NULL,$4); }
| yD_ERROR parenE { $$ = V3Parse::createDisplayError($1); }
| yD_ERROR parenE { $$ = GRAMMARP->createDisplayError($1); }
| yD_ERROR '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::ERROR, *$3,NULL,$4); $$->addNext(new AstStop($1)); }
| yD_FATAL parenE { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); }
| yD_FATAL '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); if ($3) $3->deleteTree(); }
@ -1727,14 +1717,18 @@ list_of_argumentsE<nodep>: // IEEE: [list_of_arguments]
//UNSUP empty arguments with just ,,
;
task_declaration<nodep>: // ==IEEE: task_declaration
task_declaration<taskp>: // ==IEEE: task_declaration
yTASK lifetimeE taskId tfGuts yENDTASK endLabelE
{ $$ = new AstTask ($1,*$3,$4);}
{ $$ = $3; $$->addStmtsp($4); }
;
function_declaration<funcp>: // IEEE: function_declaration + function_body_declaration
yFUNCTION lifetimeE funcTypeE tfIdScoped tfGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$5,$3); if ($3) $$->isSigned($3->isSigned()); }
| yFUNCTION lifetimeE funcTypeE tfIdScoped yVL_ISOLATE_ASSIGNMENTS tfGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$6,$3); $$->attrIsolateAssign(true); if ($3) $$->isSigned($3->isSigned()); }
yFUNCTION lifetimeE funcTypeE funcId tfGuts yENDFUNCTION endLabelE
{ $$ = $4; $$->addFvarp($3); $$->addStmtsp($5); if ($3) $$->isSigned($3->isSigned());
}
| yFUNCTION lifetimeE funcTypeE funcId yVL_ISOLATE_ASSIGNMENTS tfGuts yENDFUNCTION endLabelE
{ $$ = $4; $$->addFvarp($3); $$->addStmtsp($6); $$->attrIsolateAssign(true); if ($3) $$->isSigned($3->isSigned());
}
//UNSUP: Generic function return types
;
@ -1749,13 +1743,18 @@ lifetime: // ==IEEE: lifetime
| yAUTOMATIC { }
;
taskId<strp>:
tfIdScoped { $$ = $1; }
taskId<taskp>:
id
{ $$ = new AstTask($<fl>1, *$1, NULL);
}
;
tfIdScoped<strp>: // IEEE: part of function_body_declaration/task_body_declaration
// // IEEE: [ interface_identifier '.' | class_scope ] function_identifier
id { $$ = $1; }
funcId<funcp>: // IEEE: function_data_type_or_implicit + part of function_body_declaration
// // IEEE: function_data_type_or_implicit must be expanded here to prevent conflict
// // function_data_type expanded here to prevent conflicts with implicit_type:empty vs data_type:ID
id
{ $$ = new AstFunc ($<fl>1,*$1,NULL,NULL);
}
//UNSUP id/*interface_identifier*/ '.' id { UNSUP }
//UNSUP class_scope_id { UNSUP }
;
@ -1949,7 +1948,7 @@ expr<nodep>: // IEEE: part of expression/constant_expression/primary
//======================// IEEE: primary/constant_primary
//
// // IEEE: primary_literal (minus string, which is handled specially)
| yaINTNUM { $$ = new AstConst(CRELINE(),*$1); }
| yaINTNUM { $$ = new AstConst($<fl>1,*$1); }
//UNSUP yaFLOATNUM { UNSUP }
//UNSUP yaTIMENUM { UNSUP }
| strAsInt~noStr__IGNORE~ { $$ = $1; }
@ -2288,15 +2287,15 @@ junkToSemi:
// IDs
id<strp>:
yaID__ETC { $$ = $1; }
yaID__ETC { $$ = $1; $<fl>$=$<fl>1; }
;
idAny<strp>: // Any kind of identifier
//UNSUP yaID__aCLASS { $$ = $1; }
//UNSUP yaID__aCOVERGROUP { $$ = $1; }
//UNSUP yaID__aPACKAGE { $$ = $1; }
//UNSUP yaID__aTYPE { $$ = $1; }
yaID__ETC { $$ = $1; }
//UNSUP yaID__aCLASS { $$ = $1; $<fl>$=$<fl>1; }
//UNSUP yaID__aCOVERGROUP { $$ = $1; $<fl>$=$<fl>1; }
//UNSUP yaID__aPACKAGE { $$ = $1; $<fl>$=$<fl>1; }
//UNSUP yaID__aTYPE { $$ = $1; $<fl>$=$<fl>1; }
yaID__ETC { $$ = $1; $<fl>$=$<fl>1; }
;
idSVKwd<strp>: // Warn about non-forward compatible Verilog 2001 code
@ -2370,11 +2369,11 @@ varRefBase<nodep>:
// yaSTRING shouldn't be used directly, instead via an abstraction below
str<strp>: // yaSTRING but with \{escapes} need decoded
yaSTRING { $$ = V3Read::newString(V3Parse::deQuote(CRELINE(),*$1)); }
yaSTRING { $$ = PARSEP->newString(GRAMMARP->deQuote($<fl>1,*$1)); }
;
strAsInt<nodep>:
yaSTRING { $$ = new AstConst(CRELINE(),V3Number(V3Number::VerilogString(),CRELINE(),V3Parse::deQuote(CRELINE(),*$1)));}
yaSTRING { $$ = new AstConst($<fl>1,V3Number(V3Number::VerilogString(),$<fl>1,GRAMMARP->deQuote($<fl>1,*$1)));}
;
strAsIntIgnore<nodep>: // strAsInt, but never matches for when expr shouldn't parse strings
@ -2382,7 +2381,7 @@ strAsIntIgnore<nodep>: // strAsInt, but never matches for when expr shouldn't p
;
strAsText<nodep>:
yaSTRING { $$ = V3Parse::createTextQuoted(CRELINE(),*$1);}
yaSTRING { $$ = GRAMMARP->createTextQuoted($<fl>1,*$1);}
;
endLabelE:
@ -2432,7 +2431,7 @@ property_specDisable<nodep>: // IEEE: part of property_spec
immediate_assert_statement<nodep>: // ==IEEE: immediate_assert_statement
// // action_block expanded here, for compatibility with AstVAssert
yASSERT '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstVAssert($1,$3,$5, V3Parse::createDisplayError($1)); }
yASSERT '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstVAssert($1,$3,$5, GRAMMARP->createDisplayError($1)); }
| yASSERT '(' expr ')' yELSE stmtBlock { $$ = new AstVAssert($1,$3,NULL,$6); }
| yASSERT '(' expr ')' stmtBlock yELSE stmtBlock { $$ = new AstVAssert($1,$3,$5,$7); }
;
@ -2516,12 +2515,30 @@ pslExpr<nodep>:
//**********************************************************************
%%
void V3Read::parserClear() {
// Clear up any dynamic memory V3Parser required
V3Parse::setRange(NULL);
int V3ParseImp::bisonParse() {
if (PARSEP->debugBison()>=9) yydebug = 1;
return yyparse();
}
AstNode* V3Parse::createSupplyExpr(FileLine* fileline, string name, int value) {
const char* V3ParseImp::tokenName(int token) {
#if YYDEBUG || YYERROR_VERBOSE
if (token >= 255)
return yytname[token-255];
else {
static char ch[2]; ch[0]=token; ch[1]='\0';
return ch;
}
#else
return "";
#endif
}
void V3ParseImp::parserClear() {
// Clear up any dynamic memory V3Parser required
GRAMMARP->setRange(NULL);
}
AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, string name, int value) {
FileLine* newfl = new FileLine (fileline);
newfl->warnOff(V3ErrorCode::WIDTH, true);
AstNode* nodep = new AstConst(newfl, V3Number(fileline));
@ -2532,12 +2549,12 @@ AstNode* V3Parse::createSupplyExpr(FileLine* fileline, string name, int value) {
return nodep;
}
AstVar* V3Parse::createVariable(FileLine* fileline, string name, AstRange* arrayp, AstNode* attrsp) {
AstVarType type = V3Parse::s_varIO;
AstRange* rangep = V3Parse::s_varRangep;
AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange* arrayp, AstNode* attrsp) {
AstVarType type = GRAMMARP->m_varIO;
AstRange* rangep = GRAMMARP->m_varRangep;
AstRange* cleanup_rangep = NULL;
//UINFO(0,"CREVAR "<<fileline->ascii()<<" decl="<<V3Parse::s_varDecl.ascii()<<" io="<<V3Parse::s_varIO.ascii()<<endl);
if (type == AstVarType::UNKNOWN || type == AstVarType::PORT) type = V3Parse::s_varDecl;
//UINFO(0,"CREVAR "<<fileline->ascii()<<" decl="<<GRAMMARP->m_varDecl.ascii()<<" io="<<GRAMMARP->m_varIO.ascii()<<endl);
if (type == AstVarType::UNKNOWN || type == AstVarType::PORT) type = GRAMMARP->m_varDecl;
if (type == AstVarType::PORT) {
// Just wanted port decl; we've already made it.
if (rangep) fileline->v3error("Unsupported: Ranges ignored in port-lists");
@ -2545,12 +2562,12 @@ AstVar* V3Parse::createVariable(FileLine* fileline, string name, AstRange* array
}
if (type == AstVarType::UNKNOWN) fileline->v3fatalSrc("Unknown signal type declared");
// Linting, because we allow parsing of a superset of the language
if (type == AstVarType::INTEGER || V3Parse::s_varDecl == AstVarType::INTEGER
if (type == AstVarType::INTEGER || GRAMMARP->m_varDecl == AstVarType::INTEGER
|| type == AstVarType::GENVAR) {
if (rangep) {
if (rangep->msbConst()==31 && rangep->lsbConst()==0) {
// For backward compatibility with functions some INTEGERS are internally made as [31:0]
rangep->deleteTree(); rangep=NULL; V3Parse::s_varRangep=NULL;
rangep->deleteTree(); rangep=NULL; GRAMMARP->m_varRangep=NULL;
} else {
fileline->v3error("Integers may not be ranged: "<<name);
}
@ -2565,19 +2582,19 @@ AstVar* V3Parse::createVariable(FileLine* fileline, string name, AstRange* array
rangep->cloneTree(false),
arrayp);
nodep->addAttrsp(attrsp);
nodep->isSigned(V3Parse::s_varSigned);
if (type == AstVarType::INTEGER || V3Parse::s_varDecl == AstVarType::INTEGER
nodep->isSigned(GRAMMARP->m_varSigned);
if (type == AstVarType::INTEGER || GRAMMARP->m_varDecl == AstVarType::INTEGER
|| type == AstVarType::GENVAR) {
nodep->isSigned(true);
}
if (V3Parse::s_varDecl != AstVarType::UNKNOWN) nodep->combineType(V3Parse::s_varDecl);
if (V3Parse::s_varIO != AstVarType::UNKNOWN) nodep->combineType(V3Parse::s_varIO);
if (GRAMMARP->m_varDecl != AstVarType::UNKNOWN) nodep->combineType(GRAMMARP->m_varDecl);
if (GRAMMARP->m_varIO != AstVarType::UNKNOWN) nodep->combineType(GRAMMARP->m_varIO);
if (V3Parse::s_varDecl == AstVarType::SUPPLY0) {
nodep->addNext(V3Parse::createSupplyExpr(fileline, nodep->name(), 0));
if (GRAMMARP->m_varDecl == AstVarType::SUPPLY0) {
nodep->addNext(V3ParseGrammar::createSupplyExpr(fileline, nodep->name(), 0));
}
if (V3Parse::s_varDecl == AstVarType::SUPPLY1) {
nodep->addNext(V3Parse::createSupplyExpr(fileline, nodep->name(), 1));
if (GRAMMARP->m_varDecl == AstVarType::SUPPLY1) {
nodep->addNext(V3ParseGrammar::createSupplyExpr(fileline, nodep->name(), 1));
}
// Clear any widths that got presumed by the ranging;
// We need to autosize parameters and integers separately
@ -2587,12 +2604,12 @@ AstVar* V3Parse::createVariable(FileLine* fileline, string name, AstRange* array
else nodep->trace(v3Global.opt.trace() && nodep->fileline()->tracingOn());
// Remember the last variable created, so we can attach attributes to it in later parsing
V3Parse::s_varAttrp = nodep;
GRAMMARP->m_varAttrp = nodep;
if (cleanup_rangep) { cleanup_rangep->deleteTree(); cleanup_rangep=NULL; }
return nodep;
}
string V3Parse::deQuote(FileLine* fileline, string text) {
string V3ParseGrammar::deQuote(FileLine* fileline, string text) {
// Fix up the quoted strings the user put in, for example "\"" becomes "
// Reverse is AstNode::quoteName(...)
bool quoted = false;
@ -2647,11 +2664,6 @@ string V3Parse::deQuote(FileLine* fileline, string text) {
return newtext;
}
AstText* V3Parse::createTextQuoted(FileLine* fileline, string text) {
string newtext = deQuote(fileline, text);
return new AstText(fileline, newtext);
}
//YACC = /kits/sources/bison-2.4.1/src/bison --report=lookahead
// --report=lookahead
// --report=itemset