my($source,$dest) = @ARGV;
system qw(/usr/local/bin/byacc -P),$source;
open(OUT, ">$dest") or die "Cannot open $dest: $!\n";
open(IN, "gcc -E -C -x c y.tab.pl|");
%var = ();
%seen = ();
%state = ();
while(<IN>) {
next if /YYSTACKSIZE/;
if(s/^\$([A-Z][A-Z_0-9]*)\s*=\s*(\d+)\s*;/sub const$1 () { $2 }/) {
$var{$1} = "const" . $1 . "()";
}
s/
(\$([A-Z][A-Z_0-9]*))
/
exists $var{$2} ? $var{$2} : $1
/xeg;
s/^(?=\$yysccsid)/
s/^(\@yy\w+\s+=)/my $1/;
if (/^sub yyparse/ .. /^\}\s* s/\breturn\(1\)/return undef/;
s/\breturn\(0\)/return \$yyvs[\$yyvsp]/;
}
my $ln = /^\s+switch:/ .. /^\s+\$yyssp -= \$yym;/;
if ( $ln ) {
s/^if \(\$yyn == (\d+)\s*\)/State$1:/ and $state{"State$1"} = '';
}
s/^(\s*)(?=\$yycheck\[\$yyn\]\s+==)/$1\$yyn <= \$
print OUT;
print OUT <<'ESQ' if $ln == 2;
my $label = "State$yyn";
goto $label if exists $yystate{$label};
last switch;
ESQ
}
my $states = '%yystate = (\'' . join("','",%state) . "');\n";
$states =~ s/(.{60,75},)/$1\n/g;
print OUT $states,"\n1;\n";
close OUT;
close IN;