Skip to content

Commit

Permalink
Enable lexer to optionally help the grammar infer missing types.
Browse files Browse the repository at this point in the history
  • Loading branch information
berendo committed Dec 30, 2019
1 parent 4a8094f commit 1896d85
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 22 deletions.
1 change: 1 addition & 0 deletions Netlist/File.pm
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ sub read {
use_cb_operator => 0,
use_cb_string => 0,
use_cb_symbol => 0,
infer_missing_types => $params{infer_missing_types},
);
return $fileref;
}
Expand Down
2 changes: 2 additions & 0 deletions Parser/Parser.pm
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ sub new {
use_protected => 1, # Backward compatibility
use_pinselects => 0, # Backward compatibility
use_std => undef, # Undef = silent
infer_missing_types => 0,
#use_cb_{callback-name} => 0/1
#
#_debug # Don't set, use debug() accessor to change level
Expand All @@ -74,6 +75,7 @@ sub new {
$self->{use_unreadback},
$self->{use_protected},
$self->{use_pinselects}, # Undocumented as for use in SigParser only
$self->{infer_missing_types},
);

$self->{use_cb_contassign} = $self->{use_vars} if !exists $self->{use_cb_contassign};
Expand Down
8 changes: 4 additions & 4 deletions Parser/Parser.xs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ public:
void cbFileline(VFileLine* filelinep) { m_cbFilelinep = filelinep; }

VParserXs(VFileLine* filelinep, av* symsp,
bool sigparser, bool useUnreadback, bool useProtected, bool usePinselects)
: VParse(filelinep, symsp, sigparser, useUnreadback, useProtected, usePinselects)
bool sigparser, bool useUnreadback, bool useProtected, bool usePinselects, bool inferMissingTypes)
: VParse(filelinep, symsp, sigparser, useUnreadback, useProtected, usePinselects, inferMissingTypes)
, m_cbFilelinep(filelinep)
{ set_cb_use(); }
virtual ~VParserXs();
Expand Down Expand Up @@ -344,14 +344,14 @@ MODULE = Verilog::Parser PACKAGE = Verilog::Parser
#// self->_new (class, sigparser)

