/*
 *	Copyright 1987 Silicon Graphics, Inc. - All Rights Reserved
 */

/* #ident	"@(#)yacc:yaccpar	1.10" */
#ident	"$Revision: 1.1 $"

/*
** Skeleton parser driver for yacc output
*/
#include "stddef.h"

/*
** yacc user known macros and defines
*/
#define YYERROR		goto $Myyerrlab;
#define YYACCEPT	return(0)
#define YYABORT		return(1)

#define $MYYBACKUP( newtoken, newvalue )\
{\
	if ( Y.yychar >= 0 || ( $Myyr2[ Y.yytmp ] >> 1 ) != 1 )\
	{\
		$Myyerror( "Syntax error - cannot backup", lex_data, user_data );\
		goto $Myyerrlab;\
	}\
	Y.yychar = newtoken;\
	Y.yystate = *Y.yyps;\
	Y.yylval = newvalue;\
	goto $Myynewstate;\
}

#define $MYYRECOVERING()	(!!Y.yyerrflag)
#define $MYYNEW(type)		malloc(sizeof(type) * yynewmax)
#define $MYYCOPY(to, from, type) \
	(type *) memcpy(to, (char *) from, yynewmax * sizeof(type))
#define $MYYENLARGE( from, type) \
	(type *) realloc((char *) from, yynewmax * sizeof(type))
#ifndef $MYYDEBUG
#	define $MYYDEBUG	1	/* make debugging available */
#endif

/*
** driver internal defines
*/
#define $MYYFLAG		(-10000000)

/*
** $Myyparse - return 0 if worked, 1 if syntax error not recovered from
*/
#if defined(__STDC__) || defined(__cplusplus)
int $Myyparse(void *lex_data, void *user_data, int debug)
#else
int $Myyparse(lex_data, user_data, debug)
	void *lex_data;
	void *user_data;
	int debug;
