]> git.saurik.com Git - bison.git/blobdiff - data/yacc.c
portability: fix pointer arithmetic to conform to C standard.
[bison.git] / data / yacc.c
index 163ecfef6a64db6c5be7f4f78ffdc32a9e8c2220..5efef5f85e7b5b041c4cbcadfe7387e1ade758ab 100644 (file)
@@ -1,12 +1,11 @@
                                                              -*- C -*-
 # Yacc compatible skeleton for Bison
 
-# Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-# 2007, 2008, 2009 Free Software Foundation, Inc.
+# Copyright (C) 1984, 1989-1990, 2000-2010 Free Software Foundation,
+# Inc.
 
 m4_pushdef([b4_copyright_years],
-           [1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-            2007, 2008, 2009])
+           [1984, 1989-1990, 2000-2010])
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -24,7 +23,7 @@ m4_pushdef([b4_copyright_years],
 # Check the value of %define api.push-pull.
 b4_percent_define_default([[api.push-pull]], [[pull]])
 b4_percent_define_check_values([[[[api.push-pull]],
-                               [[pull]], [[push]], [[both]]]])
+                                 [[pull]], [[push]], [[both]]]])
 b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
 b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
 m4_case(b4_percent_define_get([[api.push-pull]]),
@@ -148,6 +147,68 @@ m4_define([b4_rhs_location],
           [(yylsp@{b4_subtract([$2], [$1])@})])
 
 
+## ------------------ ##
+## Parser variables.  ##
+## ------------------ ##
+
+# b4_declare_scanner_communication_variables
+# ------------------------------------------
+# Declare the variables that are global, or local to YYPARSE if
+# pure-parser.
+m4_define([b4_declare_scanner_communication_variables], [[
+/* The lookahead symbol.  */
+int yychar;
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval;]b4_locations_if([[
+
+/* Location data for the lookahead symbol.  */
+YYLTYPE yylloc;]])b4_pure_if([], [[
+
+/* Number of syntax errors so far.  */
+int yynerrs;]])])
+
+
+# b4_declare_parser_state_variables
+# ---------------------------------
+# Declare all the variables that are needed to maintain the parser state
+# between calls to yypush_parse.
+m4_define([b4_declare_parser_state_variables], [b4_pure_if([[
+    /* Number of syntax errors so far.  */
+    int yynerrs;
+]])[
+    int yystate;
+    /* Number of tokens to shift before error messages enabled.  */
+    int yyerrstatus;
+
+    /* The stacks and their tools:
+       `yyss': related to states.
+       `yyvs': related to semantic values.]b4_locations_if([[
+       `yyls': related to locations.]])[
+
+       Refer to the stacks thru separate pointers, to allow yyoverflow
+       to reallocate them elsewhere.  */
+
+    /* The state stack.  */
+    yytype_int16 yyssa[YYINITDEPTH];
+    yytype_int16 *yyss;
+    yytype_int16 *yyssp;
+
+    /* The semantic value stack.  */
+    YYSTYPE yyvsa[YYINITDEPTH];
+    YYSTYPE *yyvs;
+    YYSTYPE *yyvsp;]b4_locations_if([[
+
+    /* The location stack.  */
+    YYLTYPE yylsa[YYINITDEPTH];
+    YYLTYPE *yyls;
+    YYLTYPE *yylsp;
+
+    /* The locations where the error started and ended.  */
+    YYLTYPE yyerror_range[3];]])[
+
+    YYSIZE_T yystacksize;]])
+
 
 ## --------------------------------------------------------- ##
 ## Defining symbol actions, e.g., printers and destructors.  ##
@@ -172,14 +233,14 @@ b4_copyright([Implementation for Bison's Yacc-like parsers in C])[
 ]b4_identification
 b4_percent_code_get([[top]])[]dnl
 m4_if(b4_prefix, [yy], [],
-[[/* Substitute the variable and function names.  */
-]b4_pull_if([[#define yyparse         ]b4_prefix[parse
-]])b4_push_if([[#define yypush_parse    ]b4_prefix[push_parse
-]b4_pull_if([[#define yypull_parse    ]b4_prefix[pull_parse
-]])[#define yypstate_new    ]b4_prefix[pstate_new
+[[/* Substitute the variable and function names.  */]b4_pull_if([[
+#define yyparse         ]b4_prefix[parse]])b4_push_if([[
+#define yypush_parse    ]b4_prefix[push_parse]b4_pull_if([[
+#define yypull_parse    ]b4_prefix[pull_parse]])[
+#define yypstate_new    ]b4_prefix[pstate_new
 #define yypstate_delete ]b4_prefix[pstate_delete
-#define yypstate        ]b4_prefix[pstate
-]])[#define yylex           ]b4_prefix[lex
+#define yypstate        ]b4_prefix[pstate]])[
+#define yylex           ]b4_prefix[lex
 #define yyerror         ]b4_prefix[error
 #define yylval          ]b4_prefix[lval
 #define yychar          ]b4_prefix[char
@@ -312,7 +373,7 @@ typedef short int yytype_int16;
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
@@ -547,9 +608,18 @@ static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
 
 /* Like YYERROR except do call yyerror.  This remains here temporarily
    to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  */
+   Once GCC version 2 has supplanted version 1, this can go.  However,
+   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
+   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+   discussed.  */
 
 #define YYFAIL         goto yyerrlab
+#if defined YYFAIL
+  /* This is here to suppress warnings from the GCC cpp's
+     -Wunused-macros.  Normally we don't worry about that warning, but
+     some users do, and we want to make it easy for users to remove
+     YYFAIL uses, which will produce warnings from Bison 2.5.  */
+#endif
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
@@ -559,7 +629,6 @@ do                                                          \
     {                                                          \
       yychar = (Token);                                                \
       yylval = (Value);                                                \
-      yytoken = YYTRANSLATE (yychar);                          \
       YYPOPSTACK (1);                                          \
       goto yybackup;                                           \
     }                                                          \
@@ -598,7 +667,7 @@ while (YYID (0))
            YYRHSLOC (Rhs, 0).last_column;                              \
        }                                                               \
     while (YYID (0))
-#endif
+#endif]b4_locations_if([[
 
 
 /* YY_LOCATION_PRINT -- Print the location on the stream.
@@ -606,7 +675,7 @@ while (YYID (0))
    we won't break user code: when these are the locations we know.  */
 
 #ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
 #  define YY_LOCATION_PRINT(File, Loc)                 \
      fprintf (File, "%d.%d-%d.%d",                     \
              (Loc).first_line, (Loc).first_column,     \
@@ -614,7 +683,14 @@ while (YYID (0))
 # else
 #  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
 # endif
-#endif
+#endif]], [[
+
+
+/* This macro is provided for backward compatibility. */
+
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif]])[
 
 
 /* YYLEX -- calling `yylex' with the right arguments.  */
@@ -827,26 +903,27 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # endif
 
-/* Copy into YYRESULT an error message about the unexpected token
-   YYTOKEN while in state YYSTATE.  Return the number of bytes copied,
-   including the terminating null byte.  If YYRESULT is null, do not
-   copy anything; just return the number of bytes that would be
-   copied.  As a special case, return 0 if an ordinary "syntax error"
-   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
-   size calculation.  */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yytoken)
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN while in state YYSTATE.
+
+   Return 0 if *YYMSG was successfully written.  Return 1 if an ordinary
+   "syntax error" message will suffice instead.  Return 2 if *YYMSG is
+   not large enough to hold the message.  In the last case, also set
+   *YYMSG_ALLOC to either (a) the required number of bytes or (b) zero
+   if the required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                int yystate, int yytoken)
 {
   int yyn = yypact[yystate];
 
   if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
+    return 1;
   else
     {
       YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
       YYSIZE_T yysize = yysize0;
       YYSIZE_T yysize1;
-      int yysize_overflow = 0;
       enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
       /* Internationalized format string. */
       const char *yyformat = 0;
@@ -880,11 +957,17 @@ yysyntax_error (char *yyresult, int yystate, int yytoken)
              }
            yyarg[yycount++] = yytname[yyx];
            yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-           yysize_overflow |= (yysize1 < yysize);
+           if (! (yysize <= yysize1
+                  && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+             {
+               /* Overflow.  */
+               *yymsg_alloc = 0;
+               return 2;
+             }
            yysize = yysize1;
          }
 
-        switch (yycount)
+      switch (yycount)
         {
 #define YYCASE_(N, S)                           \
           case N:                               \
@@ -899,116 +982,63 @@ yysyntax_error (char *yyresult, int yystate, int yytoken)
         }
 
       yysize1 = yysize + yystrlen (yyformat);
-      yysize_overflow |= (yysize1 < yysize);
+      if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+        {
+          /* Overflow.  */
+          *yymsg_alloc = 0;
+          return 2;
+        }
       yysize = yysize1;
 
-      if (yysize_overflow)
-       return YYSIZE_MAXIMUM;
+      if (*yymsg_alloc < yysize)
+        {
+          *yymsg_alloc = 2 * yysize;
+          if (! (yysize <= *yymsg_alloc
+                 && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+            *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+          return 2;
+        }
 
-      if (yyresult)
-       {
-         /* Avoid sprintf, as that infringes on the user's name space.
-            Don't have undefined behavior even if the translation
-            produced a string with the wrong number of "%s"s.  */
-         char *yyp = yyresult;
-         int yyi = 0;
-         while ((*yyp = *yyformat) != '\0')
-            if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
-              {
-                yyp += yytnamerr (yyp, yyarg[yyi++]);
-                yyformat += 2;
-              }
-            else
-              {
-                yyp++;
-                yyformat++;
-              }
-       }
-      return yysize;
+      /* Avoid sprintf, as that infringes on the user's name space.
+         Don't have undefined behavior even if the translation
+         produced a string with the wrong number of "%s"s.  */
+      {
+        char *yyp = *yymsg;
+        int yyi = 0;
+        while ((*yyp = *yyformat) != '\0')
+          if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+            {
+              yyp += yytnamerr (yyp, yyarg[yyi++]);
+              yyformat += 2;
+            }
+          else
+            {
+              yyp++;
+              yyformat++;
+            }
+      }
+      return 0;
     }
 }
 #endif /* YYERROR_VERBOSE */
 \f
 
-]b4_yydestruct_generate([b4_c_function_def])[
+]b4_yydestruct_generate([b4_c_function_def])b4_push_if([], [[
 
-]b4_push_if([],
-[[/* Prevent warnings from -Wmissing-prototypes.  */
+
+/* Prevent warnings from -Wmissing-prototypes.  */
 #ifdef YYPARSE_PARAM
 ]b4_c_function_decl([yyparse], [int],
-   [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])[
+                    [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])[
 #else /* ! YYPARSE_PARAM */
 ]b4_c_function_decl([yyparse], [int], b4_parse_param)[
-#endif /* ! YYPARSE_PARAM */]])
-
-m4_divert_push([KILL])# ======================== M4 code.
-# b4_declare_scanner_communication_variables
-# ------------------------------------------
-# Declare the variables that are global, or local to YYPARSE if
-# pure-parser.
-m4_define([b4_declare_scanner_communication_variables],
-[[/* The lookahead symbol.  */
-int yychar;
-
-/* The semantic value of the lookahead symbol.  */
-YYSTYPE yylval;
-]b4_locations_if([[
-/* Location data for the lookahead symbol.  */
-YYLTYPE yylloc;
-]])b4_pure_if([], [[
-/* Number of syntax errors so far.  */
-int yynerrs;
-]])])
-
-# b4_declare_parser_state_variables
-# ---------------------------------
-# Declare all the variables that are needed to maintain the parser state
-# between calls to yypush_parse.
-m4_define([b4_declare_parser_state_variables],
-[b4_pure_if([[    /* Number of syntax errors so far.  */
-    int yynerrs;
-]])[
-    int yystate;
-    /* Number of tokens to shift before error messages enabled.  */
-    int yyerrstatus;
-
-    /* The stacks and their tools:
-       `yyss': related to states.
-       `yyvs': related to semantic values.]b4_locations_if([[
-       `yyls': related to locations.]])[
-
-       Refer to the stacks thru separate pointers, to allow yyoverflow
-       to reallocate them elsewhere.  */
-
-    /* The state stack.  */
-    yytype_int16 yyssa[YYINITDEPTH];
-    yytype_int16 *yyss;
-    yytype_int16 *yyssp;
-
-    /* The semantic value stack.  */
-    YYSTYPE yyvsa[YYINITDEPTH];
-    YYSTYPE *yyvs;
-    YYSTYPE *yyvsp;
-]b4_locations_if([[
-    /* The location stack.  */
-    YYLTYPE yylsa[YYINITDEPTH];
-    YYLTYPE *yyls;
-    YYLTYPE *yylsp;
+#endif /* ! YYPARSE_PARAM */]])b4_pure_if([], [
 
-    /* The locations where the error started and ended.  */
-    YYLTYPE yyerror_range[2];
-]])[
-    YYSIZE_T yystacksize;
-]])
+b4_declare_scanner_communication_variables])[]b4_push_if([[
 
-m4_divert_pop([KILL])dnl# ====================== End of M4 code.
 
-b4_pure_if([], [b4_declare_scanner_communication_variables])
-
-b4_push_if(
-[[struct yypstate
-  {
-    ]b4_declare_parser_state_variables[
+struct yypstate
+  {]b4_declare_parser_state_variables[
     /* Used to determine if this is the first time this instance has
        been used.  */
     int yynew;
@@ -1080,44 +1110,53 @@ b4_c_function_def([[yyparse]], [[int]], b4_parse_param)[
   free (yyps);]b4_pure_if([], [[
   yypstate_allocated = 0;]])[
 }
-
-]b4_pure_if([[#define ]b4_prefix[nerrs yyps->]b4_prefix[nerrs
-]])[#define yystate yyps->yystate
+]b4_pure_if([[
+#define ]b4_prefix[nerrs yyps->]b4_prefix[nerrs]])[
+#define yystate yyps->yystate
 #define yyerrstatus yyps->yyerrstatus
 #define yyssa yyps->yyssa
 #define yyss yyps->yyss
 #define yyssp yyps->yyssp
 #define yyvsa yyps->yyvsa
 #define yyvs yyps->yyvs
-#define yyvsp yyps->yyvsp
-]b4_locations_if([[#define yylsa yyps->yylsa
+#define yyvsp yyps->yyvsp]b4_locations_if([[
+#define yylsa yyps->yylsa
 #define yyls yyps->yyls
 #define yylsp yyps->yylsp
-#define yyerror_range yyps->yyerror_range
-]])[#define yystacksize yyps->yystacksize
-]])[
-/*-------------------------.
-| yyparse or yypush_parse.  |
-`-------------------------*/
-]b4_push_if([
-b4_c_function_def([[yypush_parse]], [[int]],
+#define yyerror_range yyps->yyerror_range]])[
+#define yystacksize yyps->yystacksize
+
+
+/*---------------.
+| yypush_parse.  |
+`---------------*/
+
+]b4_c_function_def([[yypush_parse]], [[int]],
   [[[yypstate *yyps]], [[yyps]]]b4_pure_if([,
   [[[int yypushed_char]], [[yypushed_char]]],
   [[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([,
   [[[YYLTYPE const *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
-  b4_parse_param]))], [
+  b4_parse_param]))], [[
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
 #ifdef YYPARSE_PARAM
-b4_c_function_def([yyparse], [int], [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])
+]b4_c_function_def([yyparse], [int],
+                   [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])[
 #else /* ! YYPARSE_PARAM */
-b4_c_function_def([yyparse], [int], b4_parse_param)
-#endif])[
-{
-]b4_pure_if([b4_declare_scanner_communication_variables])
-b4_push_if([b4_pure_if([], [[  int yypushed_char = yychar;
-  YYSTYPE yypushed_val = yylval;
-  ]b4_locations_if([[YYLTYPE yypushed_loc = yylloc;
-]])])],
-  [b4_declare_parser_state_variables])[
+]b4_c_function_def([yyparse], [int], b4_parse_param)[
+#endif]])[
+{]b4_pure_if([b4_declare_scanner_communication_variables
+])b4_push_if([b4_pure_if([], [[
+  int yypushed_char = yychar;
+  YYSTYPE yypushed_val = yylval;]b4_locations_if([[
+  YYLTYPE yypushed_loc = yylloc;]])
+])],
+  [b4_declare_parser_state_variables
+])[
   int yyn;
   int yyresult;
   /* Lookahead token as an internal (translated) token number.  */
@@ -1167,7 +1206,7 @@ b4_push_if([b4_pure_if([], [[  int yypushed_char = yychar;
   yyvsp = yyvs;]b4_locations_if([[
   yylsp = yyls;
 
-#if YYLTYPE_IS_TRIVIAL
+#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
   /* Initialize the default location before parsing starts.  */
   yylloc.first_line   = yylloc.last_line   = ]b4_location_initial_line[;
   yylloc.first_column = yylloc.last_column = ]b4_location_initial_column[;
@@ -1388,6 +1427,17 @@ yyreduce:
       ]b4_user_actions[
       default: break;
     }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -1416,6 +1466,10 @@ yyreduce:
 | yyerrlab -- here on detecting error |
 `------------------------------------*/
 yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = YYTRANSLATE (yychar);
+
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -1423,41 +1477,32 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (]b4_yyerror_args[YY_("syntax error"));
 #else
-      {
-       YYSIZE_T yysize = yysyntax_error (0, yystate, yytoken);
-       if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
-         {
-           YYSIZE_T yyalloc = 2 * yysize;
-           if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
-             yyalloc = YYSTACK_ALLOC_MAXIMUM;
-           if (yymsg != yymsgbuf)
-             YYSTACK_FREE (yymsg);
-           yymsg = (char *) YYSTACK_ALLOC (yyalloc);
-           if (yymsg)
-             yymsg_alloc = yyalloc;
-           else
-             {
-               yymsg = yymsgbuf;
-               yymsg_alloc = sizeof yymsgbuf;
-             }
-         }
-
-       if (0 < yysize && yysize <= yymsg_alloc)
-         {
-           (void) yysyntax_error (yymsg, yystate, yytoken);
-           yyerror (]b4_yyerror_args[yymsg);
-         }
-       else
-         {
-           yyerror (]b4_yyerror_args[YY_("syntax error"));
-           if (yysize != 0)
-             goto yyexhaustedlab;
-         }
-      }
+      while (1)
+        {
+          int yysyntax_error_status =
+            yysyntax_error (&yymsg_alloc, &yymsg, yystate, yytoken);
+          if (yysyntax_error_status == 2 && 0 < yymsg_alloc)
+            {
+              if (yymsg != yymsgbuf)
+                YYSTACK_FREE (yymsg);
+              yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+              if (yymsg)
+                continue;
+              yymsg = yymsgbuf;
+              yymsg_alloc = sizeof yymsgbuf;
+            }
+          if (yysyntax_error_status == 0)
+            yyerror (]b4_yyerror_args[yymsg);
+          else
+            yyerror (]b4_yyerror_args[YY_("syntax error"));
+          if (yysyntax_error_status == 2)
+            goto yyexhaustedlab;
+          break;
+        }
 #endif
     }
 
-]b4_locations_if([[  yyerror_range[0] = yylloc;]])[
+]b4_locations_if([[  yyerror_range[1] = yylloc;]])[
 
   if (yyerrstatus == 3)
     {
@@ -1494,7 +1539,7 @@ yyerrorlab:
   if (/*CONSTCOND*/ 0)
      goto yyerrorlab;
 
-]b4_locations_if([[  yyerror_range[0] = yylsp[1-yylen];
+]b4_locations_if([[  yyerror_range[1] = yylsp[1-yylen];
 ]])[  /* Do not reclaim the symbols of the rule which action triggered
      this YYERROR.  */
   YYPOPSTACK (yylen);
@@ -1528,7 +1573,7 @@ yyerrlab1:
       if (yyssp == yyss)
        YYABORT;
 
-]b4_locations_if([[      yyerror_range[0] = *yylsp;]])[
+]b4_locations_if([[      yyerror_range[1] = *yylsp;]])[
       yydestruct ("Error: popping",
                  yystos[yystate], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
       YYPOPSTACK (1);
@@ -1538,10 +1583,10 @@ yyerrlab1:
 
   *++yyvsp = yylval;
 ]b4_locations_if([[
-  yyerror_range[1] = yylloc;
+  yyerror_range[2] = yylloc;
   /* Using YYLLOC is tempting, but would change the location of
      the lookahead.  YYLOC is available though.  */
-  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
+  YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
   *++yylsp = yyloc;]])[
 
   /* Shift the error token.  */
@@ -1577,8 +1622,13 @@ yyexhaustedlab:
 
 yyreturn:
   if (yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-                yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
+    }
   /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
@@ -1592,11 +1642,11 @@ yyreturn:
 #ifndef yyoverflow
   if (yyss != yyssa)
     YYSTACK_FREE (yyss);
-#endif
-]b4_push_if([[  yyps->yynew = 1;
+#endif]b4_push_if([[
+  yyps->yynew = 1;
 
-yypushreturn:
-]])[#if YYERROR_VERBOSE
+yypushreturn:]])[
+#if YYERROR_VERBOSE
   if (yymsg != yymsgbuf)
     YYSTACK_FREE (yymsg);
 #endif