Blame mkparse

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