#!/usr/local/bin/perl
my
(
$source
,
$dest
) =
@ARGV
;
system
qw(byacc -P)
,
$source
;
open
(OUT,
">$dest"
) or
die
"Cannot open $dest: $!\n"
;
open
(IN,
"cpp y.tab.pl|"
);
%var
= ();
%seen
= ();
%state
= ();
while
(<IN>) {
next
if
/YYSTACKSIZE/;
next
if
/^
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
<= \
$#yycheck
&& /;
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;