]> git.saurik.com Git - bison.git/blobdiff - data/glr.c
* src/parse-gram.y: Fix minor problems uncovered by lint.
[bison.git] / data / glr.c
index febed5796dda4f196a5526204eab60db02bd4940..b4077c9f58adfbe05f831f7a50fadeb6a2bd1e01 100644 (file)
@@ -36,8 +36,10 @@ m4_define_default([b4_stack_depth_init],  [200])
 
 # b4_user_formals
 # ---------------
-# This is specific to GLR because it relies on ISO C formal argument
-# declarations.
+# The possible parse-params formal arguments preceded by a comma.
+#
+# This is not shared with yacc.c in c.m4 because  GLR relies on ISO C
+# formal argument declarations.
 m4_define([b4_user_formals],
 [m4_ifset([b4_parse_param], [, b4_c_ansi_formals(b4_parse_param)])])
 
@@ -54,7 +56,8 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)))
 
 # b4_yyerror_args
 # ---------------
-# Arguments passed to yyerror: user args plus yylloc.
+# Optional effective arguments passed to yyerror: user args plus yylloc, and
+# a trailing comma.
 m4_define([b4_yyerror_args],
 [b4_pure_if([b4_location_if([yylocp, ])])dnl
 m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])])
@@ -70,18 +73,11 @@ m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])])
 
 # b4_pure_args
 # ------------
-# Arguments needed by yyerror: user args plus yylloc.
+# Same as b4_yyerror_args, but with a leading comma.
 m4_define([b4_pure_args],
 [b4_pure_if([b4_location_if([, yylocp])])[]b4_user_args])
 
 
-# b4_pure_formals
-# ---------------
-# Arguments passed to yyerror: user formals plus yyllocp.
-m4_define([b4_pure_formals],
-[b4_pure_if([b4_location_if([, YYLTYPE *yylocp])])[]b4_user_formals])
-
-
 # b4_lpure_args
 # -------------
 # Same as above, but on the look-ahead, hence yyllocp instead of yylocp.
@@ -89,6 +85,13 @@ m4_define([b4_lpure_args],
 [b4_pure_if([b4_location_if([, yyllocp])])[]b4_user_args])
 
 
+# b4_pure_formals
+# ---------------
+# Arguments passed to yyerror: user formals plus yyllocp.
+m4_define([b4_pure_formals],
+[b4_pure_if([b4_location_if([, YYLTYPE *yylocp])])[]b4_user_formals])
+
+
 # b4_lpure_formals
 # ----------------
 # Same as above, but on the look-ahead, hence yyllocp instead of yylocp.
@@ -113,7 +116,7 @@ m4_define([b4_lhs_value],
 # Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
 # symbols on RHS.
 m4_define([b4_rhs_value],
-[(((yyGLRStackItem const *)yyvsp)@{YYFILL (m4_eval([$2 - $1]))@}.yystate.yysemantics.yysval[]m4_ifval([$3], [.$3]))])
+[(((yyGLRStackItem const *)yyvsp)@{YYFILL (($2) - ($1))@}.yystate.yysemantics.yysval[]m4_ifval([$3], [.$3]))])
 
 
 
@@ -133,7 +136,13 @@ m4_define([b4_lhs_location],
 # Expansion of @NUM, where the current rule has RULE-LENGTH symbols
 # on RHS.
 m4_define([b4_rhs_location],
-[(((yyGLRStackItem const *)yyvsp)@{YYFILL (m4_eval([$2 - $1]))@}.yystate.yyloc)])
+[(((yyGLRStackItem const *)yyvsp)@{YYFILL (($2) - ($1))@}.yystate.yyloc)])
+
+
+
+## -------------- ##
+## Output files.  ##
+## -------------- ##
 
 # We do want M4 expansion after # for CPP macros.
 m4_changecom()
@@ -145,6 +154,7 @@ b4_copyright([Skeleton parser for GLR parsing with Bison],
 /* This is the parser code for GLR (Generalized LR) parser. */
 
 ]b4_identification
