X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/18d9185cae4c43684e4a2a134dd3090b55307586..455671735e6f4e9712c2f5ac1bc153b07b33e67b:/data/glr.c

diff --git a/data/glr.c b/data/glr.c
index 48eae8d5..e67573b6 100644
--- a/data/glr.c
+++ b/data/glr.c
@@ -979,7 +979,10 @@ yydestroyGLRState (char const *yymsg, yyGLRState *yys]b4_user_formals[)
 #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");
@@ -1666,9 +1669,14 @@ yypreference (yySemanticOption* y0, yySemanticOption* y1)
 }
 
 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[)
@@ -1678,22 +1686,15 @@ yyresolveStates (yyGLRState* yys, int yyn,
       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[)
@@ -1703,10 +1704,18 @@ yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystackp,
   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.  */
@@ -1717,13 +1726,13 @@ yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystackp,
   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
@@ -1774,12 +1783,9 @@ yyreportTree (yySemanticOption* yyx, int yyindent)
 }
 #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);
@@ -1792,20 +1798,79 @@ yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* 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;
@@ -1823,7 +1888,8 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp, YYSTYPE* yyvalp,
 	  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;
@@ -1848,29 +1914,39 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp, YYSTYPE* yyvalp,
     {
       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
@@ -2314,9 +2390,8 @@ b4_syncline([@oline@], [@ofile@])])dnl
 	{
 	  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:
@@ -2335,13 +2410,23 @@ b4_syncline([@oline@], [@ofile@])])dnl
 	     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
@@ -2351,7 +2436,7 @@ b4_syncline([@oline@], [@ofile@])])dnl
 	  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;
@@ -2367,18 +2452,8 @@ b4_syncline([@oline@], [@ofile@])])dnl
 			  (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"));