#!/usr/local/bin/perl
'di';
'ig00';
#
# $Header: exyacc,v 1.1 90/08/12 22:54:12 lwall Locked $
#
# $Log:	exyacc,v $
# Revision 1.1  90/08/12  22:54:12  lwall
# Initial revision
# 

$num = shift if $ARGV[0] =~ /^-n/;

undef $/;
$* = 1;

while (<>) {	# One file at a time...

		# 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 %% 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 negation of terminator easy to find
    s#/\*[^\202]*\202\202##g;

		# Strip {}'s from the inside out; several passes handle nesting.

    0 while s/{[^}{]*}//g;

		# Restore 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;
}
##############################################################################

	# These next few lines are legal in both Perl and nroff.

.00;			# finish .ig
 
'di			\" finish diversion--previous line must be blank
.nr nl 0-1		\" fake up transition to first page again
.nr % 0			\" start at page 1
'; __END__ ############# From here on it's a standard manual page ############
.TH EXYACC 1 "August 12, 1990"
.AT 3
.SH NAME
exyacc \- extract grammar from yacc file
.SH SYNOPSIS
.B exyacc [-n] [yaccfiles]
.SH DESCRIPTION
.I Exyacc
munches one or more yacc files and spits out just the grammar rules to
standard output.
With a
.B \-n
switch, numbers the productions, which can be useful for interpreting
yacc diagnostics.
.SH ENVIRONMENT
No environment variables are used.
.SH FILES
None.
.SH AUTHOR
Larry Wall
.SH "SEE ALSO"
yacc(1)
.SH DIAGNOSTICS
None.
.SH BUGS
.ex