+
 m4_if(b4_prefix[], [yy], [],
 [/* Substitute the variable and function names.  */
 #define yyparse b4_prefix[]parse
@@ -154,30 +164,17 @@ m4_if(b4_prefix[], [yy], [],
 #define yychar  b4_prefix[]char
 #define yydebug b4_prefix[]debug
 #define yynerrs b4_prefix[]nerrs
-#define yylloc b4_prefix[]lloc])
+#define yylloc  b4_prefix[]lloc])
 
-b4_token_enums(b4_tokens)
+dnl # b4_shared_declarations
+dnl # ----------------------
+dnl # Declaration that might either go into the header (if --defines)
+dnl # or open coded in the parser body.
+m4_define([b4_shared_declarations],
+[b4_token_enums(b4_tokens)[
 
 /* Copy the first part of user declarations.  */
-b4_pre_prologue[
-
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG ]b4_debug[
-#endif
-
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE ]b4_error_verbose[
-#endif
-
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE ]b4_token_table[
-#endif
+]b4_pre_prologue[
 
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
 ]m4_ifdef([b4_stype],
@@ -205,6 +202,29 @@ typedef struct YYLTYPE
 # define YYLTYPE_IS_DECLARED 1
 # define YYLTYPE_IS_TRIVIAL 1
 #endif
+]])
+
+m4_if(b4_defines_flag, 0,
+      [b4_shared_declarations],
+      [#include @output_header_name@])[
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG ]b4_debug[
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE ]b4_error_verbose[
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE ]b4_token_table[
+#endif
 
 /* Default (constant) value used for initialization for null
    right-hand sides.  Unlike the standard yacc.c template,
@@ -237,7 +257,21 @@ b4_syncline([@oline@], [@ofile@])
 #endif
 
 /* Suppress unused-variable warnings by "using" E.  */
-#define YYUSE(e) do {;} while (/*CONSTCOND*/ yyfalse && (e))
+#ifndef lint
+# define YYUSE(e) ((void) (e))
+#else
+# 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
 # define YYFREE free
@@ -475,7 +509,7 @@ static const ]b4_int_type_for([b4_stos])[ yystos[] =
          (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
@@ -483,8 +517,8 @@ static const ]b4_int_type_for([b4_stos])[ yystos[] =
 
 # 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
@@ -520,7 +554,7 @@ typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
 
 #define YYCHK(YYE)                                                          \
    do { YYRESULTTAG yyflag = YYE; if (yyflag != yyok) return yyflag; }      \
-   while (/*CONSTCOND*/ 0)
+   while (YYID (0))
 
 #if YYDEBUG
 
@@ -532,7 +566,7 @@ typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
 do {                                           \
   if (yydebug)                                 \
     YYFPRINTF Args;                            \
-} while (/*CONSTCOND*/ 0)
+} while (YYID (0))
 
 ]b4_yysymprint_generate([b4_c_ansi_function_def])[
 
@@ -542,10 +576,10 @@ do {                                                                          \
     {                                                                      \
       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.  */
@@ -591,6 +625,21 @@ int yydebug;
 # endif
 #endif
 
+#if YYSTACKEXPANDABLE
+# define YY_RESERVE_GLRSTACK(Yystack)                  \
+  do {                                                 \
+    if (Yystack->yyspaceLeft < YYHEADROOM)             \
+      yyexpandGLRStack (Yystack);                      \
+  } while (YYID (0))
+#else
+# define YY_RESERVE_GLRSTACK(Yystack)                  \
+  do {                                                 \
+    if (Yystack->yyspaceLeft < YYHEADROOM)             \
+      yyMemoryExhausted (Yystack);                     \
+  } while (YYID (0))
+#endif
+
+
 #if YYERROR_VERBOSE
 
 # ifndef yystpcpy
@@ -748,7 +797,9 @@ struct yyGLRStack {
   yyGLRStateSet yytops;
 };
 
+#if YYSTACKEXPANDABLE
 static void yyexpandGLRStack (yyGLRStack* yystack);
+#endif
 
 static void yyFail (yyGLRStack* yystack]b4_pure_formals[, const char* yymsg)
   __attribute__ ((__noreturn__));
@@ -782,8 +833,7 @@ yytokenName (yySymbol yytoken)
 
 /** Fill in YYVSP[YYLOW1 .. YYLOW0-1] from the chain of states starting
  *  at YYVSP[YYLOW0].yystate.yypred.  Leaves YYVSP[YYLOW1].yystate.yypred
- *  containing the pointer to the next state in the chain. Assumes
- *  YYLOW1 < YYLOW0.  */
+ *  containing the pointer to the next state in the chain. */
 static void yyfillin (yyGLRStackItem *, int, int) __attribute__ ((__unused__));
 static void
 yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
@@ -802,8 +852,8 @@ yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
 }
 
 /* Do nothing if YYNORMAL or if *YYLOW <= YYLOW1.  Otherwise, fill in
  YYVSP[YYLOW1 .. *YYLOW-1] as in yyfillin and set *YYLOW = YYLOW1.
  For convenience, always return YYLOW1.  */
* YYVSP[YYLOW1 .. *YYLOW-1] as in yyfillin and set *YYLOW = YYLOW1.
* For convenience, always return YYLOW1.  */
 static inline int yyfill (yyGLRStackItem *, int *, int, yybool)
      __attribute__ ((__unused__));
 static inline int
@@ -822,18 +872,18 @@ yyfill (yyGLRStackItem *yyvsp, int *yylow, int yylow1, yybool yynormal)
  *  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);
   int yylow;
-
-# undef yyerrok
+]b4_parse_param_use[]dnl
+[# undef yyerrok
 # define yyerrok (yystack->yyerrState = 0)
 # undef YYACCEPT
 # define YYACCEPT return yyaccept
@@ -879,7 +929,7 @@ b4_syncline([@oline@], [@ofile@])
 }
 \f
 
-static void
+/*ARGSUSED*/ static void
 yyuserMerge (int yyn, YYSTYPE* yy0, YYSTYPE* yy1)
 {
   YYUSE (yy0);
@@ -922,15 +972,15 @@ yydestroyGLRState (char const *yymsg, yyGLRState *yys]b4_user_formals[)
 #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[);
+       }
     }
 }
 
@@ -942,9 +992,9 @@ yylhsNonterm (yyRuleNum yyrule)
 }
 
 #define yyis_pact_ninf(yystate) \
-  ]m4_if(m4_eval(b4_pact_ninf < b4_pact_min), 1,
-        0,
-        ((yystate) == YYPACT_NINF))[
+  ]m4_if(m4_eval(b4_pact_ninf < b4_pact_min), [1],
+        [0],
+        [((yystate) == YYPACT_NINF)])[
 
 /** True iff LR state STATE has only a default reduction (regardless
  *  of token). */
@@ -962,9 +1012,9 @@ yydefaultAction (yyStateNum yystate)
 }
 
 #define yyis_table_ninf(yytable_value) \
-  ]m4_if(m4_eval(b4_table_ninf < b4_table_min), 1,
-        0,
-        ((yytable_value) == YYTABLE_NINF))[
+  ]m4_if(m4_eval(b4_table_ninf < b4_table_min), [1],
+        [0],
+        [((yytable_value) == YYTABLE_NINF)])[
 
 /** Set *YYACTION to the action to take in YYSTATE on seeing YYTOKEN.
  *  Result R means
@@ -976,7 +1026,7 @@ yydefaultAction (yyStateNum yystate)
  */
 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)
