#/usr/bin/perl # Usage: exyacc [-n] [yaccfiles] $num = shift if $ARGV[0] =~ /^-n/; undef $/; $* = 1; # Treat $_ as multi-line buffer. while (<>) { # One file at a time because of undef above. # First pull out the rules section. # (Note: Assumes no comment includes "\n%%"). $start = index($_,"\n%%") + 1; $end = rindex($_,"\n%%") + 1; $_ = substr($_, $start, $end - $start); s/.*\n//;; # Delete the %% line. # Save curly brackets used as tokens. s/'{'/'\200'/g; # Keep length same for inplace. s/'}'/'\201'/g; # Strip comments. s#\*/#\202\202#g; # Make terminator easy to find s#/\*[^\202]*\202\202##g; # Strip {}'s from the inside out; # several passes handle nesting. 0 while s/{[^}{]*}//g; # Restore any curly brackets used as tokens. s/'\200'/'{'/g; s/'\201'/'}'/g; # Eliminate unwanted blank lines. 0 while s/^[ \t]*\n(\s)/$1/g; # Number rules if desired. # Assumes | always starts line. $seq = 0; s/^(\w*\s*[:|])/$1 . ++$seq/eg if $num; # And there you have it... print; }