#endif
{
	$Myystate_t Y;
	register $MYYSTYPE *yypvt;	/* top of value stack for $vars */

	/*
	** Initialize externals - yyparse may be called more than once
	*/

	Y.yymaxdepth = $MYYMAXDEPTH;
	Y.yydebug = debug;
	Y.yyv = Y.yy_yyv;
	Y.yys = Y.yy_yys;

	Y.yypv = &Y.yyv[-1];
	Y.yyps = &Y.yys[-1];
	Y.yystate = 0;
	Y.yytmp = 0;
	Y.yynerrs = 0;
	Y.yyerrflag = 0;
	Y.yychar = -1;

#if $MYYMAXDEPTH <= 0
	if (Y.yymaxdepth <= 0)
	{
		if ((Y.yymaxdepth = $MYYEXPAND(0)) <= 0)
		{
			$Myyerror( "Yacc initialization error", lex_data, user_data );
			YYABORT;
		}
	}
#endif

	goto $Myystack;
	{
		register $MYYSTYPE *yy_pv;	/* top of value stack */
		register int *yy_ps;		/* top of state stack */
		register int yy_state;		/* current state */
		register int  yy_n;		/* internal state number info */

		/*
		** get globals into registers.
		** branch to here only if YYBACKUP was called.
		*/
	$Myynewstate:
		yy_pv = Y.yypv;
		yy_ps = Y.yyps;
		yy_state = Y.yystate;
		goto $Myy_newstate;

		/*
		** get globals into registers.
		** either we just started, or we just finished a reduction
		*/
	$Myystack:
		yy_pv = Y.yypv;
		yy_ps = Y.yyps;
		yy_state = Y.yystate;

		/*
		** top of for (;;) loop while no reductions done
		*/
	$Myy_stack:
		/*
		** put a state and value onto the stacks
		*/
#if $MYYDEBUG
		/*
		** if debugging, look up token value in list of value vs.
		** name pairs.  0 and negative (-1) are special values.
		** Note: linear search is used since time is not a real
		** consideration while debugging.
		*/
		if ( Y.yydebug )
		{
			register int yy_i;

			printf( "State %d, token ", yy_state );
			if ( Y.yychar == 0 )
				printf( "end-of-file\n" );
			else if ( Y.yychar < 0 )
				printf( "-none-\n" );
			else
			{
				for ( yy_i = 0; $Myytoks[yy_i].t_val >= 0;
					yy_i++ )
				{
					if ( $Myytoks[yy_i].t_val == Y.yychar )
						break;
				}
				printf( "%s\n", $Myytoks[yy_i].t_name );
			}
		}
#endif /* $MYYDEBUG */
		if ( ++yy_ps >= &Y.yys[ Y.yymaxdepth ] )	/* room on stack? */
		{
#if $MYYMAXDEPTH > 0
			$Myyerror( "Yacc stack overflow", lex_data, user_data );
			YYABORT;
#else
			int yynewmax;
			ptrdiff_t yys_off;

			/* The following pointer-differences are safe, since
			 * yypvt, yy_pv, and yypv all are a multiple of
			 * sizeof(YYSTYPE) bytes from yyv.
			 */
			ptrdiff_t yypvt_off = yypvt - Y.yyv;
			ptrdiff_t yy_pv_off = yy_pv - Y.yyv;
			ptrdiff_t yypv_off = Y.yypv - Y.yyv;

			int *yys_base = Y.yys;
#    ifdef $MYYEXPAND
			yynewmax = $MYYEXPAND(Y.yymaxdepth);
#    else
			yynewmax = 2 * Y.yymaxdepth;	/* double table size */
			if (Y.yymaxdepth == $MYYMAXDEPTH)	/* first time growth */
			{
				void *newyys = $MYYNEW(int);
				void *newyyv = $MYYNEW($MYYSTYPE);
				if (newyys != 0 && newyyv != 0)
				{
					Y.yys = $MYYCOPY(newyys, Y.yys, int);
					Y.yyv = $MYYCOPY(newyyv, Y.yyv, $MYYSTYPE);
				}
				else
					yynewmax = 0;	/* failed */
			}
			else				/* not first time */
			{
				Y.yys = $MYYENLARGE(Y.yys, int);
				Y.yyv = $MYYENLARGE(Y.yyv, $MYYSTYPE);
				if (Y.yys == 0 || Y.yyv == 0)
					yynewmax = 0;	/* failed */
			}
#    endif
			if (yynewmax <= Y.yymaxdepth)	/* tables not expanded */
			{
				$Myyerror( "Yacc stack overflow", lex_data, user_data );
				YYABORT;
			}
			Y.yymaxdepth = yynewmax;

			/* reset pointers into yys */
			yys_off = Y.yys - yys_base;
			yy_ps = yy_ps + yys_off;
			Y.yyps = Y.yyps + yys_off;

			/* reset pointers into yyv */
			yypvt = Y.yyv + yypvt_off;
			yy_pv = Y.yyv + yy_pv_off;
			Y.yypv = Y.yyv + yypv_off;
#endif
		}
		*yy_ps = yy_state;
		*++yy_pv = Y.yyval;

		/*
		** we have a new state - find out what to do
		*/
	$Myy_newstate:
		if ( ( yy_n = $Myypact[ yy_state ] ) <= $MYYFLAG )
			goto $Myydefault;		/* simple state */
#if $MYYDEBUG
		/*
		** if debugging, need to mark whether new token grabbed
		*/
		Y.yytmp = Y.yychar < 0;
#endif
		if ( ( Y.yychar < 0 ) && ( ( Y.yychar = $Myylex(&Y.yylval, lex_data) ) < 0 ) )
			Y.yychar = 0;		/* reached EOF */
#if $MYYDEBUG
		if ( Y.yydebug && Y.yytmp )
		{
			register int yy_i;

			printf( "Received token " );
			if ( Y.yychar == 0 )
				printf( "end-of-file\n" );
			else if ( Y.yychar < 0 )
				printf( "-none-\n" );
			else
			{
				for ( yy_i = 0; $Myytoks[yy_i].t_val >= 0;
					yy_i++ )
				{
					if ( $Myytoks[yy_i].t_val == Y.yychar )
						break;
				}
				printf( "%s\n", $Myytoks[yy_i].t_name );
			}
		}
#endif /* $MYYDEBUG */
		if ( ( ( yy_n += Y.yychar ) < 0 ) || ( yy_n >= $MYYLAST ) )
			goto $Myydefault;
		if ( $Myychk[ yy_n = $Myyact[ yy_n ] ] == Y.yychar )	/*valid shift*/
		{
			Y.yychar = -1;
			Y.yyval = Y.yylval;
			yy_state = yy_n;
			if ( Y.yyerrflag > 0 )
				Y.yyerrflag--;
			goto $Myy_stack;
		}

	$Myydefault:
		if ( ( yy_n = $Myydef[ yy_state ] ) == -2 )
		{
#if $MYYDEBUG
			Y.yytmp = Y.yychar < 0;
#endif
			if ( ( Y.yychar < 0 ) && ( ( Y.yychar = $Myylex(&Y.yylval, lex_data) ) < 0 ) )
				Y.yychar = 0;		/* reached EOF */
#if $MYYDEBUG
			if ( Y.yydebug && Y.yytmp )
			{
				register int yy_i;

				printf( "Received token " );
				if ( Y.yychar == 0 )
					printf( "end-of-file\n" );
				else if ( Y.yychar < 0 )
					printf( "-none-\n" );
				else
				{
					for ( yy_i = 0;
						$Myytoks[yy_i].t_val >= 0;
						yy_i++ )
					{
						if ( $Myytoks[yy_i].t_val
							== Y.yychar )
						{
							break;
						}
					}
					printf( "%s\n", $Myytoks[yy_i].t_name );
				}
			}
#endif /* $MYYDEBUG */
			/*
			** look through exception table
			*/
			{
				register int *yyxi = $Myyexca;

				while ( ( *yyxi != -1 ) ||
					( yyxi[1] != yy_state ) )
				{
					yyxi += 2;
				}
				while ( ( *(yyxi += 2) >= 0 ) &&
					( *yyxi != Y.yychar ) )
					;
				if ( ( yy_n = yyxi[1] ) < 0 )
					YYACCEPT;
			}
		}

		/*
		** check for syntax error
		*/
		if ( yy_n == 0 )	/* have an error */
		{
			/* no worry about speed here! */
			switch ( Y.yyerrflag )
			{
			case 0:		/* new error */
				$Myyerror( "Syntax error", lex_data, user_data );
				goto $Mskip_init;
			$Myyerrlab:
				/*
				** get globals into registers.
				** we have a user generated syntax type error
				*/
				yy_pv = Y.yypv;
				yy_ps = Y.yyps;
				yy_state = Y.yystate;
				Y.yynerrs++;
				/* FALLTHRU */
			$Mskip_init:
			case 1:
			case 2:		/* incompletely recovered error */
					/* try again... */
				Y.yyerrflag = 3;
				/*
				** find state where "error" is a legal
				** shift action
				*/
				while ( yy_ps >= Y.yys )
				{
					yy_n = $Myypact[ *yy_ps ] + $MYYERRCODE;
					if ( yy_n >= 0 && yy_n < $MYYLAST &&
						$Myychk[$Myyact[yy_n]] == $MYYERRCODE)					{
						/*
						** simulate shift of "error"
						*/
						yy_state = $Myyact[ yy_n ];
						goto $Myy_stack;
					}
					/*
					** current state has no shift on
					** "error", pop stack
					*/
#if $MYYDEBUG
#	define _POP_ "Error recovery pops state %d, uncovers state %d\n"
					if ( Y.yydebug )
						printf( _POP_, *yy_ps,
							yy_ps[-1] );
#	undef _POP_
#endif
					yy_ps--;
					yy_pv--;
				}
				/*
				** there is no state on stack with "error" as
				** a valid shift.  give up.
				*/
				YYABORT;
			case 3:		/* no shift yet; eat a token */
#if $MYYDEBUG
				/*
				** if debugging, look up token in list of
				** pairs.  0 and negative shouldn't occur,
				** but since timing doesn't matter when
				** debugging, it doesn't hurt to leave the
				** tests here.
				*/
				if ( Y.yydebug )
				{
					register int yy_i;

					printf( "Error recovery discards " );
					if ( Y.yychar == 0 )
						printf( "token end-of-file\n" );
					else if ( Y.yychar < 0 )
						printf( "token -none-\n" );
					else
					{
						for ( yy_i = 0;
							$Myytoks[yy_i].t_val >= 0;
							yy_i++ )
						{
							if ( $Myytoks[yy_i].t_val
								== Y.yychar )
							{
								break;
							}
						}
						printf( "token %s\n",
							$Myytoks[yy_i].t_name );
					}
				}
#endif /* $MYYDEBUG */
				if ( Y.yychar == 0 )	/* reached EOF. quit */
					YYABORT;
				Y.yychar = -1;
				goto $Myy_newstate;
			}
		}/* end if ( yy_n == 0 ) */
		/*
		** reduction by production yy_n
		** put stack tops, etc. so things right after switch
		*/
#if $MYYDEBUG
		/*
		** if debugging, print the string that is the user's
		** specification of the reduction which is just about
		** to be done.
		*/
		if ( Y.yydebug )
			printf( "Reduce by (%d) \"%s\"\n",
				yy_n, $Myyreds[ yy_n ] );
#endif
		Y.yytmp = yy_n;		/* value to switch over */
		yypvt = yy_pv;			/* $vars top of value stack */
		/*
		** Look in goto table for next state
		** Sorry about using yy_state here as temporary
		** register variable, but why not, if it works...
		** If yyr2[ yy_n ] doesn't have the low order bit
		** set, then there is no action to be done for
		** this reduction.  So, no saving & unsaving of
		** registers done.  The only difference between the
		** code just after the if and the body of the if is
		** the goto yy_stack in the body.  This way the test
		** can be made before the choice of what to do is needed.
		*/
		{
			/* length of production doubled with extra bit */
			register int yy_len = $Myyr2[ yy_n ];

			if ( !( yy_len & 01 ) )
			{
				yy_len >>= 1;
				Y.yyval = ( yy_pv -= yy_len )[1];	/* $$ = $1 */
				yy_state = $Myypgo[ yy_n = $Myyr1[ yy_n ] ] +
					*( yy_ps -= yy_len ) + 1;
				if ( yy_state >= $MYYLAST ||
					$Myychk[ yy_state =
					$Myyact[ yy_state ] ] != -yy_n )
				{
					yy_state = $Myyact[ $Myypgo[ yy_n ] ];
				}
				goto $Myy_stack;
			}
			yy_len >>= 1;
			Y.yyval = ( yy_pv -= yy_len )[1];	/* $$ = $1 */
			yy_state = $Myypgo[ yy_n = $Myyr1[ yy_n ] ] +
				*( yy_ps -= yy_len ) + 1;
			if ( yy_state >= $MYYLAST ||
				$Myychk[ yy_state = $Myyact[ yy_state ] ] != -yy_n )
			{
				yy_state = $Myyact[ $Myypgo[ yy_n ] ];
			}
		}
					/* save until reenter driver code */
		Y.yystate = yy_state;
		Y.yyps = yy_ps;
		Y.yypv = yy_pv;
	}
	/*
	** code supplied by user is placed in this switch
	*/
	switch( Y.yytmp )
	{
		$A
	}
	goto $Myystack;		/* reset registers in driver code */
}