@@ -1021,21 +1071,32 @@ yyisErrorAction (int yyaction)
 
                                /* GLRStates */
 
+/** Return a fresh GLRStackItem.  Callers should call
+ * YY_RESERVE_GLRSTACK afterwards to make sure there is sufficient
+ * headroom.  */
+
+static inline yyGLRStackItem*
+yynewGLRStackItem (yyGLRStack* yystack, yybool yyisState)
+{
+  yyGLRStackItem* yynewItem = yystack->yynextFree;
+  yystack->yyspaceLeft -= 1;
+  yystack->yynextFree += 1;
+  yynewItem->yystate.yyisState = yyisState;
+  return yynewItem;
+}
+
 static void
 yyaddDeferredAction (yyGLRStack* yystack, yyGLRState* yystate,
                     yyGLRState* rhs, yyRuleNum yyrule)
 {
-  yySemanticOption* yynewItem;
-  yynewItem = &yystack->yynextFree->yyoption;
-  yystack->yyspaceLeft -= 1;
-  yystack->yynextFree += 1;
-  yynewItem->yyisState = yyfalse;
-  yynewItem->yystate = rhs;
-  yynewItem->yyrule = yyrule;
-  yynewItem->yynext = yystate->yysemantics.yyfirstVal;
-  yystate->yysemantics.yyfirstVal = yynewItem;
-  if (yystack->yyspaceLeft < YYHEADROOM)
-    yyexpandGLRStack (yystack);
+  yySemanticOption* yynewOption =
+    &yynewGLRStackItem (yystack, yyfalse)->yyoption;
+  yynewOption->yystate = rhs;
+  yynewOption->yyrule = yyrule;
+  yynewOption->yynext = yystate->yysemantics.yyfirstVal;
+  yystate->yysemantics.yyfirstVal = yynewOption;
+
+  YY_RESERVE_GLRSTACK (yystack);
 }
 
                                /* GLRStacks */
