# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
# symbols on RHS.
m4_define([b4_rhs_value],
-[(((yyGLRStackItem const *)yyvsp)@{YYFILL ($2 - $1)@}.yystate.yysemantics.yysval[]m4_ifval([$3], [.$3]))])
+[(((yyGLRStackItem const *)yyvsp)@{YYFILL (($2) - ($1))@}.yystate.yysemantics.yysval[]m4_ifval([$3], [.$3]))])
# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
# on RHS.
m4_define([b4_rhs_location],
-[(((yyGLRStackItem const *)yyvsp)@{YYFILL ($2 - $1)@}.yystate.yyloc)])
+[(((yyGLRStackItem const *)yyvsp)@{YYFILL (($2) - ($1))@}.yystate.yyloc)])
#endif
/* Suppress unused-variable warnings by "using" E. */
-#if __cplusplus
-# define YYUSE(e) (void) (e)
+#ifndef lint
+# define YYUSE(e) ((void) (e))
#else
-# define YYUSE(e) do {;} while (/*CONSTCOND*/ yyfalse && (e))
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+]b4_c_function_def([YYID], [static int], [[int i], [i]])[
+{
+ return i;
+}
#endif
#ifndef YYFREE
(Current).first_column = (Current).last_column = \
YYRHSLOC (Rhs, 0).last_column; \
} \
- while (/*CONSTCOND*/ 0)
+ while (YYID (0))
/* YY_LOCATION_PRINT -- Print the location on the stream.
This macro was not mandated originally: define only if we know
# define YY_LOCATION_PRINT(File, Loc) \
fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
#endif
]],[
#ifndef YYLLOC_DEFAULT
#define YYCHK(YYE) \
do { YYRESULTTAG yyflag = YYE; if (yyflag != yyok) return yyflag; } \
- while (/*CONSTCOND*/ 0)
+ while (YYID (0))
#if YYDEBUG
do { \
if (yydebug) \
YYFPRINTF Args; \
-} while (/*CONSTCOND*/ 0)
+} while (YYID (0))
]b4_yysymprint_generate([b4_c_ansi_function_def])[
{ \
YYFPRINTF (stderr, "%s ", Title); \
yysymprint (stderr, \
- Type, Value]b4_location_if([, Location])[]b4_user_args[); \
+ Type, Value]b4_location_if([, Location])[]b4_user_args[); \
YYFPRINTF (stderr, "\n"); \
} \
-} while (/*CONSTCOND*/ 0)
+} while (YYID (0))
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
do { \
if (Yystack->yyspaceLeft < YYHEADROOM) \
yyexpandGLRStack (Yystack); \
- } while (/*CONSTCOND*/ 0)
+ } while (YYID (0))
#else
# define YY_RESERVE_GLRSTACK(Yystack) \
do { \
if (Yystack->yyspaceLeft < YYHEADROOM) \
yyMemoryExhausted (Yystack); \
- } while (/*CONSTCOND*/ 0)
+ } while (YYID (0))
#endif
* value ($$), and yylocp points to place for location information
* (@@$). Returns yyok for normal return, yyaccept for YYACCEPT,
* yyerr for YYERROR, yyabort for YYABORT. */
-static YYRESULTTAG
+/*ARGSUSED*/ static YYRESULTTAG
yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
YYSTYPE* yyvalp,
YYLTYPE* YYOPTIONAL_LOC (yylocp),
yyGLRStack* yystack
- ]b4_user_formals[)
+ ]b4_user_formals[)
{
yybool yynormal __attribute__ ((__unused__)) =
(yystack->yysplitPoint == NULL);
}
\f
-static void
+/*ARGSUSED*/ static void
yyuserMerge (int yyn, YYSTYPE* yy0, YYSTYPE* yy1)
{
YYUSE (yy0);
#endif
if (yys->yysemantics.yyfirstVal)
- {
- yySemanticOption *yyoption = yys->yysemantics.yyfirstVal;
- yyGLRState *yyrh;
- int yyn;
- for (yyrh = yyoption->yystate, yyn = yyrhsLength (yyoption->yyrule);
- yyn > 0;
- yyrh = yyrh->yypred, yyn -= 1)
- yydestroyGLRState (yymsg, yyrh]b4_user_args[);
- }
+ {
+ yySemanticOption *yyoption = yys->yysemantics.yyfirstVal;
+ yyGLRState *yyrh;
+ int yyn;
+ for (yyrh = yyoption->yystate, yyn = yyrhsLength (yyoption->yyrule);
+ yyn > 0;
+ yyrh = yyrh->yypred, yyn -= 1)
+ yydestroyGLRState (yymsg, yyrh]b4_user_args[);
+ }
}
}
*/
static inline void
yygetLRActions (yyStateNum yystate, int yytoken,
- int* yyaction, const short int** yyconflicts)
+ int* yyaction, const short int** yyconflicts)
{
int yyindex = yypact[yystate] + yytoken;
if (yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken)
= yystack->yytops.yystates[yyk];]b4_location_if([[
if (yynrhs == 0)
/* Set default location. */
- yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yys->yyloc;]])[
+ yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yys->yyloc;]])[
for (yyi = 0; yyi < yynrhs; yyi += 1)
{
yys = yys->yypred;
do { \
if (yydebug) \
yy_reduce_print Args; \
-} while (/*CONSTCOND*/ 0)
+} while (YYID (0))
/*----------------------------------------------------------.
| Report that the RULE is going to be reduced on stack #K. |
`----------------------------------------------------------*/
-static inline void
+/*ARGSUSED*/ static inline void
yy_reduce_print (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[)
{
[ YYFPRINTF (stderr, "Reducing stack %lu by rule %d (line %lu):\n",
(unsigned long int) yyk, yyrule - 1,
(unsigned long int) yyrline[yyrule]);
- /* Print the symbols being reduced, and their result. */
- //for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+ /* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
{
- fprintf (stderr, " $%d = ", yyi);
+ fprintf (stderr, " $%d = ", yyi + 1);
yysymprint (stderr, yyrhs[yyprhs[yyrule] + yyi],
- &]b4_rhs_value(yynrhs, yyi)[
- ]b4_location_if([, &]b4_rhs_location(yynrhs, yyi))[]dnl
- b4_user_args[);
+ &]b4_rhs_value(yynrhs, yyi + 1)[
+ ]b4_location_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
+ b4_user_args[);
fprintf (stderr, "\n");
}
}
*/
static inline YYRESULTTAG
yyglrReduce (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
- yybool yyforceEval]b4_user_formals[)
+ yybool yyforceEval]b4_user_formals[)
{
size_t yyposn = yystack->yytops.yystates[yyk]->yyposn;
static YYRESULTTAG
yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystack,
- YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[)
+ YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[)
{
yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
int yynrhs;
break;
default:
/* This cannot happen so it is not worth a YYASSERT (yyfalse),
- but some compilers complain if the default case is
+ but some compilers complain if the default case is
omitted. */
break;
}
static YYRESULTTAG
yyprocessOneStack (yyGLRStack* yystack, size_t yyk,
- size_t yyposn, YYSTYPE* yylvalp, YYLTYPE* yyllocp
+ size_t yyposn, YYSTYPE* yylvalp, YYLTYPE* yyllocp
]b4_pure_formals[)
{
int yyaction;
}
if (yyisShiftAction (yyaction))
- {
- YYDPRINTF ((stderr, "On stack %lu, ", (unsigned long int) yyk));
- YY_SYMBOL_PRINT ("shifting", *yytokenp, yylvalp, yyllocp);
- yyglrShift (yystack, yyk, yyaction, yyposn+1,
- *yylvalp, yyllocp);
- YYDPRINTF ((stderr, "Stack %lu now in state #%d\n",
- (unsigned long int) yyk,
- yystack->yytops.yystates[yyk]->yylrState));
- break;
- }
+ break;
else if (yyisErrorAction (yyaction))
{
YYDPRINTF ((stderr, "Stack %lu dies.\n",
/* Recover from a syntax error on YYSTACK, assuming that YYTOKENP,
YYLVALP, and YYLLOCP point to the syntactic category, semantic
value, and location of the look-ahead. */
-static void
+/*ARGSUSED*/ static void
yyrecoverSyntaxError (yyGLRStack* yystack,
YYSTYPE* yylvalp,
YYLTYPE* YYOPTIONAL_LOC (yyllocp)
default: \
goto yybuglab; \
} \
- } while (/*CONSTCOND*/ 0)
+ } while (YYID (0))
/*----------.
const short int* yyconflicts;
yyStateNum yystate = yystack.yytops.yystates[0]->yylrState;
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
if (yystate == YYFINAL)
goto yyacceptlab;
if (yyisDefaultedState (yystate))
YYDPRINTF ((stderr, "Reading a token: "));
yychar = YYLEX;
yytoken = YYTRANSLATE (yychar);
- YY_SYMBOL_PRINT ("Next token is", yytoken, yylvalp, yyllocp);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, yylvalp, yyllocp);
}
yygetLRActions (yystate, yytoken, &yyaction, &yyconflicts);
if (*yyconflicts != 0)
while (yytrue)
{
+ yySymbol yytoken_to_shift;
size_t yys;
size_t yyn = yystack.yytops.yysize;
+
+ /* yyprocessOneStack returns one of three things:
+
+ - An error flag. If the caller is yyprocessOneStack, it
+ immediately returns as well. When the caller is finally
+ yyparse, it jumps to an error label via YYCHK1.
+
+ - yyok, but yyprocessOneStack has invoked yymarkStackDeleted
+ (&yystack, yys), which sets the top state of yys to NULL. Thus,
+ yyparse's following invocation of yyremoveDeletes will remove
+ the stack.
+
+ - yyok, when ready to shift a token.
+
+ Except in the first case, yyparse will invoke yyremoveDeletes and
+ then shift the next token onto all remaining stacks. This
+ synchronization of the shift (that is, after all preceding
+ reductions on all stacks) helps prevents double destructor calls
+ on yylval in the event of memory exhaustion. */
+
for (yys = 0; yys < yyn; yys += 1)
YYCHK1 (yyprocessOneStack (&yystack, yys, yyposn,
yylvalp, yyllocp]b4_lpure_args[));
+ yyremoveDeletes (&yystack);
+ yyn = yystack.yytops.yysize;
+
+ /* If any yyglrShift call fails, it will fail after shifting. Thus,
+ a copy of yylval will already be on stack 0 in the event of a
+ failure in the following loop. Thus, yytoken is set to YYEMPTY
+ before the loop to make sure the user destructor for yylval isn't
+ called twice. */
+ yytoken_to_shift = yytoken;
yytoken = YYEMPTY;
yyposn += 1;
- yyremoveDeletes (&yystack);
+ for (yys = 0; yys < yyn; yys += 1)
+ {
+ int yyaction;
+ const short int* yyconflicts;
+ yyStateNum yystate = yystack.yytops.yystates[yys]->yylrState;
+ yygetLRActions (yystate, yytoken_to_shift, &yyaction,
+ &yyconflicts);
+ /* Note that yyconflicts were handled by yyprocessOneStack. */
+ YYDPRINTF ((stderr, "On stack %lu, ", (unsigned long int) yys));
+ YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, yylvalp, yyllocp);
+ yyglrShift (&yystack, yys, yyaction, yyposn,
+ *yylvalp, yyllocp);
+ YYDPRINTF ((stderr, "Stack %lu now in state #%d\n",
+ (unsigned long int) yys,
+ yystack.yytops.yystates[yys]->yylrState));
+ }
if (yystack.yytops.yysize == 0)
{
yyundeleteLastStack (&yystack);
yyreturn:
if (yytoken != YYEOF && yytoken != YYEMPTY)
yydestruct ("Cleanup: discarding lookahead",
- yytoken, yylvalp]b4_location_if([, yyllocp])[]b4_user_args[);
+ yytoken, yylvalp]b4_location_if([, yyllocp])[]b4_user_args[);
/* If the stack is well-formed, pop the stack until it is empty,
destroying its entries as we go. But free the stack regardless
{
yyGLRState** yystates = yystack.yytops.yystates;
if (yystates)
- while (yystates[0])
- {
- yyGLRState *yys = yystates[0];
-]b4_location_if([[ yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;]]
-)[ yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[);
- yystates[0] = yys->yypred;
- yystack.yynextFree -= 1;
- yystack.yyspaceLeft += 1;
- }
+ {
+ size_t yysize = yystack.yytops.yysize;
+ size_t yyk;
+ for (yyk = 0; yyk < yysize; yyk += 1)
+ if (yystates[yyk])
+ {
+ while (yystates[yyk])
+ {
+ yyGLRState *yys = yystates[yyk];
+]b4_location_if([[ yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;]]
+)[ yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[);
+ yystates[yyk] = yys->yypred;
+ yystack.yynextFree -= 1;
+ yystack.yyspaceLeft += 1;
+ }
+ break;
+ }
+ }
yyfreeGLRStack (&yystack);
}
m4_if(b4_defines_flag, 0, [],
[@output @output_header_name@
b4_copyright([Skeleton parser for GLR parsing with Bison],
- [2002, 2003, 2004, 2005])
+ [2002, 2003, 2004, 2005])[
+
+/* As a special exception, when this parser skeleton is copied by
+ Bison into a Bison output file, you may use that output file
+ without restriction. This special exception was added by the Free
+ Software Foundation for C GLR parsers in version 2.2 of Bison. */
+
+/* C GLR parser skeleton written by Paul Hilfinger. */
+]
b4_shared_declarations