]> git.saurik.com Git - bison.git/blobdiff - data/lalr1.java
java: fix parser stack popping bug.
[bison.git] / data / lalr1.java
index c156e5e7b2a1bf9fba65b5be0e646826a01e9c23..e1b488c48690a525ab1510d3a340222b5e6f3579 100644 (file)
@@ -1,6 +1,6 @@
 # Java skeleton for Bison -*- autoconf -*-
 
-# Copyright (C) 2007-2010 Free Software Foundation, Inc.
+# Copyright (C) 2007-2011 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
@@ -33,7 +33,7 @@ b4_symbol_foreach([b4_symbol_no_destructor_assert])
 m4_divert_push(0)dnl
 @output(b4_parser_file_name@)@
 b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
-             [2007-2010])
+             [2007-2011])
 
 b4_percent_define_ifdef([package], [package b4_percent_define_get([package]);
 ])[/* First part of user declarations.  */
@@ -120,7 +120,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);
   }]])[
@@ -303,7 +303,7 @@ b4_lexer_if([[
     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);
+        java.util.Arrays.fill (valueStack, height - num + 1, height + 1, null);
         ]b4_locations_if([[java.util.Arrays.fill (locStack, height - num + 1, height, null);]])[
       }
       height -= num;
@@ -627,6 +627,8 @@ m4_popdef([b4_at_dollar])])dnl
         if (yyerrstatus_ == 0)
           {
             ++yynerrs_;
+            if (yychar == yyempty_)
+              yytoken = yyempty_;
             yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
           }
 
@@ -727,39 +729,71 @@ m4_popdef([b4_at_dollar])])dnl
   {]b4_error_verbose_if([[
     if (yyErrorVerbose)
       {
-        int yyn = yypact_[yystate];
-        if (yypact_ninf_ < yyn && yyn <= yylast_)
+        /* There are many possibilities here to consider:
+           - Assume YYFAIL is not used.  It's too flawed to consider.
+             See
+             <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+             for details.  YYERROR is fine as it does not invoke this
+             function.
+           - 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.  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_
-                  && !yy_table_value_is_error_ (yytable_[x + yyn]))
-                ++count;
-
             // FIXME: This method of building the message is not compatible
             // with internationalization.
-            res = new StringBuffer ("syntax error, unexpected ");
+            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_
                       && !yy_table_value_is_error_ (yytable_[x + yyn]))
-                    {
-                      res.append (count++ == 0 ? ", expecting " : " or ");
-                      res.append (yytnamerr_ (yytname_[x]));
-                    }
+                    ++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 ();
           }