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 -rf obj_* *.log *.dmp *.vpd core
-rm -f *.o *.d perlxsi.c *_gen_* -rm -f *.o *.d perlxsi.c *_gen_*
-rm -f *__gen* -rm -f *__gen*
-rm -f *.yy.* y.output y.tab.[cho] *_test
-rm -f .objcache* -rm -f .objcache*
distclean maintainer-clean:: distclean maintainer-clean::

View File

@ -118,7 +118,6 @@ make_info:
clean mostlyclean distclean maintainer-clean:: clean mostlyclean distclean maintainer-clean::
-rm -f *.o *.d perlxsi.c *_gen_* -rm -f *.o *.d perlxsi.c *_gen_*
-rm -f *__gen* -rm -f *__gen*
-rm -f *.yy.* y.output y.tab.[cho] *_test
-rm -f obj_* .objcache* -rm -f obj_* .objcache*
distclean maintainer-clean:: clean distclean maintainer-clean:: clean
@ -245,10 +244,10 @@ V3Number_test: V3Number_test.o
%.o: %.c %.o: %.c
$(OBJCACHE) ${CC} ${CPPFLAGS} -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 $< $(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
V3Parse.o: V3Parse.cpp y.tab.c V3Parse.o: V3Parse.cpp V3ParseBison.c
$(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $< $(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp
@ -257,19 +256,19 @@ V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp
#### Generated files #### Generated files
# Target rule called before parallel build to make 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 V3Ast__gen_classes.h : $(ASTGEN) V3Ast.h V3AstNodes.h
$(PERL) $(ASTGEN) -I$(srcdir) --classes $(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 # 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." @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} --version
${LEX} ${LFLAGS} -o$@ $< ${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 // The guts came from bison
#include "y.tab.c" #include "V3ParseBison.c"

View File

@ -9,7 +9,9 @@ use Pod::Usage;
use strict; use strict;
use vars qw ($Debug $VERSION); use vars qw ($Debug $VERSION);
$VERSION = '3.101'; $VERSION = '3.202';
our $Self;
#====================================================================== #======================================================================
# main # main
@ -74,13 +76,17 @@ sub process {
clean_input($Opt_Input, tmp_prefix().".y"); clean_input($Opt_Input, tmp_prefix().".y");
my $supports_report = (bison_version_check() >= 2.3);
# Run bison # Run bison
my $command = ($Opt_Yacc my $command = ($Opt_Yacc
.($Opt_Debug?" -t":"") .($Opt_Debug?" -t":"")
.($Opt_Definitions?" -d":"") .($Opt_Definitions?" -d":"")
.($Opt_Token_Table?" -k":"") .($Opt_Token_Table?" -k":"")
.($Opt_Name_Prefix?" -p $Opt_Name_Prefix":"")
.($Opt_Verbose?" -v":"") .($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() ." -b ".tmp_prefix()
." -o ".tmp_prefix().".c" ." -o ".tmp_prefix().".c"
." ".tmp_prefix().".y" ); ." ".tmp_prefix().".y" );
@ -94,16 +100,16 @@ sub process {
die "bisonpre: %Error: $Opt_Yacc version $v run failed due to errors\n"; 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"); warning_check(output_prefix().".output");
clean_output(tmp_prefix().".c", output_prefix().".c"); clean_output(tmp_prefix().".c", output_prefix().".c", 0);
clean_output(tmp_prefix().".h", output_prefix().".h"); clean_output(tmp_prefix().".h", output_prefix().".h", 0);
remove_tmp(); remove_tmp();
} }
sub tmp_prefix { sub tmp_prefix {
return output_prefix().".pre"; return output_prefix()."_pretmp";
} }
sub output_prefix { sub output_prefix {
@ -143,22 +149,44 @@ sub bison_version_check {
sub clean_output { sub clean_output {
my $filename = shift; my $filename = shift;
my $outname = shift || $filename; my $outname = shift || $filename;
my $is_output = shift;
print " edit $filename $outname\n"; print " edit $filename $outname\n";
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n"; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
my @lines = $fh->getlines; my @lines = $fh->getlines;
$fh->close; $fh->close;
(my $basename = tmp_prefix().".y") =~ s!.*/!!; (my $basename = tmp_prefix()) =~ s!.*/!!;
$basename = quotemeta($basename); $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"; $fh = IO::File->new(">$outname") or die "%Error: $! writing $outname\n";
foreach my $line (@lines) { foreach my $line (@lines) {
# Fix bison 2.3 and GCC 4.2.1
$line =~ s!\(YY_\("!(YY_((char*)"!g;
# Fix filename refs # Fix filename refs
$line =~ s!$basename!$newbase!g; $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->write($line);
} }
$fh->close; $fh->close;
@ -169,8 +197,7 @@ sub warning_check {
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n"; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
while (defined(my $line = $fh->getline)) { while (defined(my $line = $fh->getline)) {
if ($line =~ /(conflicts|warning:)/) { if ($line =~ /(conflicts|warning:|^useless)/i) {
clean_output();
die "%Error: $filename:$.: $line\n"; die "%Error: $filename:$.: $line\n";
} }
} }
@ -189,17 +216,67 @@ sub clean_input {
$fh->close; $fh->close;
# Find "%tokens<type>:" # Find "%tokens<type>:"
# Find "rule<type>:" and replace with just "rule:"
my %types;
my %rules; $Self->{rules} = \%rules;
my %tokens; my %tokens;
foreach my $line (@lines) { my $last_rule;
if ($line =~ /^%token\s*<(\S+)>\s*(\S+)/) { my $section = 1;
$tokens{$2} = $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 # Replace BISONPRE_NOT(type,...) with expanded list
{ {
my @linesin = @lines; @lines=(); my $l=0; my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) { foreach my $line (@linesin) {
$l++;
if ($line =~ /BISONPRE_NOT/) { if ($line =~ /BISONPRE_NOT/) {
($line =~ s/BISONPRE_NOT\((\S+)\)\s*({[^}]+})\s*$//) ($line =~ s/BISONPRE_NOT\((\S+)\)\s*({[^}]+})\s*$//)
or die "%Error: $filename:$l: Bad form of BISONPRE_NOT: $line\n"; 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:" # Replace BISONPRE_COPY(type,{code})
my %types;
{ {
my @linesin = @lines; @lines=(); my $l=0; my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) { foreach my $line (@linesin) {
# ^/ to prevent comments from matching $l++;
if ($line =~ s/^([^<\/ \t\n]+)<(\S+)>:/$1:/) { if ($line =~ /BISONPRE_COPY/) {
$types{$2}{$1} = 1; ($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; 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" # Find "BISONPRE_TYPES"
{ {
my @linesin = @lines; @lines=(); my $l=0; my @linesin = @lines; @lines=(); my $l=0;
@ -273,7 +371,6 @@ sub clean_input {
$fh->close; $fh->close;
} }
####################################################################### #######################################################################
__END__ __END__
@ -303,11 +400,21 @@ various compile warnings.
This is expanded into %type declarations. 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>: =item rule_label<type>:
This allows the label declaring a rule to also specify the type of the 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. 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...]) =item BISONPRE_NOT(token[, token...])
Create a rule that matches every token except for those specified. 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. in order by their token numbers; this is defined in the array yytname.
Also generated are #defines for YYNTOKENS, YYNNTS, YYNRULES, and YYNSTATES. 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 -t
==item --debug ==item --debug

View File

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

View File

@ -593,13 +593,17 @@ net_type: // ==IEEE: net_type
| yWIRE { VARDECL(WIRE); } | yWIRE { VARDECL(WIRE); }
| yTRI { VARDECL(TRIWIRE); } | 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); } | yINTEGER { VARDECL(INTEGER); }
; ;
@ -1390,33 +1394,47 @@ gatePulldownList<nodep>:
| gatePulldownList ',' gatePulldown { $$ = $1->addNext($3); } | 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: gateIdE:
/*empty*/ {} /*empty*/ {}