]> git.saurik.com Git - bison.git/blobdiff - data/lalr1.java
examples: improve the output of the "variant" example
[bison.git] / data / lalr1.java
index 0140a68362d397aeee9d22dd2d1dd605b6932ec2..d137ed814b9eddee6ce11ea08f949b2872686bf6 100644 (file)
@@ -1,6 +1,6 @@
 # Java skeleton for Bison -*- autoconf -*-
 
-# Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+# Copyright (C) 2007-2013 Free Software Foundation, Inc.
 
 # 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
@@ -20,7 +20,8 @@ m4_include(b4_pkgdatadir/[java.m4])
 b4_defines_if([b4_fatal([%s: %%defines does not make sense in Java],
               [b4_skeleton])])
 
-# We don't depend on %debug in Java, but pacify warnings about non-used flags.
+# We do not depend on %debug in Java, but pacify warnings about
+# non-used flags.
 b4_parse_trace_if([0], [0])
 
 m4_define([b4_symbol_no_destructor_assert],
@@ -30,10 +31,60 @@ m4_define([b4_symbol_no_destructor_assert],
                         [b4_symbol_action_location([$1], [destructor])])])])
 b4_symbol_foreach([b4_symbol_no_destructor_assert])
 
-m4_divert_push(0)dnl
-@output(b4_parser_file_name@)@
+# Setup some macros for api.push-pull.
+b4_percent_define_default([[api.push-pull]], [[pull]])
+b4_percent_define_check_values([[[[api.push-pull]],
+                                 [[pull]], [[push]], [[both]]]])
+
+# Define m4 conditional macros that encode the value
+# of the api.push-pull flag.
+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]]),
+        [pull], [m4_define([b4_push_flag], [[0]])],
+        [push], [m4_define([b4_pull_flag], [[0]])])
+
+# Define a macro to be true when api.push-pull has the value "both".
+m4_define([b4_both_if],[b4_push_if([b4_pull_if([$1],[$2])],[$2])])
+
+# Handle BISON_USE_PUSH_FOR_PULL for the test suite.  So that push parsing
+# tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the
+# behavior of Bison at all when push parsing is already requested.
+b4_define_flag_if([use_push_for_pull])
+b4_use_push_for_pull_if([
+  b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
+             [m4_define([b4_push_flag], [[1]])])])
+
+# Define a macro to encapsulate the parse state variables.
+# This allows them to be defined either in parse() when doing
+# pull parsing, or as class instance variable when doing push parsing.
+m4_define([b4_define_state],[[
+    /* Lookahead and lookahead in internal form.  */
+    int yychar = yyempty_;
+    int yytoken = 0;
+
+    /* State.  */
+    int yyn = 0;
+    int yylen = 0;
+    int yystate = 0;
+    YYStack yystack = new YYStack ();
+    int label = YYNEWSTATE;
+
+    /* Error handling.  */
+    int yynerrs_ = 0;
+    ]b4_locations_if([/* The location where the error started.  */
+    b4_location_type yyerrloc = null;
+
+    /* Location. */
+    b4_location_type yylloc = new b4_location_type (null, null);])[
+
+    /* Semantic value of the lookahead.  */
+    ]b4_yystype[ yylval = null;
+]])
+
+b4_output_begin([b4_parser_file_name])
 b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