static VParserXs *
VParserXs::_new(SV* SELF, AV* symsp, bool sigparser, bool useUnreadback, bool useProtected, bool usePinselects)
VParserXs::_new(SV* SELF, AV* symsp, bool sigparser, bool useUnreadback, bool useProtected, bool usePinselects, bool inferMissingTypes)
PROTOTYPE: $$$$
CODE:
{
if (CLASS) {} /* Prevent unused warning */
if (!SvROK(SELF)) { warn("${Package}::$func_name() -- SELF is not a hash reference"); }
VFileLineParseXs* filelinep = new VFileLineParseXs(NULL/*ok,for initial*/);
VParserXs* parserp = new VParserXs(filelinep, symsp, sigparser, useUnreadback, useProtected, usePinselects);
VParserXs* parserp = new VParserXs(filelinep, symsp, sigparser, useUnreadback, useProtected, usePinselects, inferMissingTypes);
filelinep->setParser(parserp);
parserp->m_self = SvRV(SELF);
RETVAL = parserp;
Expand Down
3 changes: 2 additions & 1 deletion Parser/VParse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,15 @@ VParseGrammar* VParseGrammar::s_grammarp = NULL;
//*************************************************************************

VParse::VParse(VFileLine* filelinep, av* symsp,
bool sigParser, bool useUnreadbackFlag, bool useProtected, bool usePinselects)
bool sigParser, bool useUnreadbackFlag, bool useProtected, bool usePinselects, bool inferMissingTypes)
: m_syms(filelinep, symsp)
{
m_inFilelinep = filelinep;
m_sigParser = sigParser;
m_useUnreadback = useUnreadbackFlag;
m_useProtected = useProtected;
m_usePinselects = usePinselects;
m_inferMissingTypes = inferMissingTypes;
m_debug = 0;
m_lexp = new VParseLex(this);
m_grammarp = new VParseGrammar(this);
Expand Down
4 changes: 3 additions & 1 deletion Parser/VParse.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class VParse {
bool m_useUnreadback;///< Need m_unreadback tracking
bool m_useProtected; ///< Need `protected tracking
bool m_usePinselects;///< Need bit-select parsing
bool m_inferMissingTypes;
string m_unreadback; ///< Otherwise unprocessed whitespace before current token
deque<string> m_buffers; ///< Buffer of characters to process

Expand Down Expand Up @@ -123,7 +124,7 @@ class VParse {
public:
// CONSTRUCTORS
VParse(VFileLine* filelinep, av* symsp,
bool sigParser, bool useUnreadbackFlag, bool useProtected, bool usePinselects);
bool sigParser, bool useUnreadbackFlag, bool useProtected, bool usePinselects, bool inferMissingTypes);
virtual ~VParse();

// ACCESSORS
Expand All @@ -138,6 +139,7 @@ class VParse {
bool callbackMasterEna() const { return m_callbackMasterEna; }
bool useProtected() const { return m_useProtected; }
bool usePinSelects() const { return m_usePinselects; }
bool inferMissingTypes() const { return m_inferMissingTypes; }

VFileLine* inFilelinep() const; ///< File/Line number for last callback
void inFileline(const string& filename, int lineno) { m_inFilelinep = m_inFilelinep->create(filename, lineno); }
Expand Down
9 changes: 5 additions & 4 deletions Parser/VParseLex.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,10 @@ class VParseLex {
bool m_inCellDefine; ///< In a `celldefine

int m_prevLexToken; ///< previous parsed token (for lexer)
bool m_ahead; ///< aheadToken is valid
int m_aheadToken; ///< Token we read ahead
VParseBisonYYSType m_aheadVal; ///< aheadToken's value
static const int k_aheadLimit = 100;
int m_aheadCount; ///< aheadToken is valid
int m_aheadToken[k_aheadLimit]; ///< Token we read ahead
VParseBisonYYSType m_aheadVal[k_aheadLimit]; ///< aheadToken's value

int m_pvstate; ///< "pure virtual" detection

Expand All @@ -96,7 +97,7 @@ class VParseLex {
m_parsep = parsep;
m_inCellDefine = false;
m_prevLexToken = 0;
m_ahead = false;
m_aheadCount = 0;
m_pvstate = 0;

m_yyState = yy_create_buffer(NULL, YY_BUF_SIZE);
Expand Down
84 changes: 73 additions & 11 deletions Parser/VParseLex.l
Original file line number Diff line number Diff line change
Expand Up @@ -727,17 +727,25 @@ int VParseLex::lexToken(VParseBisonYYSType* yylvalp) {
// Fetch next token from prefetch or real lexer
s_currentLexp = this;
int token;
if (m_ahead) {
int prevtok = LEXP->prevLexToken();
if (m_aheadCount) {
// We prefetched an extra token, give it back
m_ahead = false;
token = m_aheadToken;
*yylvalp = m_aheadVal;
m_aheadCount--;
token = m_aheadToken[0];
*yylvalp = m_aheadVal[0];
for (int i=0; i<m_aheadCount; i++) {
m_aheadToken[i] = m_aheadToken[i+1];
m_aheadVal[i] = m_aheadVal[i+1];
}
m_prevLexToken = token;
} else {
// Parse new token
s_yylvalp = yylvalp; // Read by yylex()
token = yylexReadTok();
}

// If a paren, read another
VParseBisonYYSType curValue = *s_yylvalp; // Remember value, as about to read ahead
if (token == '('
|| token == yCONST__LEX
|| token == yGLOBAL__LEX
Expand All @@ -751,12 +759,17 @@ int VParseLex::lexToken(VParseBisonYYSType* yylvalp) {
#ifdef FLEX_DEBUG
if (yy_flex_debug) { cout<<" lexToken: reading ahead to find possible strength"<<endl; }
#endif
VParseBisonYYSType curValue = *s_yylvalp; // Remember value, as about to read ahead
int nexttok = yylexReadTok();
m_ahead = true;
m_aheadToken = nexttok;
m_aheadVal = *s_yylvalp;
*s_yylvalp = curValue;
int nexttok;
if (!m_aheadCount) {
nexttok = yylex();
m_aheadCount = 1;
m_aheadToken[0] = nexttok;
m_aheadVal[0] = *s_yylvalp;
*s_yylvalp = curValue;
}
else {
nexttok = m_aheadToken[0];
}
// Now potentially munge the current token
if (token == '(' && (nexttok == ygenSTRENGTH
|| nexttok == ySUPPLY0
Expand Down Expand Up @@ -849,7 +862,56 @@ int VParseLex::lexToken(VParseBisonYYSType* yylvalp) {
case VAstType::TYPE: token = yaID__aTYPE; break;
default: token = yaID__ETC; break;
}
} else { // Not found
}
else if (LPARSEP->inferMissingTypes()) {
while (m_aheadCount < 2) {
m_aheadToken[m_aheadCount] = yylex();
m_aheadVal[m_aheadCount] = *s_yylvalp;
m_aheadCount++;
*s_yylvalp = curValue;
}

if (m_aheadToken[0] == yP_COLONCOLON) {
LPARSEP->symPushNew(VAstType::PACKAGE, s_yylvalp->str);
LPARSEP->symPopScope(VAstType::PACKAGE);
token = yaID__aPACKAGE;
}
else if ((m_aheadToken[0] == yaID__LEX && m_aheadToken[1] != '(') || m_aheadToken[0] == '[') {
if (prevtok == '('
|| prevtok == ','
|| prevtok == ';'
|| prevtok == '{'
|| prevtok == yBEGIN
|| prevtok == yEND
|| prevtok == yINOUT
|| prevtok == yINPUT
|| prevtok == yOUTPUT
|| prevtok == yWIRE
|| prevtok == yP_COLONCOLON) {
if (m_aheadToken[0] == '[') {
for (int i=1; i<k_aheadLimit-1; i++) {
if ((i+1) >= m_aheadCount) {
m_aheadToken[m_aheadCount] = yylex();
m_aheadVal[m_aheadCount] = *s_yylvalp;
m_aheadCount++;
*s_yylvalp = curValue;
}

if (m_aheadToken[i] == ']') {
if (m_aheadToken[i+1] == yaID__LEX) {
token = yaID__aTYPE;
}
break;
}
}
} else {
token = yaID__aTYPE;
}
}
}
}

if (token == yaID__LEX) {
token = yaID__ETC;
}
}
Expand Down
4 changes: 3 additions & 1 deletion vhier
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ my $Opt_ModFiles;
my $Opt_InFiles;
my $Opt_Missing = 1;
my $Opt_Missing_Modules;
my $Opt_InferMissingTypes;
my $Opt_TopModule;
my $Opt_ResolveFiles;
my $Opt_Synthesis;
Expand Down Expand Up @@ -65,6 +66,7 @@ if (! GetOptions (
"language=s" => sub { shift; Verilog::Language::language_standard(shift); },
"missing!" => \$Opt_Missing,
"missing-modules!" => \$Opt_Missing_Modules,
"infer-missing-types!"=> \$Opt_InferMissingTypes,
"synthesis!" => \$Opt_Synthesis,
"top-module=s" => \$Opt_TopModule,
"version" => sub { print "Version $VERSION\n"; exit(0); },
Expand Down Expand Up @@ -144,7 +146,7 @@ sub vhier {
}
foreach my $file (@files) {
print " Reading $file\n" if $Debug;
$nl->read_file(filename=>$file);
$nl->read_file(filename=>$file, infer_missing_types=>$Opt_InferMissingTypes);
}
# Read in any sub-modules
$nl->link();
Expand Down

0 comments on commit 1896d85

Please sign in to comment.