Update bisonpre to match Verilog-Perl version

This commit is contained in:
Wilson Snyder 2009-05-04 21:54:44 -04:00
parent 7df730cedd
commit 0985f675e3
6 changed files with 175 additions and 62 deletions

View File

@ -88,7 +88,6 @@ clean mostlyclean distclean maintainer-clean::
-rm -rf obj_* *.log *.dmp *.vpd core
-rm -f *.o *.d perlxsi.c *_gen_*
-rm -f *__gen*
-rm -f *.yy.* y.output y.tab.[cho] *_test
-rm -f .objcache*
distclean maintainer-clean::

View File

@ -118,7 +118,6 @@ make_info:
clean mostlyclean distclean maintainer-clean::
-rm -f *.o *.d perlxsi.c *_gen_*
-rm -f *__gen*
-rm -f *.yy.* y.output y.tab.[cho] *_test
-rm -f obj_* .objcache*
distclean maintainer-clean:: clean
@ -245,10 +244,10 @@ V3Number_test: V3Number_test.o
%.o: %.c
$(OBJCACHE) ${CC} ${CPPFLAGS} -c $<
V3Read.o: V3Read.cpp V3Lexer.yy.cpp
V3Read.o: V3Read.cpp V3Lexer.yy.cpp V3ParseBison.c
$(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
V3Parse.o: V3Parse.cpp y.tab.c
V3Parse.o: V3Parse.cpp V3ParseBison.c
$(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp
@ -257,19 +256,19 @@ V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp
#### Generated files
# Target rule called before parallel build to make generated files
serial:: V3Ast__gen_classes.h y.tab.c
serial:: V3Ast__gen_classes.h V3ParseBison.c
V3Ast__gen_classes.h : $(ASTGEN) V3Ast.h V3AstNodes.h
$(PERL) $(ASTGEN) -I$(srcdir) --classes
y.tab.h: y.tab.c
V3ParseBison.h: V3ParseBison.c
# Have only one output file in this rule to prevent parallel make issues
y.tab.c: verilog.y $(HEADERS) bisonpre
V3ParseBison.c: verilog.y $(HEADERS) bisonpre
@echo "If you get errors from verilog.y below, try upgrading bison to version 1.875 or newer."
$(PERL) $(BISONPRE) --yacc ${YACC} -d -v -o y.tab.c $<
$(PERL) $(BISONPRE) --yacc ${YACC} -d -v -o V3ParseBison.c $<
V3Lexer_pregen.yy.cpp: verilog.l y.tab.h $(HEADERS)
V3Lexer_pregen.yy.cpp: verilog.l V3ParseBison.h $(HEADERS)
${LEX} --version
${LEX} ${LFLAGS} -o$@ $<

View File

@ -19,8 +19,8 @@
//
//*************************************************************************
#include "V3Ast.h" // This must be before yy.tab.c, as we don't want #defines to conflict
#include "V3Ast.h" // This must be before V3ParseBison.cpp, as we don't want #defines to conflict
//======================================================================
// The guts are in bison
#include "y.tab.c"
// The guts came from bison
#include "V3ParseBison.c"

View File

@ -9,7 +9,9 @@ use Pod::Usage;
use strict;
use vars qw ($Debug $VERSION);
$VERSION = '3.101';
$VERSION = '3.202';
our $Self;
#======================================================================
# main
@ -74,13 +76,17 @@ sub process {
clean_input($Opt_Input, tmp_prefix().".y");
my $supports_report = (bison_version_check() >= 2.3);
# Run bison
my $command = ($Opt_Yacc
.($Opt_Debug?" -t":"")
.($Opt_Definitions?" -d":"")
.($Opt_Token_Table?" -k":"")
.($Opt_Name_Prefix?" -p $Opt_Name_Prefix":"")
.($Opt_Verbose?" -v":"")
.(($Opt_Verbose && $supports_report)?" --report=itemset --report=lookahead":"")
# -p required for GLR parsers; they write to -p basename, not -o
.($Opt_Name_Prefix?" -p $Opt_Name_Prefix":"")
." -b ".tmp_prefix()
." -o ".tmp_prefix().".c"
." ".tmp_prefix().".y" );
@ -94,16 +100,16 @@ sub process {
die "bisonpre: %Error: $Opt_Yacc version $v run failed due to errors\n";
}
clean_output(tmp_prefix().".output",output_prefix().".output");
clean_output(tmp_prefix().".output",output_prefix().".output", 1);
warning_check(output_prefix().".output");
clean_output(tmp_prefix().".c", output_prefix().".c");
clean_output(tmp_prefix().".h", output_prefix().".h");
clean_output(tmp_prefix().".c", output_prefix().".c", 0);
clean_output(tmp_prefix().".h", output_prefix().".h", 0);
remove_tmp();
}
sub tmp_prefix {
return output_prefix().".pre";
return output_prefix()."_pretmp";
}
sub output_prefix {
@ -143,22 +149,44 @@ sub bison_version_check {
sub clean_output {
my $filename = shift;
my $outname = shift || $filename;
my $is_output = shift;
print " edit $filename $outname\n";
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
my @lines = $fh->getlines;
$fh->close;
(my $basename = tmp_prefix().".y") =~ s!.*/!!;
(my $basename = tmp_prefix()) =~ s!.*/!!;
$basename = quotemeta($basename);
(my $newbase = output_prefix().".y") =~ s!.*/!!;
(my $newbase = output_prefix()) =~ s!.*/!!;
if ($is_output) {
my %state_line; my $l=0;
foreach my $line (@lines) {
$l++;
$state_line{$1} = $l if $line =~ /^state (\d+)\s*$/;
}
my @out;
foreach my $line (@lines) {
$state_line{$1} = $l if $line =~ /^state (\d+)\s*$/;
if ($line =~ /^State (\d+) (conflicts)/) {
chomp $line;
$line .= " // line $state_line{$1}" if $state_line{$1};
$line .= "\n";
}
push @out, $line;
}
@lines = @out; @out = ();
}
$fh = IO::File->new(">$outname") or die "%Error: $! writing $outname\n";
foreach my $line (@lines) {
# Fix bison 2.3 and GCC 4.2.1
$line =~ s!\(YY_\("!(YY_((char*)"!g;
# Fix filename refs
$line =~ s!$basename!$newbase!g;
# Fix bison 2.3 and GCC 4.2.1
$line =~ s!\(YY_\("!(YY_((char*)"!g;
# Fix bison 2.3 glr-parser warning about yyerrorloc.YYTYPE::yydummy uninit
$line =~ s!(YYLTYPE yyerrloc;)!$1 yyerrloc.yydummy=0;/*bisonpre*/!g;
$fh->write($line);
}
$fh->close;
@ -169,8 +197,7 @@ sub warning_check {
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
while (defined(my $line = $fh->getline)) {
if ($line =~ /(conflicts|warning:)/) {
clean_output();
if ($line =~ /(conflicts|warning:|^useless)/i) {
die "%Error: $filename:$.: $line\n";
}
}
@ -189,17 +216,67 @@ sub clean_input {
$fh->close;
# Find "%tokens<type>:"
# Find "rule<type>:" and replace with just "rule:"
my %types;
my %rules; $Self->{rules} = \%rules;
my %tokens;
foreach my $line (@lines) {
if ($line =~ /^%token\s*<(\S+)>\s*(\S+)/) {
my $last_rule;
my $section = 1;
{
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
$l++;
# ^/ to prevent comments from matching
$line =~ m!^[a-zA-Z0-9_<>]+:[^/]*[a-zA-Z]! and die "%Error: $filename:$l: Move text on rule line to next line: $line\n";
if ($line =~ /^%%/) {
$section++;
if ($section==2) { $last_rule = undef; }
}
elsif ($line =~ s/^([a-zA-Z0-9_]+)<(\S+)>:/$1:/) {
!$rules{$1}{name} or die "%Error: $filename:$l: Redeclaring '$1': $line\n";
$types{$2}{$1} = 1;
$rules{$1}{name} = $1;
$rules{$1}{type} = $2;
!$last_rule or die "%Error: $filename:$l: Unterminated previous rule\n";
$last_rule = $1;
} elsif ($line =~ /^([a-zA-Z0-9_]+):/) {
!$rules{$1}{name} or die "%Error: $filename:$l: Redeclaring '$1': $line\n";
$rules{$1}{name} = $1;
$rules{$1}{type} = "";
!$last_rule or die "%Error: $filename:$l: Unterminated previous rule\n";
$last_rule = $1;
}
push @lines, $line;
# Now clean the line and extract some more info
(my $cline = $line) =~ s/\/\/.*$/\n/;
(my $rline = $line) =~ s/\/\/.*$/\n/;
if ($cline =~ /^\s*;/) {
$last_rule or die "%Error: $filename:$l: Stray semicolon\n";
$last_rule = undef;
} elsif ($last_rule) {
$rules{$last_rule}{rules_and_productions} .= $cline;
}
if ($cline =~ /^%token\s*<(\S+)>\s*(\S+)/) {
!$tokens{$2} or die "%Error: $filename:$l: Redeclaring '$2': $line\n";
$tokens{$2} = $1;
}
foreach my $tok (split /[^a-zA-Z0-9_]+/, $cline) {
if ($last_rule && $tok=~/^[a-zA-Z]/) {
#print "TT $last_rule $tok\n";
$rules{$last_rule}{subrules}{$tok} = 1;
$rules{$tok}{parentrules}{$last_rule} = 1;
}
}
}
}
#use Data::Dumper; print Dumper(\%rules);
# Replace BISONPRE_NOT(type,...) with expanded list
{
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
$l++;
if ($line =~ /BISONPRE_NOT/) {
($line =~ s/BISONPRE_NOT\((\S+)\)\s*({[^}]+})\s*$//)
or die "%Error: $filename:$l: Bad form of BISONPRE_NOT: $line\n";
@ -225,19 +302,40 @@ sub clean_input {
}
}
# Find "rule<type>:" and replace with just "rule:"
my %types;
# Replace BISONPRE_COPY(type,{code})
{
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
# ^/ to prevent comments from matching
if ($line =~ s/^([^<\/ \t\n]+)<(\S+)>:/$1:/) {
$types{$2}{$1} = 1;
$l++;
if ($line =~ /BISONPRE_COPY/) {
($line =~ s/BISONPRE_COPY\((\S+)\s*,\s*{([^}]*)}\s*\)/{HERE}/)
or die "%Error: $filename:$l: Bad form of BISONPRE_NOT: $line\n";
my $rule = $1; my $code = $2;
$rules{$rule} or die "%Error: $filename:$l: Can't find definition for rule: $rule\n";
# Push it all onto one line to avoid error messages changing
my $insert = $rules{$rule}{rules_and_productions};
$insert =~ s/^\S+://g; # Strip rule name
#print "COPY code $code\n";
#print "COPY in $insert\n";
$_=$insert; eval("$code; \$_;"); $insert = $_;
#print "COPY out $insert\n";
while ($insert =~ s/[ \t\n]+\n/\n/go) {}
$line =~ s/{HERE}/$insert/;
}
push @lines, $line;
}
}
# Replace ~[x]~ - must be after BISONPRE_COPY expansion
{
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
$l++;
$line =~ s/~[a-zA-Z0-9_]+~//g;
push @lines, $line;
}
}
# Find "BISONPRE_TYPES"
{
my @linesin = @lines; @lines=(); my $l=0;
@ -273,7 +371,6 @@ sub clean_input {
$fh->close;
}
#######################################################################
__END__
@ -303,11 +400,21 @@ various compile warnings.
This is expanded into %type declarations.
=item ~[a-z]+~
Any text matching ~[a-z]+~ is removed. This allows optional text to be
used only when the rule containing the ~~ is used in a BISONPRE_COPY.
=item rule_label<type>:
This allows the label declaring a rule to also specify the type of the
rule. The type will be inserted where /*BISONPRE_TYPES*/ is encountered.
=item BISONPRE_COPY(rule, {code})
Copy the rules and productions from the specified rule, filter through the
Perl code provided in the {} and insert here into the output file.
=item BISONPRE_NOT(token[, token...])
Create a rule that matches every token except for those specified.
@ -351,16 +458,6 @@ This switch causes the name.tab.c output to include a list of token names
in order by their token numbers; this is defined in the array yytname.
Also generated are #defines for YYNTOKENS, YYNNTS, YYNRULES, and YYNSTATES.
=item -p prefix
=item --name-prefix=prefix
Passed to bison.
Rename the external symbols used in the parser so that they start with
prefix instead of yy. The precise list of symbols renamed is yyparse,
yylex, yyerror, yylval, yychar, and yydebug. For example, if you use -p c,
the names become cparse, clex, and so on.
==item -t
==item --debug

View File

@ -27,7 +27,7 @@
#include <cstdlib>
#include "V3Read.h"
#include "V3Number.h"
#include "y.tab.h"
#include "V3ParseBison.h" // Generated by bison
extern void yyerror(char*);
extern void yyerrorf(const char* format, ...);

View File

@ -593,13 +593,17 @@ net_type: // ==IEEE: net_type
| yWIRE { VARDECL(WIRE); }
| yTRI { VARDECL(TRIWIRE); }
;
varGParam: yPARAMETER { VARDECL(GPARAM); }
varGParam:
yPARAMETER { VARDECL(GPARAM); }
;
varLParam: yLOCALPARAM { VARDECL(LPARAM); }
varLParam:
yLOCALPARAM { VARDECL(LPARAM); }
;
varGenVar: yGENVAR { VARDECL(GENVAR); }
varGenVar:
yGENVAR { VARDECL(GENVAR); }
;
varReg: yREG { VARDECL(REG); }
varReg:
yREG { VARDECL(REG); }
| yINTEGER { VARDECL(INTEGER); }
;
@ -1390,33 +1394,47 @@ gatePulldownList<nodep>:
| gatePulldownList ',' gatePulldown { $$ = $1->addNext($3); }
;
gateBuf<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' expr ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
gateBuf<assignwp>:
gateIdE instRangeE '(' varRefDotBit ',' expr ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
;
gateBufif0<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, new AstConst($3,V3Number($3,"1'bz")), $6)); }
gateBufif0<assignwp>:
gateIdE instRangeE '(' varRefDotBit ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, new AstConst($3,V3Number($3,"1'bz")), $6)); }
;
gateBufif1<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, $6, new AstConst($3,V3Number($3,"1'bz")))); }
gateBufif1<assignwp>:
gateIdE instRangeE '(' varRefDotBit ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, $6, new AstConst($3,V3Number($3,"1'bz")))); }
;
gateNot<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
gateNot<assignwp>:
gateIdE instRangeE '(' varRefDotBit ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
;
gateNotif0<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, new AstConst($3,V3Number($3,"1'bz")), new AstNot($3, $6))); }
gateNotif0<assignwp>:
gateIdE instRangeE '(' varRefDotBit ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, new AstConst($3,V3Number($3,"1'bz")), new AstNot($3, $6))); }
;
gateNotif1<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, new AstNot($3,$6), new AstConst($3,V3Number($3,"1'bz")))); }
gateNotif1<assignwp>:
gateIdE instRangeE '(' varRefDotBit ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, new AstNot($3,$6), new AstConst($3,V3Number($3,"1'bz")))); }
;
gateAnd<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
gateAnd<assignwp>:
gateIdE instRangeE '(' varRefDotBit ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
;
gateNand<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
gateNand<assignwp>:
gateIdE instRangeE '(' varRefDotBit ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
;
gateOr<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
gateOr<assignwp>:
gateIdE instRangeE '(' varRefDotBit ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
;
gateNor<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
gateNor<assignwp>:
gateIdE instRangeE '(' varRefDotBit ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
;
gateXor<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
gateXor<assignwp>:
gateIdE instRangeE '(' varRefDotBit ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); }
;
gateXnor<assignwp>: gateIdE instRangeE '(' varRefDotBit ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
gateXnor<assignwp>:
gateIdE instRangeE '(' varRefDotBit ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); }
;
gatePullup<pullp>: gateIdE instRangeE '(' varRefDotBit ')' { $$ = new AstPull ($3, $4, true); }
gatePullup<pullp>:
gateIdE instRangeE '(' varRefDotBit ')' { $$ = new AstPull ($3, $4, true); }
;
gatePulldown<pullp>: gateIdE instRangeE '(' varRefDotBit ')' { $$ = new AstPull ($3, $4, false); }
gatePulldown<pullp>:
gateIdE instRangeE '(' varRefDotBit ')' { $$ = new AstPull ($3, $4, false); }
;
gateIdE:
/*empty*/ {}