-             [2007, 2008])
+             [2007-2013])
 
 b4_percent_define_ifdef([package], [package b4_percent_define_get([package]);
 ])[/* First part of user declarations.  */
@@ -56,7 +107,9 @@ b4_percent_define_get3([implements], [ implements ])[
 {
   ]b4_identification[
 ]b4_error_verbose_if([[
-  /** True if verbose error messages are enabled.  */
+  /**
+   * True if verbose error messages are enabled.
+   */
   private boolean yyErrorVerbose = true;
 
   /**
@@ -77,18 +130,24 @@ b4_locations_if([[
    * A class defining a pair of positions.  Positions, defined by the
    * <code>]b4_position_type[</code> class, denote a point in the input.
    * Locations represent a part of the input through the beginning
-   * and ending positions.  */
+   * and ending positions.
+   */
   public class ]b4_location_type[ {
-    /** The first, inclusive, position in the range.  */
+    /**
+     * The first, inclusive, position in the range.
+     */
     public ]b4_position_type[ begin;
 
-    /** The first position beyond the range.  */
+    /**
+     * The first position beyond the range.
+     */
     public ]b4_position_type[ end;
 
     /**
      * Create a <code>]b4_location_type[</code> denoting an empty range located at
      * a given point.
-     * @@param loc The position at which the range is anchored.  */
+     * @@param loc The position at which the range is anchored.
+     */
     public ]b4_location_type[ (]b4_position_type[ loc) {
       this.begin = this.end = loc;
     }
@@ -96,7 +155,8 @@ b4_locations_if([[
     /**
      * Create a <code>]b4_location_type[</code> from the endpoints of the range.
      * @@param begin The first position included in the range.
-     * @@param end   The first position beyond the range.  */
+     * @@param end   The first position beyond the range.
+     */
     public ]b4_location_type[ (]b4_position_type[ begin, ]b4_position_type[ end) {
       this.begin = begin;
       this.end = end;
@@ -105,7 +165,8 @@ b4_locations_if([[
     /**
      * Print a representation of the location.  For this to be correct,
      * <code>]b4_position_type[</code> should override the <code>equals</code>
-     * method.  */
+     * method.
+     */
     public String toString () {
       if (begin.equals (end))
         return begin.toString ();
@@ -120,7 +181,7 @@ b4_locations_if([[
   private ]b4_location_type[ yylloc (YYStack rhs, int n)
   {
     if (n > 0)
-      return new ]b4_location_type[ (rhs.locationAt (1).begin, rhs.locationAt (n).end);
+      return new ]b4_location_type[ (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
     else
       return new ]b4_location_type[ (rhs.locationAt (0).end);
   }]])[
@@ -133,28 +194,32 @@ b4_locations_if([[
     /** Token returned by the scanner to signal the end of its input.  */
     public static final int EOF = 0;
 
-]b4_token_enums(b4_tokens)[
+]b4_token_enums[
 
     ]b4_locations_if([[/**
      * Method to retrieve the beginning position of the last scanned token.
-     * @@return the position at which the last scanned token starts.  */
+     * @@return the position at which the last scanned token starts.
+     */
     ]b4_position_type[ getStartPos ();
 
     /**
      * Method to retrieve the ending position of the last scanned token.
-     * @@return the first position beyond the last scanned token.  */
+     * @@return the first position beyond the last scanned token.
+     */
     ]b4_position_type[ getEndPos ();]])[
 
     /**
      * Method to retrieve the semantic value of the last scanned token.
-     * @@return the semantic value of the last scanned token.  */
+     * @@return the semantic value of the last scanned token.
+     */
     ]b4_yystype[ getLVal ();
 
     /**
      * Entry point for the scanner.  Returns the token identifier corresponding
      * to the next token and prepares to return the semantic value
      * ]b4_locations_if([and beginning/ending positions ])[of the token.
-     * @@return the token identifier corresponding to the next token. */
+     * @@return the token identifier corresponding to the next token.
+     */
     int yylex () ]b4_maybe_throws([b4_lex_throws])[;
 
     /**
@@ -163,7 +228,8 @@ b4_locations_if([[
      *
      * ]b4_locations_if([[@@param loc The location of the element to which the
      *                error message is related]])[
-     * @@param msg The string for the error message.  */
+     * @@param msg The string for the error message.
+     */
      void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);]
   }
 
@@ -171,7 +237,9 @@ b4_locations_if([[
 ]b4_percent_code_get([[lexer]])[
   }
 
-  ]])[/** The object doing lexical analysis for us.  */
+  ]])[/**
+   * The object doing lexical analysis for us.
+   */
   private Lexer yylexer;
   ]
   b4_parse_param_vars
@@ -297,14 +365,14 @@ b4_lexer_if([[
     }
 
     public final void pop () {
-      height--;
+      pop (1);
     }
 
     public final void pop (int num) {
       // Avoid memory leaks... garbage collection is a white lie!
       if (num > 0) {
-        java.util.Arrays.fill (valueStack, height - num + 1, height, null);
-        ]b4_locations_if([[java.util.Arrays.fill (locStack, height - num + 1, height, null);]])[
+        java.util.Arrays.fill (valueStack, height - num + 1, height + 1, null);
+        ]b4_locations_if([[java.util.Arrays.fill (locStack, height - num + 1, height + 1, null);]])[
       }
       height -= num;
     }
@@ -326,7 +394,7 @@ b4_lexer_if([[
     {
       out.print ("Stack now");
 
-      for (int i = 0; i < height; i++)
+      for (int i = 0; i <= height; i++)
         {
           out.print (' ');
           out.print (stateStack[i]);
@@ -337,36 +405,49 @@ b4_lexer_if([[
 
   /**
    * Returned by a Bison action in order to stop the parsing process and
-   * return success (<tt>true</tt>).  */
+   * return success (<tt>true</tt>).
+   */
   public static final int YYACCEPT = 0;
 
   /**
    * Returned by a Bison action in order to stop the parsing process and
-   * return failure (<tt>false</tt>).  */
+   * return failure (<tt>false</tt>).
+   */
   public static final int YYABORT = 1;
 
+]b4_push_if([
+  /**
+   * Returned by a Bison action in order to request a new token.
+   */
+  public static final int YYPUSH_MORE = 4;])[
+
   /**
    * Returned by a Bison action in order to start error recovery without
-   * printing an error message.  */
+   * printing an error message.
+   */
   public static final int YYERROR = 2;
 
   /**
-   * Returned by a Bison action in order to print an error message and start
-   * error recovery.  */
-  public static final int YYFAIL = 3;
-
+   * Internal return codes that are not supported for user semantic
+   * actions.
+   */
+  private static final int YYERRLAB = 3;
   private static final int YYNEWSTATE = 4;
   private static final int YYDEFAULT = 5;
   private static final int YYREDUCE = 6;
   private static final int YYERRLAB1 = 7;
   private static final int YYRETURN = 8;
+]b4_push_if([[  private static final int YYGETTOKEN = 9; /* Signify that a new token is expected when doing push-parsing.  */]])[
 
   private int yyerrstatus_ = 0;
 
+]b4_push_if([dnl
+b4_define_state])[
   /**
    * Return whether error recovery is being done.  In this state, the parser
    * reads token until it reaches a known state, and then restarts normal
-   * operation.  */
+   * operation.
+   */
   public final boolean recovering ()
   {
     return yyerrstatus_ == 0;
@@ -378,7 +459,7 @@ b4_lexer_if([[
     ]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[
 
     /* If YYLEN is nonzero, implement the default value of the action:
-       `$$ = $1'.  Otherwise, use the top of the stack.
+       '$$ = $1'.  Otherwise, use the top of the stack.
 
        Otherwise, the following line sets YYVAL to garbage.
        This behavior is undocumented and Bison
@@ -466,6 +547,7 @@ b4_lexer_if([[
               + (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")");
   }
 
+]b4_push_if([],[[
   /**
    * Parse input from the scanner that was specified at object construction
    * time.  Return whether the end of the input was reached successfully.
@@ -473,50 +555,53 @@ b4_lexer_if([[
    * @@return <tt>true</tt> if the parsing succeeds.  Note that this does not
    *          imply that there were no syntax errors.
    */
-  public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
+   public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[]])[
+]b4_push_if([
+  /**
+   * Push Parse input from external lexer
+   *
+   * @@param yylextoken current token
+   * @@param yylexval current lval
+]b4_locations_if([   * @@param yylexloc current position])[
+   *
+   * @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
+   */
+  public int push_parse (int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4_location_type yylexloc]))
+      b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])])[
   {
-    /// Lookahead and lookahead in internal form.
-    int yychar = yyempty_;
-    int yytoken = 0;
-
-    /* State.  */
-    int yyn = 0;
-    int yylen = 0;
-    int yystate = 0;
-
-    YYStack yystack = new YYStack ();
-
-    /* Error handling.  */
-    int yynerrs_ = 0;
-    ]b4_locations_if([/// The location where the error started.
-    ]b4_location_type[ yyerrloc = null;
-
-    /// ]b4_location_type[ of the lookahead.
-    ]b4_location_type[ yylloc = new ]b4_location_type[ (null, null);
-
-    /// @@$.
-    ]b4_location_type[ yyloc;])
-
-    /// Semantic value of the lookahead.
-    b4_yystype[ yylval = null;
-
-    int yyresult;
-
+    ]b4_locations_if([/* @@$.  */
+    b4_location_type yyloc;])[
+]b4_push_if([],[[
+]b4_define_state[
     yycdebug ("Starting parse\n");
     yyerrstatus_ = 0;
 
+    /* Initialize the stack.  */
+    yystack.push (yystate, yylval ]b4_locations_if([, yylloc])[);
 ]m4_ifdef([b4_initial_action], [
-m4_pushdef([b4_at_dollar],     [yylloc])dnl
-m4_pushdef([b4_dollar_dollar], [yylval])dnl
+b4_dollar_pushdef([yylval], [], [yylloc])dnl
     /* User initialization code.  */
     b4_user_initial_action
-m4_popdef([b4_dollar_dollar])dnl
-m4_popdef([b4_at_dollar])])dnl
-
-  [  /* Initialize the stack.  */
-    yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
-
-    int label = YYNEWSTATE;
+b4_dollar_popdef[]dnl
+])[
+]])[
+]b4_push_if([[
+    if (!this.push_parse_initialized)
+      {
+        push_parse_initialize ();
+]m4_ifdef([b4_initial_action], [
+b4_dollar_pushdef([yylval], [], [yylloc])dnl
+    /* User initialization code.  */
+    b4_user_initial_action
+b4_dollar_popdef[]dnl
+])[
+        yycdebug ("Starting parse\n");
+        yyerrstatus_ = 0;
+      } else
+        label = YYGETTOKEN;
+
+    boolean push_token_consumed = true;
+]])[
     for (;;)
       switch (label)
       {
@@ -529,25 +614,37 @@ m4_popdef([b4_at_dollar])])dnl
 
         /* Accept?  */
         if (yystate == yyfinal_)
-          return true;
+          ]b4_push_if([{label = YYACCEPT; break;}],
+                      [return true;])[
 
         /* Take a decision.  First try without lookahead.  */
         yyn = yypact_[yystate];
-        if (yyn == yypact_ninf_)
+        if (yy_pact_value_is_default_ (yyn))
           {
             label = YYDEFAULT;
             break;
           }
+]b4_push_if([        /* Fall Through */
 
+      case YYGETTOKEN:])[
         /* Read a lookahead token.  */
         if (yychar == yyempty_)
           {
+]b4_push_if([[
+            if (!push_token_consumed)
+              return YYPUSH_MORE;
             yycdebug ("Reading a token: ");
-            yychar = yylexer.yylex ();]
-            b4_locations_if([[
-            yylloc = new ]b4_location_type[(yylexer.getStartPos (),
-                            yylexer.getEndPos ());]])
-            yylval = yylexer.getLVal ();[
+            yychar = yylextoken;
+            yylval = yylexval;]b4_locations_if([
+            yylloc = yylexloc;])[
+            push_token_consumed = false;]])[
+]b4_push_if([],[[
+            yycdebug ("Reading a token: ");
+            yychar = yylexer.yylex ();
+            yylval = yylexer.getLVal ();]b4_locations_if([
+            yylloc = new b4_location_type (yylexer.getStartPos (),
+                            yylexer.getEndPos ());])[
+]])[
           }
 
         /* Convert token to internal form.  */
@@ -572,8 +669,8 @@ m4_popdef([b4_at_dollar])])dnl
         /* <= 0 means reduce or error.  */
         else if ((yyn = yytable_[yyn]) <= 0)
           {
-            if (yyn == 0 || yyn == yytable_ninf_)
-              label = YYFAIL;
+            if (yy_table_value_is_error_ (yyn))
+              label = YYERRLAB;
             else
               {
                 yyn = -yyn;
@@ -607,7 +704,7 @@ m4_popdef([b4_at_dollar])])dnl
       case YYDEFAULT:
         yyn = yydefact_[yystate];
         if (yyn == 0)
-          label = YYFAIL;
+          label = YYERRLAB;
         else
           label = YYREDUCE;
         break;
@@ -624,11 +721,13 @@ m4_popdef([b4_at_dollar])])dnl
       /*------------------------------------.
       | yyerrlab -- here on detecting error |
       `------------------------------------*/
-      case YYFAIL:
+      case YYERRLAB:
         /* If not already recovering from an error, report this error.  */
         if (yyerrstatus_ == 0)
           {
             ++yynerrs_;
+            if (yychar == yyempty_)
+              yytoken = yyempty_;
             yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
           }
 
@@ -642,10 +741,10 @@ m4_popdef([b4_at_dollar])])dnl
           {
           /* Return failure if at end of input.  */
           if (yychar == Lexer.EOF)
-            return false;
+            ]b4_push_if([{label = YYABORT; break;}],[return false;])[
           }
         else
-              yychar = yyempty_;
+            yychar = yyempty_;
           }
 
         /* Else will try to reuse lookahead token after shifting the error
@@ -653,9 +752,9 @@ m4_popdef([b4_at_dollar])])dnl
         label = YYERRLAB1;
         break;
 
-      /*---------------------------------------------------.
+      /*-------------------------------------------------.
       | errorlab -- error raised explicitly by YYERROR.  |
-      `---------------------------------------------------*/
+      `-------------------------------------------------*/
       case YYERROR:
 
         ]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[
@@ -676,7 +775,7 @@ m4_popdef([b4_at_dollar])])dnl
         for (;;)
           {
             yyn = yypact_[yystate];
-            if (yyn != yypact_ninf_)
+            if (!yy_pact_value_is_default_ (yyn))
               {
                 yyn += yyterror_;
                 if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
@@ -687,9 +786,10 @@ m4_popdef([b4_at_dollar])])dnl
                   }
               }
 
-            /* Pop the current state because it cannot handle the error token.  */
-            if (yystack.height == 1)
-              return false;
+            /* Pop the current state because it cannot handle the
+             * error token.  */
+            if (yystack.height == 0)
+              ]b4_push_if([{label = YYABORT; break;}],[return false;])[
 
             ]b4_locations_if([yyerrloc = yystack.locationAt (0);])[
             yystack.pop ();
@@ -698,7 +798,11 @@ m4_popdef([b4_at_dollar])])dnl
               yystack.print (yyDebugStream);
           }
 
-        ]b4_locations_if([
+        if (label == YYABORT)
+            /* Leave the switch.  */
+            break;
+
+]b4_locations_if([
         /* Muck with the stack to setup for yylloc.  */
         yystack.push (0, null, yylloc);
         yystack.push (0, null, yyerrloc);
@@ -716,49 +820,157 @@ m4_popdef([b4_at_dollar])])dnl
 
         /* Accept.  */
       case YYACCEPT:
-        return true;
+        ]b4_push_if([this.push_parse_initialized = false; return YYACCEPT;],
+                    [return true;])[
 
         /* Abort.  */
       case YYABORT:
-        return false;
+        ]b4_push_if([this.push_parse_initialized = false; return YYABORT;],
+                    [return false;])[
       }
+}
+]b4_push_if([[
+  boolean push_parse_initialized = false;
+
+    /**
+     * (Re-)Initialize the state of the push parser.
+     */
+  public void push_parse_initialize()
+  {
+    /* Lookahead and lookahead in internal form.  */
+    this.yychar = yyempty_;
+    this.yytoken = 0;
+
+    /* State.  */
+    this.yyn = 0;
+    this.yylen = 0;
+    this.yystate = 0;
+    this.yystack = new YYStack ();
+    this.label = YYNEWSTATE;
+
+    /* Error handling.  */
+    this.yynerrs_ = 0;
+    ]b4_locations_if([/* The location where the error started.  */
+    this.yyerrloc = null;
+    this.yylloc = new b4_location_type (null, null);])[
+
+    /* Semantic value of the lookahead.  */
+    this.yylval = null;
+
+    yystack.push (this.yystate, this.yylval]b4_locations_if([, this.yylloc])[);
+
+    this.push_parse_initialized = true;
+
   }
+]b4_locations_if([
+  /**
+   * Push parse given input from an external lexer.
+   *
+   * @@param yylextoken current token
+   * @@param yylexval current lval
+   * @@param yyylexpos current position
+   *
+   * @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
+   */
+  public int push_parse (int yylextoken, b4_yystype yylexval, b4_position_type yylexpos)
+      b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])
+  {
+    return push_parse (yylextoken, yylexval, new b4_location_type (yylexpos));
+  }
+])[]])
+
+b4_both_if([[
+  /**
+   * Parse input from the scanner that was specified at object construction
+   * time.  Return whether the end of the input was reached successfully.
+   * This version of parse () is defined only when api.push-push=both.
+   *
+   * @@return <tt>true</tt> if the parsing succeeds.  Note that this does not
+   *          imply that there were no syntax errors.
+   */
+   public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
+   {
+      if (yylexer == null)
+        throw new NullPointerException("Null Lexer");
+      int status;
+      do {
+        int token = yylexer.yylex();
+        ]b4_yystype[ lval = yylexer.getLVal();
+]b4_locations_if([dnl
+        b4_location_type yyloc = new b4_location_type (yylexer.getStartPos (),
+                                              yylexer.getEndPos ());])[
+        ]b4_locations_if([status = push_parse(token,lval,yyloc);],[
+        status = push_parse(token,lval);])[
+      } while (status == YYPUSH_MORE);
+      return (status == YYACCEPT);
+  }
+]])[
 
   // Generate an error message.
   private String yysyntax_error (int yystate, int tok)
   {]b4_error_verbose_if([[
     if (yyErrorVerbose)
       {
-        int yyn = yypact_[yystate];
-        if (yypact_ninf_ < yyn && yyn <= yylast_)
+        /* There are many possibilities here to consider:
+           - If this state is a consistent state with a default action,
+             then the only way this function was invoked is if the
+             default action is an error action.  In that case, don't
+             check for expected tokens because there are none.
+           - The only way there can be no lookahead present (in tok) is
+             if this state is a consistent state with a default action.
+             Thus, detecting the absence of a lookahead is sufficient to
+             determine that there is no unexpected or expected token to
+             report.  In that case, just report a simple "syntax error".
+           - Don't assume there isn't a lookahead just because this
+             state is a consistent state with a default action.  There
+             might have been a previous inconsistent state, consistent
+             state with a non-default action, or user semantic action
+             that manipulated yychar.  (However, yychar is currently out
+             of scope during semantic actions.)
+           - Of course, the expected token list depends on states to
+             have correct lookahead information, and it depends on the
+             parser not to perform extra reductions after fetching a
+             lookahead from the scanner and before detecting a syntax
+             error.  Thus, state merging (from LALR or IELR) and default
+             reductions corrupt the expected token list.  However, the
+             list is correct for canonical LR with one exception: it
+             will still contain any token that will not be accepted due
+             to an error action in a later state.
+        */
+        if (tok != yyempty_)
           {
-            StringBuffer res;
-
-            /* Start YYX at -YYN if negative to avoid negative indexes in
-               YYCHECK.  */
-            int yyxbegin = yyn < 0 ? -yyn : 0;
-
-            /* Stay within bounds of both yycheck and yytname.  */
-            int yychecklim = yylast_ - yyn + 1;
-            int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
-            int count = 0;
-            for (int x = yyxbegin; x < yyxend; ++x)
-              if (yycheck_[x + yyn] == x && x != yyterror_)
-                ++count;
-
-            // FIXME: This method of building the message is not compatible
-            // with internationalization.
-            res = new StringBuffer ("syntax error, unexpected ");
+            /* FIXME: This method of building the message is not compatible
+               with internationalization.  */
+            StringBuffer res =
+              new StringBuffer ("syntax error, unexpected ");
             res.append (yytnamerr_ (yytname_[tok]));
-            if (count < 5)
+            int yyn = yypact_[yystate];
+            if (!yy_pact_value_is_default_ (yyn))
               {
-                count = 0;
+                /* Start YYX at -YYN if negative to avoid negative
+                   indexes in YYCHECK.  In other words, skip the first
+                   -YYN actions for this state because they are default
+                   actions.  */
+                int yyxbegin = yyn < 0 ? -yyn : 0;
+                /* Stay within bounds of both yycheck and yytname.  */
+                int yychecklim = yylast_ - yyn + 1;
+                int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
+                int count = 0;
                 for (int x = yyxbegin; x < yyxend; ++x)
-                  if (yycheck_[x + yyn] == x && x != yyterror_)
-                    {
-                      res.append (count++ == 0 ? ", expecting " : " or ");
-                      res.append (yytnamerr_ (yytname_[x]));
-                    }
+                  if (yycheck_[x + yyn] == x && x != yyterror_
+                      && !yy_table_value_is_error_ (yytable_[x + yyn]))
+                    ++count;
+                if (count < 5)
+                  {
+                    count = 0;
+                    for (int x = yyxbegin; x < yyxend; ++x)
+                      if (yycheck_[x + yyn] == x && x != yyterror_
+                          && !yy_table_value_is_error_ (yytable_[x + yyn]))
+                        {
+                          res.append (count++ == 0 ? ", expecting " : " or ");
+                          res.append (yytnamerr_ (yytname_[x]));
+                        }
+                  }
               }
             return res.toString ();
           }
@@ -767,20 +979,40 @@ m4_popdef([b4_at_dollar])])dnl
     return "syntax error";
   }
 
+  /**
+   * Whether the given <code>yypact_</code> value indicates a defaulted state.
+   * @@param yyvalue   the value to check
+   */
+  private static boolean yy_pact_value_is_default_ (int yyvalue)
+  {
+    return yyvalue == yypact_ninf_;
+  }
+
+  /**
+   * Whether the given <code>yytable_</code>
+   * value indicates a syntax error.
+   * @@param yyvalue the value to check
+   */
+  private static boolean yy_table_value_is_error_ (int yyvalue)
+  {
+    return yyvalue == yytable_ninf_;
+  }
+
   private static final ]b4_int_type_for([b4_pact])[ yypact_ninf_ = ]b4_pact_ninf[;
   private static final ]b4_int_type_for([b4_table])[ yytable_ninf_ = ]b4_table_ninf[;
 
   ]b4_parser_tables_define[
   ]b4_integral_parser_table_define([token_number], [b4_toknum],
-     [TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding
-     to YYLEX-NUM.])[
+     [[YYTOKEN_NUMBER[YYLEX-NUM] -- Internal symbol number corresponding
+   to YYLEX-NUM.]])[
 
   /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
      First, the terminals, then, starting at \a yyntokens_, nonterminals.  */
   ]b4_typed_parser_table_define([String], [tname], [b4_tname])[
 
   ]b4_integral_parser_table_define([rline], [b4_rline],
-  [YYRLINE[YYN] -- Source line where rule number YYN was defined.])[
+  [[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
+
 
   // Report on the debug stream that the rule yyrule is going to be reduced.
   private void yy_reduce_print (int yyrule, YYStack yystack)
@@ -797,7 +1029,7 @@ m4_popdef([b4_at_dollar])])dnl
     /* The symbols being reduced.  */
     for (int yyi = 0; yyi < yynrhs; yyi++)
       yy_symbol_print ("   $" + (yyi + 1) + " =",
-                       yystos_[yystack.stateAt(yyi + 1 - yynrhs)],
+                       yystos_[yystack.stateAt(yynrhs - (yyi + 1))],
                        ]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([,
                        b4_rhs_location(yynrhs, yyi + 1)])[);
   }
@@ -830,4 +1062,4 @@ b4_percent_code_get[]dnl
 }
 
 b4_epilogue[]dnl
-m4_divert_pop(0)dnl
+b4_output_end()