|
Packit |
ef9df4 |
#!/usr/local/bin/perl
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
# $Id: mkparse,v 1.2 2002/03/25 07:39:46 gbarr Exp $
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
my($source,$dest) = @ARGV;
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
system qw(byacc -P),$source;
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
open(OUT, ">$dest") or die "Cannot open $dest: $!\n";
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
open(IN, "cpp y.tab.pl|");
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
%var = ();
|
|
Packit |
ef9df4 |
%seen = ();
|
|
Packit |
ef9df4 |
%state = ();
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
while(<IN>) {
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
# In perl the stack size is not a problem
|
|
Packit |
ef9df4 |
next if /YYSTACKSIZE/;
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
next if /^# \d+ "(.*?)"/ and $1 ne "parser.y";
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
# Replace variables with constant subs
|
|
Packit |
ef9df4 |
if(s/^\$([A-Z][A-Z_0-9]*)\s*=\s*(\d+)\s*;/sub const$1 () { $2 }/) {
|
|
Packit |
ef9df4 |
$var{$1} = "const" . $1 . "()";
|
|
Packit |
ef9df4 |
}
|
|
Packit |
ef9df4 |
s/
|
|
Packit |
ef9df4 |
(\$([A-Z][A-Z_0-9]*))
|
|
Packit |
ef9df4 |
/
|
|
Packit |
ef9df4 |
exists $var{$2} ? $var{$2} : $1
|
|
Packit |
ef9df4 |
/xeg;
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
# Comment out the id line
|
|
Packit |
ef9df4 |
s/^(?=\$yysccsid)/#/;
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
# Use my variables
|
|
Packit |
ef9df4 |
s/^(\@yy\w+\s+=)/my $1/;
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
# Make yyparse return $$ for the top terminal
|
|
Packit |
ef9df4 |
if (/^sub yyparse/ .. /^\}\s*#\s*yyparse/) {
|
|
Packit |
ef9df4 |
s/\breturn\(1\)/return undef/;
|
|
Packit |
ef9df4 |
s/\breturn\(0\)/return \$yyvs[\$yyvsp]/;
|
|
Packit |
ef9df4 |
}
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
# Are we inside the switch statement ?
|
|
Packit |
ef9df4 |
my $ln = /^\s+switch:/ .. /^\s+\$yyssp -= \$yym;/;
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
# Change all the if statements in the switch to labels
|
|
Packit |
ef9df4 |
if ( $ln ) {
|
|
Packit |
ef9df4 |
s/^if \(\$yyn == (\d+)\s*\)/State$1:/ and $state{"State$1"} = '';
|
|
Packit |
ef9df4 |
}
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
# fix an uninit bug
|
|
Packit |
ef9df4 |
s/^(\s*)(?=\$yycheck\[\$yyn\]\s+==)/$1\$yyn <= \$#yycheck && /;
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
print OUT;
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
# Print the goto for the switch
|
|
Packit |
ef9df4 |
print OUT <<'ESQ' if $ln == 2;
|
|
Packit |
ef9df4 |
my $label = "State$yyn";
|
|
Packit |
ef9df4 |
goto $label if exists $yystate{$label};
|
|
Packit |
ef9df4 |
last switch;
|
|
Packit |
ef9df4 |
ESQ
|
|
Packit |
ef9df4 |
}
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
# output table with names of labels that exist
|
|
Packit |
ef9df4 |
my $states = '%yystate = (\'' . join("','",%state) . "');\n";
|
|
Packit |
ef9df4 |
$states =~ s/(.{60,75},)/$1\n/g;
|
|
Packit |
ef9df4 |
print OUT $states,"\n1;\n";
|
|
Packit |
ef9df4 |
|
|
Packit |
ef9df4 |
close OUT;
|
|
Packit |
ef9df4 |
close IN;
|
|
Packit |
ef9df4 |
|