#!/bin/sh
#    yacc++
#	by Frank Barrus (December, 1996)
#	converts yacc/bison output to a format 
#	that can more easily be used by C++ classes

set -e

YACC="bison"
SED=sed
AWK=awk

( $YACC -h 2> /dev/null | grep bison > /dev/null )
if [ $? = 0 ] ; then
	bison=true
fi
fprefix=
raw=false
opts=""
outfile=
err=false

while [ "$1" != "" ]; do
	case $1 in 
	-[vltd])	opts="$opts $1" ;;
	-b)		fprefix=$2; shift ;;
	-r)		raw=true
			if $bison ; then opts="$opts -r"; fi
			;;
	-o)		outfile=$2; shift ;;
	-[A-Za-z]*)	echo "illegal option: $1"; err=true ;;
	*)		file=$1
	esac
	shift
done

if [ "$file" = "" ] ; then
	err=true
fi
if $err; then
	echo "usage: $0 [-vltd] [-b prefix] [-o outfile] filename"
	exit 1
fi
if [ "$fprefix" = "" ] ; then
	fprefix=`basename $file .y`
fi
cfile=$fprefix.tab.c
if [ "$outfile" = "" ] ; then
	outfile=$fprefix.tab.C
fi

$YACC $opts -b $fprefix $file

echo "converting $cfile to $outfile..."

$SED -f - $cfile <<-endsed > $outfile
	/^#include <stdio.h>/d
	/^.*yysccsid.*$/d
	/^int[ 	]\+yydebug;/d
	/^YYLTYPE[ 	]\+yylloc;/d
	/^short[ 	]\+\**yy[A-Za-z0-9_]\+\[]/s/^/static /
	/^yyerrlab:/{
		i\\
		goto yyerrlab;
	}
	/^yynewerror:/{
		i\\
		goto yynewerror;
	}
	/^int[ 	]\+yychar;/ {
		H
		a\\
\#ifndef YYPARSEVARS
		a\\
\#define YYPARSEVARS
		a\\
\#endif
		a\\
\#ifndef YYPARSE
		a\\
\#define YYPARSE yyparse
		a\\
\#endif
		a\\
\#ifdef YYCLASS
		a\\
\#define YYPARSEDEF YYCLASS::YYPARSE
		a\\
\#else
		a\\
\#define YYPARSEDEF YYPARSE
		a\\
\#endif
		a\\
\#ifndef YYDEBUGFLAG
		a\\
\#define YYDEBUGFLAG yydebug
		a\\
\#endif
		a\\
\#ifndef YYEPRINTF
		a\\
\#define YYEPRINTF printf
		a\\
\#endif
		d
	}
	/^[a-zA-Z_]\+[ 	]\+\**yy[][a-zA-Z_]\+;/{
		H
		d
	}
	/[ 	]*yyparse(/{
		s/yyparse/YYPARSEDEF/
		N
		/^[^{]\*$/{
		}
		N
		/{/{
		} 
		G
		a\\
YYPARSEVARS
	}
	/^[^#]/{
		s/\<yydebug\>/YYDEBUGFLAG/g
		s/\<yyparse\W*(/YYPARSE(/g
		s/\<fprintf\W*(\W*stderr,/YYEPRINTF(/g
		s/\<printf\W*(/YYEPRINTF(/g
		s/\<YYLEX\>/YYLEXCALL/g
	}
	/^#define\W\+YYLEX\W\+yylex(/s/YYLEX/YYLEXCALL/
	s/\<yylex\W*([ 	]*)/YYLEX(\&yylval)/
	s/\<$cfile\>/$outfile/
	s/yyn = yydefred\[yystate]/(&)/
endsed

rm -f $cfile

#$AWK -f - $cfile <<-endawk
#	/
#	/^ +[0-9]+/ { print \$0; }
#endawk