@@ -1076,7 +1137,9 @@ yyinitGLRStack (yyGLRStack* yystack, size_t yysize)
   return yyinitStateSet (&yystack->yytops);
 }
 
-#define YYRELOC(YYFROMITEMS,YYTOITEMS,YYX,YYTYPE) \
+
+#if YYSTACKEXPANDABLE
+# define YYRELOC(YYFROMITEMS,YYTOITEMS,YYX,YYTYPE) \
   &((YYTOITEMS) - ((YYFROMITEMS) - (yyGLRStackItem*) (YYX)))->YYTYPE
 
 /** If STACK is expandable, extend it.  WARNING: Pointers into the
@@ -1087,7 +1150,6 @@ yyinitGLRStack (yyGLRStack* yystack, size_t yysize)
 static void
 yyexpandGLRStack (yyGLRStack* yystack)
 {
-#if YYSTACKEXPANDABLE
   yyGLRStackItem* yynewItems;
   yyGLRStackItem* yyp0, *yyp1;
   size_t yysize, yynewSize;
@@ -1140,11 +1202,8 @@ yyexpandGLRStack (yyGLRStack* yystack)
   yystack->yyitems = yynewItems;
   yystack->yynextFree = yynewItems + yysize;
   yystack->yyspaceLeft = yynewSize - yysize;
-
-#else
-  yyMemoryExhausted (yystack);
-#endif
 }
+#endif
 
 static void
 yyfreeGLRStack (yyGLRStack* yystack)
@@ -1222,21 +1281,17 @@ yyglrShift (yyGLRStack* yystack, size_t yyk, yyStateNum yylrState,
            size_t yyposn,
            YYSTYPE yysval, YYLTYPE* yylocp)
 {
-  yyGLRStackItem* yynewItem;
+  yyGLRState* yynewState = &yynewGLRStackItem (yystack, yytrue)->yystate;
 
-  yynewItem = yystack->yynextFree;
-  yystack->yynextFree += 1;
-  yystack->yyspaceLeft -= 1;
-  yynewItem->yystate.yyisState = yytrue;
-  yynewItem->yystate.yylrState = yylrState;
-  yynewItem->yystate.yyposn = yyposn;
-  yynewItem->yystate.yyresolved = yytrue;
-  yynewItem->yystate.yypred = yystack->yytops.yystates[yyk];
-  yystack->yytops.yystates[yyk] = &yynewItem->yystate;
-  yynewItem->yystate.yysemantics.yysval = yysval;
-  yynewItem->yystate.yyloc = *yylocp;
-  if (yystack->yyspaceLeft < YYHEADROOM)
-    yyexpandGLRStack (yystack);
+  yynewState->yylrState = yylrState;
+  yynewState->yyposn = yyposn;
+  yynewState->yyresolved = yytrue;
+  yynewState->yypred = yystack->yytops.yystates[yyk];
+  yynewState->yysemantics.yysval = yysval;
+  yynewState->yyloc = *yylocp;
+  yystack->yytops.yystates[yyk] = yynewState;
+
+  YY_RESERVE_GLRSTACK (yystack);
 }
 
 /** Shift stack #K of YYSTACK, to a new state corresponding to LR
@@ -1246,19 +1301,17 @@ static inline void
 yyglrShiftDefer (yyGLRStack* yystack, size_t yyk, yyStateNum yylrState,
                 size_t yyposn, yyGLRState* rhs, yyRuleNum yyrule)
 {
-  yyGLRStackItem* yynewItem;
+  yyGLRState* yynewState = &yynewGLRStackItem (yystack, yytrue)->yystate;
 
-  yynewItem = yystack->yynextFree;
-  yynewItem->yystate.yyisState = yytrue;
-  yynewItem->yystate.yylrState = yylrState;
-  yynewItem->yystate.yyposn = yyposn;
-  yynewItem->yystate.yyresolved = yyfalse;
-  yynewItem->yystate.yypred = yystack->yytops.yystates[yyk];
-  yynewItem->yystate.yysemantics.yyfirstVal = NULL;
-  yystack->yytops.yystates[yyk] = &yynewItem->yystate;
-  yystack->yynextFree += 1;
-  yystack->yyspaceLeft -= 1;
-  yyaddDeferredAction (yystack, &yynewItem->yystate, rhs, yyrule);
+  yynewState->yylrState = yylrState;
+  yynewState->yyposn = yyposn;
+  yynewState->yyresolved = yyfalse;
+  yynewState->yypred = yystack->yytops.yystates[yyk];
+  yynewState->yysemantics.yyfirstVal = NULL;
+  yystack->yytops.yystates[yyk] = yynewState;
+
+  /* Invokes YY_RESERVE_GLRSTACK. */
+  yyaddDeferredAction (yystack, yynewState, rhs, yyrule);
 }
 
 /** Pop the symbols consumed by reduction #RULE from the top of stack
@@ -1286,11 +1339,18 @@ yydoAction (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
     }
   else
     {
+      /* At present, doAction is never called in nondeterministic
+       * mode, so this branch is never taken.  It is here in
+       * anticipation of a future feature that will allow immediate
+       * evaluation of selected actions in nondeterministic mode. */
       int yyi;
       yyGLRState* yys;
       yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
       yys = yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred
