#if YYDEBUG
if (yydebug)
{
- YYFPRINTF (stderr, "%s unresolved ", yymsg);
+ if (yys->yysemantics.yyfirstVal)
+ YYFPRINTF (stderr, "%s unresolved ", yymsg);
+ else
+ YYFPRINTF (stderr, "%s incomplete ", yymsg);
yy_symbol_print (stderr, yystos[yys->yylrState],
NULL]b4_location_if([, &yys->yyloc])[]b4_user_args[);
YYFPRINTF (stderr, "\n");
}
static YYRESULTTAG yyresolveValue (yyGLRState* yys,
- yyGLRStack* yystackp, YYSTYPE* yyvalp,
- YYLTYPE* yylocp]b4_user_formals[);
+ yyGLRStack* yystackp]b4_user_formals[);
+
+/** Resolve the previous N states starting at and including state S. If result
+ * != yyok, some states may have been left unresolved possibly with empty
+ * semantic option chains. Regardless of whether result = yyok, each state
+ * has been left with consistent data so that yydestroyGLRState can be invoked
+ * if necessary. */
static YYRESULTTAG
yyresolveStates (yyGLRState* yys, int yyn,
yyGLRStack* yystackp]b4_user_formals[)
YYASSERT (yys->yypred);
YYCHK (yyresolveStates (yys->yypred, yyn-1, yystackp]b4_user_args[));
if (! yys->yyresolved)
- {
- YYSTYPE yysval;
- YYRESULTTAG yyflag = yyresolveValue (yys, yystackp, &yysval,
- &yys->yyloc]b4_user_args[);
- if (yyflag != yyok)
- {
- yys->yysemantics.yyfirstVal = NULL;
- return yyflag;
- }
- yys->yysemantics.yysval = yysval;
- yys->yyresolved = yytrue;
- }
+ YYCHK (yyresolveValue (yys, yystackp]b4_user_args[));
}
return yyok;
}
+/** Resolve the states for the RHS of OPT, perform its user action, and return
+ * the semantic value and location. Regardless of whether result = yyok, all
+ * RHS states have been destroyed (assuming the user action destroys all RHS
+ * semantic values if invoked). */
static YYRESULTTAG
yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystackp,
YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[)
int yychar_current;
YYSTYPE yylval_current;
YYLTYPE yylloc_current;
- YYRESULTTAG yyresult;
+ YYRESULTTAG yyflag;
yynrhs = yyrhsLength (yyopt->yyrule);
- YYCHK (yyresolveStates (yyopt->yystate, yynrhs, yystackp]b4_user_args[));
+ yyflag = yyresolveStates (yyopt->yystate, yynrhs, yystackp]b4_user_args[);
+ if (yyflag != yyok)
+ {
+ yyGLRState *yys;
+ for (yys = yyopt->yystate; yynrhs > 0; yys = yys->yypred, yynrhs -= 1)
+ yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[);
+ return yyflag;
+ }
+
yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred = yyopt->yystate;]b4_location_if([[
if (yynrhs == 0)
/* Set default location. */
yychar = yyopt->yyrawchar;
yylval = yyopt->yyval;
yylloc = yyopt->yyloc;
- yyresult = yyuserAction (yyopt->yyrule, yynrhs,
+ yyflag = yyuserAction (yyopt->yyrule, yynrhs,
yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
yyvalp, yylocp, yystackp]b4_user_args[);
yychar = yychar_current;
yylval = yylval_current;
yylloc = yylloc_current;
- return yyresult;
+ return yyflag;
}
#if YYDEBUG
}
#endif
-static void yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1,
- yyGLRStack* yystackp]b4_pure_formals[)
- __attribute__ ((__noreturn__));
-/*ARGSUSED*/ static void
-yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1,
- yyGLRStack* yystackp]b4_pure_formals[)
+/*ARGSUSED*/ static YYRESULTTAG
+yyreportAmbiguity (yySemanticOption* yyx0,
+ yySemanticOption* yyx1]b4_pure_formals[)
{
YYUSE (yyx0);
YYUSE (yyx1);
yyreportTree (yyx1, 2);
YYFPRINTF (stderr, "\n");
#endif
- yyFail (yystackp][]b4_pure_args[, YY_("syntax is ambiguous"));
+
+ yyerror (]b4_yyerror_args[YY_("syntax is ambiguous"));
+ return yyabort;
}
+/** Starting at and including state S1, resolve the location for each of the
+ * previous N1 states that is unresolved. The first semantic option of a state
+ * is always chosen. */
+static void
+yyresolveLocations (yyGLRState* yys1, int yyn1,
+ yyGLRStack *yystackp]b4_user_formals[)
+{
+ if (0 < yyn1)
+ {
+ yyresolveLocations (yys1->yypred, yyn1 - 1, yystackp]b4_user_args[);
+ if (!yys1->yyresolved)
+ {
+ yySemanticOption *yyoption;
+ yyGLRStackItem yyrhsloc[1 + YYMAXRHS];
+ int yynrhs;
+ int yychar_current;
+ YYSTYPE yylval_current;
+ YYLTYPE yylloc_current;
+ yyoption = yys1->yysemantics.yyfirstVal;
+ YYASSERT (yyoption != NULL);
+ yynrhs = yyrhsLength (yyoption->yyrule);
+ if (yynrhs > 0)
+ {
+ yyGLRState *yys;
+ int yyn;
+ yyresolveLocations (yyoption->yystate, yynrhs,
+ yystackp]b4_user_args[);
+ for (yys = yyoption->yystate, yyn = yynrhs;
+ yyn > 0;
+ yys = yys->yypred, yyn -= 1)
+ yyrhsloc[yyn].yystate.yyloc = yys->yyloc;
+ }
+ else
+ {
+ yyGLRState *yyprevious = yyoption->yystate;
+ YYASSERT (yyprevious->yyresolved);
+ yyrhsloc[0].yystate.yyloc = yyprevious->yyloc;
+ }
+ yychar_current = yychar;
+ yylval_current = yylval;
+ yylloc_current = yylloc;
+ yychar = yyoption->yyrawchar;
+ yylval = yyoption->yyval;
+ yylloc = yyoption->yyloc;
+ YYLLOC_DEFAULT ((yys1->yyloc), yyrhsloc, yynrhs);
+ yychar = yychar_current;
+ yylval = yylval_current;
+ yylloc = yylloc_current;
+ }
+ }
+}
/** Resolve the ambiguity represented in state S, perform the indicated
- * actions, and return the result. */
+ * actions, and set the semantic value of S. If result != yyok, the chain of
+ * semantic options in S has been cleared instead or it has been left
+ * unmodified except that redundant options may have been removed. Regardless
+ * of whether result = yyok, S has been left with consistent data so that
+ * yydestroyGLRState can be invoked if necessary. */
static YYRESULTTAG
-yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp, YYSTYPE* yyvalp,
- YYLTYPE* yylocp]b4_user_formals[)
+yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
{
yySemanticOption* yyoptionList = yys->yysemantics.yyfirstVal;
yySemanticOption* yybest;
yySemanticOption** yypp;
yybool yymerge;
+ YYSTYPE yysval;
+ YYRESULTTAG yyflag;
+ YYLTYPE *yylocp = &yys->yyloc;
yybest = yyoptionList;
yymerge = yyfalse;
switch (yypreference (yybest, yyp))
{
case 0:
- yyreportAmbiguity (yybest, yyp, yystackp]b4_pure_args[);
+ yyresolveLocations (yys, 1, yystackp]b4_user_args[);
+ return yyreportAmbiguity (yybest, yyp]b4_pure_args[);
break;
case 1:
yymerge = yytrue;
{
yySemanticOption* yyp;
int yyprec = yydprec[yybest->yyrule];
- YYCHK (yyresolveAction (yybest, yystackp, yyvalp, yylocp]b4_user_args[));
- for (yyp = yybest->yynext; yyp != NULL; yyp = yyp->yynext)
- {
- if (yyprec == yydprec[yyp->yyrule])
- {
- YYSTYPE yyval1;
- YYLTYPE yydummy;
- YYRESULTTAG yyflag = yyresolveAction (yyp, yystackp, &yyval1,
- &yydummy]b4_user_args[);
- if (yyflag != yyok)
- {
- yydestruct ("Cleanup: discarding merged value",
- yystos[yys->yylrState],
- yyvalp]b4_location_if([, yylocp])[]b4_user_args[);
- return yyflag;
- }
- yyuserMerge (yymerger[yyp->yyrule], yyvalp, &yyval1);
- }
- }
- return yyok;
+ yyflag = yyresolveAction (yybest, yystackp, &yysval,
+ yylocp]b4_user_args[);
+ if (yyflag == yyok)
+ for (yyp = yybest->yynext; yyp != NULL; yyp = yyp->yynext)
+ {
+ if (yyprec == yydprec[yyp->yyrule])
+ {
+ YYSTYPE yysval_other;
+ YYLTYPE yydummy;
+ yyflag = yyresolveAction (yyp, yystackp, &yysval_other,
+ &yydummy]b4_user_args[);
+ if (yyflag != yyok)
+ {
+ yydestruct ("Cleanup: discarding incompletely merged value for",
+ yystos[yys->yylrState],
+ &yysval]b4_location_if([, yylocp])[]b4_user_args[);
+ break;
+ }
+ yyuserMerge (yymerger[yyp->yyrule], &yysval, &yysval_other);
+ }
+ }
}
else
- return yyresolveAction (yybest, yystackp, yyvalp, yylocp]b4_user_args[);
+ yyflag = yyresolveAction (yybest, yystackp, &yysval, yylocp]b4_user_args[);
+
+ if (yyflag == yyok)
+ {
+ yys->yyresolved = yytrue;
+ yys->yysemantics.yysval = yysval;
+ }
+ else
+ yys->yysemantics.yyfirstVal = NULL;
+ return yyflag;
}
static YYRESULTTAG
{
yySymbol yytoken_to_shift;
size_t yys;
- size_t yyn = yystack.yytops.yysize;
- for (yys = 0; yys < yyn; yys += 1)
+ for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
yystackp->yytops.yylookaheadNeeds[yys] = yychar != YYEMPTY;
/* yyprocessOneStack returns one of three things:
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
+ reductions on all stacks) helps prevent double destructor calls
on yylval in the event of memory exhaustion. */
- for (yys = 0; yys < yyn; yys += 1)
+ for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
YYCHK1 (yyprocessOneStack (&yystack, yys, yyposn]b4_lpure_args[));
yyremoveDeletes (&yystack);
- yyn = yystack.yytops.yysize;
+ if (yystack.yytops.yysize == 0)
+ {
+ yyundeleteLastStack (&yystack);
+ if (yystack.yytops.yysize == 0)
+ yyFail (&yystack][]b4_lpure_args[, YY_("syntax error"));
+ YYCHK1 (yyresolveStack (&yystack]b4_user_args[));
+ YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
+]b4_location_if([[ yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
+ yyreportSyntaxError (&yystack]b4_user_args[);
+ goto yyuser_error;
+ }
/* 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
yytoken_to_shift = YYTRANSLATE (yychar);
yychar = YYEMPTY;
yyposn += 1;
- for (yys = 0; yys < yyn; yys += 1)
+ for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
{
int yyaction;
const short int* yyconflicts;
(unsigned long int) yys,
yystack.yytops.yystates[yys]->yylrState));
}
- if (yystack.yytops.yysize == 0)
- {
- yyundeleteLastStack (&yystack);
- if (yystack.yytops.yysize == 0)
- yyFail (&yystack][]b4_lpure_args[, YY_("syntax error"));
- YYCHK1 (yyresolveStack (&yystack]b4_user_args[));
- YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
-]b4_location_if([[ yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
- yyreportSyntaxError (&yystack]b4_user_args[);
- goto yyuser_error;
- }
- else if (yystack.yytops.yysize == 1)
+
+ if (yystack.yytops.yysize == 1)
{
YYCHK1 (yyresolveStack (&yystack]b4_user_args[));
YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));