-       = yystack->yytops.yystates[yyk];
+       = yystack->yytops.yystates[yyk];]b4_location_if([[
+      if (yynrhs == 0)
+       /* Set default location. */
+       yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yys->yyloc;]])[
       for (yyi = 0; yyi < yynrhs; yyi += 1)
        {
          yys = yys->yypred;
@@ -1304,29 +1364,44 @@ yydoAction (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
 }
 
 #if !YYDEBUG
-# define YY_REDUCE_PRINT(K, Rule)
+# define YY_REDUCE_PRINT(Args)
 #else
-# define YY_REDUCE_PRINT(K, Rule)      \
+# define YY_REDUCE_PRINT(Args)         \
 do {                                   \
   if (yydebug)                         \
-    yy_reduce_print (K, Rule);         \
-} while (/*CONSTCOND*/ 0)
+    yy_reduce_print Args;              \
+} while (YYID (0))
 
 /*----------------------------------------------------------.
 | Report that the RULE is going to be reduced on stack #K.  |
 `----------------------------------------------------------*/
 
-static inline void
-yy_reduce_print (size_t yyk, yyRuleNum yyrule)
+/*ARGSUSED*/ static inline void
+yy_reduce_print (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
+                YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[)
 {
+  int yynrhs = yyrhsLength (yyrule);
+  yybool yynormal __attribute__ ((__unused__)) =
+    (yystack->yysplitPoint == NULL);
+  yyGLRStackItem* yyvsp = (yyGLRStackItem*) yystack->yytops.yystates[yyk];
+  int yylow = 1;
   int yyi;
-  YYFPRINTF (stderr, "Reducing stack %lu by rule %d (line %lu), ",
+  YYUSE (yyvalp);
+  YYUSE (yylocp);
+]b4_parse_param_use[]dnl
+[  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++)
-    YYFPRINTF (stderr, "%s ", yytokenName (yyrhs[yyi]));
-  YYFPRINTF (stderr, "-> %s\n", yytokenName (yyr1[yyrule]));
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      fprintf (stderr, "   $%d = ", yyi + 1);
+      yysymprint (stderr, yyrhs[yyprhs[yyrule] + yyi],
+                 &]b4_rhs_value(yynrhs, yyi + 1)[
+                 ]b4_location_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
+                 b4_user_args[);
+      fprintf (stderr, "\n");
+    }
 }
 #endif
 
@@ -1343,7 +1418,7 @@ yy_reduce_print (size_t yyk, yyRuleNum yyrule)
  */
 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;
 
@@ -1352,8 +1427,9 @@ yyglrReduce (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
       YYSTYPE yysval;
       YYLTYPE yyloc;
 
-      YY_REDUCE_PRINT (yyk, yyrule);
+      YY_REDUCE_PRINT ((yystack, yyk, yyrule, &yysval, &yyloc]b4_user_args[));
       YYCHK (yydoAction (yystack, yyk, yyrule, &yysval, &yyloc]b4_user_args[));
+      YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyrule], &yysval, &yyloc);
       yyglrShift (yystack, yyk,
                  yyLRgotoState (yystack->yytops.yystates[yyk]->yylrState,
                                 yylhsNonterm (yyrule)),
@@ -1557,14 +1633,17 @@ yyresolveStates (yyGLRState* yys, int yyn, yyGLRStack* yystack]b4_user_formals[)
 
 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;
 
   yynrhs = yyrhsLength (yyopt->yyrule);
   YYCHK (yyresolveStates (yyopt->yystate, yynrhs, yystack]b4_user_args[));
-  yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred = yyopt->yystate;
+  yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred = yyopt->yystate;]b4_location_if([[
+  if (yynrhs == 0)
+    /* Set default location. */
+    yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yyopt->yystate->yyloc;]])[
   return yyuserAction (yyopt->yyrule, yynrhs,
                       yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
                       yyvalp, yylocp, yystack]b4_user_args[);
@@ -1679,7 +1758,7 @@ yyresolveValue (yySemanticOption* yyoptionList, yyGLRStack* yystack,
              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;
            }
@@ -1758,7 +1837,7 @@ yycompressStack (yyGLRStack* yystack)
 
 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;
@@ -1811,16 +1890,7 @@ yyprocessOneStack (yyGLRStack* yystack, size_t yyk,
            }
 
          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",
@@ -1943,7 +2013,7 @@ yyreportSyntaxError (yyGLRStack* yystack,
 /* 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)
@@ -2048,7 +2118,7 @@ yyrecoverSyntaxError (yyGLRStack* yystack,
     default:                                                                \
       goto yybuglab;                                                        \
     }                                                                       \
-  } while (/*CONSTCOND*/ 0)
+  } while (YYID (0))
 
 
 /*----------.
@@ -2118,7 +2188,7 @@ b4_syncline([@oline@], [@ofile@])])dnl
          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))
@@ -2139,7 +2209,7 @@ b4_syncline([@oline@], [@ofile@])])dnl
                  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)
@@ -2167,14 +2237,59 @@ b4_syncline([@oline@], [@ofile@])])dnl
 
       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);
@@ -2220,7 +2335,7 @@ b4_syncline([@oline@], [@ofile@])])dnl
  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
@@ -2229,15 +2344,24 @@ b4_syncline([@oline@], [@ofile@])])dnl
     {
       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);
     }
 
@@ -2321,39 +2445,19 @@ b4_epilogue
 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])[
 
-b4_token_enums(b4_tokens)
+/* 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.  */
 
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-m4_ifdef([b4_stype],
-[b4_syncline([b4_stype_line], [b4_file_name])
-typedef union m4_bregexp(b4_stype, [^{], [YYSTYPE ])b4_stype YYSTYPE;
-/* Line __line__ of glr.c.  */
-b4_syncline([@oline@], [@ofile@])],
-[typedef int YYSTYPE;])
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
+/* C GLR parser skeleton written by Paul Hilfinger.  */
+]
 
-b4_pure_if([],
-[extern YYSTYPE b4_prefix[]lval;])
+b4_shared_declarations
 
-#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
-typedef struct YYLTYPE
-{
-b4_location_if([
-  int first_line;
-  int first_column;
-  int last_line;
-  int last_column;
-],[
-  char yydummy;
-])
-} YYLTYPE;
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
+extern YYSTYPE b4_prefix[]lval;
 
 b4_location_if([b4_pure_if([],
 [extern YYLTYPE b4_prefix[]lloc;])