]> git.saurik.com Git - bison.git/blobdiff - data/lalr1.cc
lalr1.cc: don't discard non-existent lookahead on syntax error.
[bison.git] / data / lalr1.cc
index b0d14dc0e8c06ebf1c9fadca77510b0684fcc7fb..6174e824edeb507beb4d33f60ae74cbfbd6d7367 100644 (file)
@@ -1,6 +1,6 @@
 # C++ skeleton for Bison
 
 # C++ skeleton for Bison
 
-# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
 # Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
@@ -29,7 +29,7 @@ m4_define([b4_integral_parser_table_declare],
 ])
 
 # b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
 ])
 
 # b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
-# ---------------------------------------------
+# -------------------------------------------------------------
 # Define "parser::yy<TABLE-NAME>_" which contents is CONTENT.
 m4_define([b4_integral_parser_table_define],
 [  const b4_int_type_for([$2])
 # Define "parser::yy<TABLE-NAME>_" which contents is CONTENT.
 m4_define([b4_integral_parser_table_define],
 [  const b4_int_type_for([$2])
@@ -114,92 +114,9 @@ m4_popdef([b4_at_dollar])dnl
 m4_popdef([b4_dollar_dollar])dnl
 ])])
 
 m4_popdef([b4_dollar_dollar])dnl
 ])])
 
-# b4_symbol_constructor_declare_(SYMBOL-NUMBER)
-# ---------------------------------------------
-# Declare the overloaded version of make_symbol for the (common) type of
-# these SYMBOL-NUMBERS.  Use at class-level.
-m4_define([b4_symbol_constructor_declare_],
-[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
-[    static inline
-    symbol_type
-    make_[]b4_symbol_([$1], [id]) (dnl
-b4_args(b4_symbol_if([$1], [has_type],
-                     [const b4_symbol([$1], [type])& v]),
-        b4_locations_if([const location_type& l])));
-
-])])])
-
-
-# b4_symbol_constructor_declare
-# -----------------------------
-# Declare symbol constructors for all the value types.
-# Use at class-level.
-m4_define([b4_symbol_constructor_declare],
-[b4_variant_if([
-    // Symbol constructors declarations.
-b4_symbol_foreach([b4_symbol_constructor_declare_])])])
-
-
-
-# b4_symbol_constructor_define_(SYMBOL-NUMBER)
-# --------------------------------------------
-# Define symbol constructor for this SYMBOL-NUMBER.
-m4_define([b4_symbol_constructor_define_],
-[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
-[  b4_parser_class_name::symbol_type
-  b4_parser_class_name::make_[]b4_symbol_([$1], [id]) (dnl
-b4_args(b4_symbol_if([$1], [has_type],
-                     [const b4_symbol([$1], [type])& v]),
-        b4_locations_if([const location_type& l])))
-  {
-    return symbol_type (b4_args([yytranslate_ (token::b4_symbol([$1], [id]))],
-                                b4_symbol_if([$1], [has_type], [v]),
-                                b4_locations_if([l])));
-  }
-
-])])])
-
-
-# b4_symbol_constructor_define
-# ----------------------------
-# Define the overloaded versions of make_symbol for all the value types.
-m4_define([b4_symbol_constructor_define],
-[b4_variant_if([
-  // Implementation of make_symbol for each symbol type.
-b4_symbol_foreach([b4_symbol_constructor_define_])])])
-
-
-# b4_yytranslate_define
-# ---------------------
-# Define yytranslate_.  Sometimes we want it in the header file,
-# sometimes the cc file suffices.
-m4_define([b4_yytranslate_define],
-[[  // Symbol number corresponding to token number t.
-  ]b4_parser_class_name[::token_number_type
-  ]b4_parser_class_name[::yytranslate_ (]b4_lex_symbol_if([token_type],
-                                                          [int])[ t)
-  {
-    static
-    const token_number_type
-    translate_table[] =
-    {
-]b4_translate[
-    };
-    const unsigned int user_token_number_max_ = ]b4_user_token_number_max[;
-    const token_number_type undef_token_ = ]b4_undef_token_number[;
-
-    if (static_cast<int>(t) <= yyeof_)
-      return yyeof_;
-    else if (static_cast<unsigned int> (t) <= user_token_number_max_)
-      return translate_table[t];
-    else
-      return undef_token_;
-  }
-]])
-
 
 m4_pushdef([b4_copyright_years],
 
 m4_pushdef([b4_copyright_years],
-           [2002, 2003, 2004, 2005, 2006, 2007, 2008])
+           [2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009])
 
 m4_define([b4_parser_class_name],
           [b4_percent_define_get([[parser_class_name]])])
 
 m4_define([b4_parser_class_name],
           [b4_percent_define_get([[parser_class_name]])])
@@ -229,7 +146,8 @@ dnl FIXME: This is wrong, we want computed header guards.
 
 ]b4_percent_code_get([[requires]])[
 
 
 ]b4_percent_code_get([[requires]])[
 
-]b4_assert_if([#include <cassert>])[
+]b4_parse_assert_if([#include <cassert>])[
+#include <stdexcept>
 #include <string>
 #include <iostream>
 #include "stack.hh"
 #include <string>
 #include <iostream>
 #include "stack.hh"
@@ -244,7 +162,7 @@ dnl FIXME: This is wrong, we want computed header guards.
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
-# define YYDEBUG ]b4_debug_flag[
+# define YYDEBUG ]b4_parse_trace_if([1], [0])[
 #endif
 
 /* Enabling verbose error messages.  */
 #endif
 
 /* Enabling verbose error messages.  */
@@ -252,7 +170,7 @@ dnl FIXME: This is wrong, we want computed header guards.
 # undef YYERROR_VERBOSE
 # define YYERROR_VERBOSE 1
 #else
 # undef YYERROR_VERBOSE
 # define YYERROR_VERBOSE 1
 #else
-# define YYERROR_VERBOSE ]b4_error_verbose_flag[
+# define YYERROR_VERBOSE ]b4_error_verbose_if([1], [0])[
 #endif
 
 /* Enabling the token table.  */
 #endif
 
 /* Enabling the token table.  */
@@ -287,7 +205,6 @@ do {                                                            \
   {
   public:
 ]b4_public_types_declare[
   {
   public:
 ]b4_public_types_declare[
-]b4_symbol_constructor_declare[
     /// Build a parser object.
     ]b4_parser_class_name[ (]b4_parse_param_decl[);
     virtual ~]b4_parser_class_name[ ();
     /// Build a parser object.
     ]b4_parser_class_name[ (]b4_parse_param_decl[);
     virtual ~]b4_parser_class_name[ ();
@@ -316,14 +233,27 @@ do {                                                            \
     virtual void error (]b4_locations_if([const location_type& loc, ])[const std::string& msg);
 
   private:
     virtual void error (]b4_locations_if([const location_type& loc, ])[const std::string& msg);
 
   private:
-    /// Generate an error message.
-    /// \param state   the state where the error occurred.
-    /// \param tok     the lookahead token.
-    virtual std::string yysyntax_error_ (int yystate, int tok);
-
     /// State numbers.
     typedef int state_type;
 
     /// State numbers.
     typedef int state_type;
 
+    /// Generate an error message.
+    /// \param yystate   the state where the error occurred.
+    /// \param yytoken   the lookahead token.
+    virtual std::string yysyntax_error_ (state_type yystate, int yytoken);
+
+    /// Compute post-reduction state.
+    /// \param yystate   the current state
+    /// \param yylhs     the nonterminal to push on the stack
+    state_type yy_lr_goto_state_ (state_type yystate, int yylhs);
+
+    /// Whether the given \c yypact_ value indicates a defaulted state.
+    /// \param yyvalue   the value to check
+    static bool yy_pact_value_is_default_ (int yyvalue);
+
+    /// Whether the given \c yytable_ value indicates a syntax error.
+    /// \param yyvalue   the value to check
+    static bool yy_table_value_is_error_ (int yyvalue);
+
     /// Internal symbol numbers.
     typedef ]b4_int_type_for([b4_translate])[ token_number_type;
     static const ]b4_int_type(b4_pact_ninf, b4_pact_ninf)[ yypact_ninf_;
     /// Internal symbol numbers.
     typedef ]b4_int_type_for([b4_translate])[ token_number_type;
     static const ]b4_int_type(b4_pact_ninf, b4_pact_ninf)[ yypact_ninf_;
@@ -391,7 +321,7 @@ do {                                                            \
       /// The state.
       state_type state;
 
       /// The state.
       state_type state;
 
-      /// Return the type corresponding to this state.
+      /// The type (corresponding to \a state).
       inline int type_get_ () const;
     };
 
       inline int type_get_ () const;
     };
 
@@ -436,8 +366,7 @@ do {                                                            \
   };
 
 ]b4_lex_symbol_if([b4_yytranslate_define
   };
 
 ]b4_lex_symbol_if([b4_yytranslate_define
-b4_public_types_define
-b4_symbol_constructor_define])[
+b4_public_types_define])[
 ]b4_namespace_close[
 
 ]b4_percent_define_flag_if([[global_tokens_and_yystype]],
 ]b4_namespace_close[
 
 ]b4_percent_define_flag_if([[global_tokens_and_yystype]],
@@ -469,7 +398,7 @@ m4_if(b4_prefix, [yy], [],
 b4_percent_code_get[]dnl
 
 [#ifndef YY_
 b4_percent_code_get[]dnl
 
 [#ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* FIXME: INFRINGES ON USER NAME SPACE */
 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
 #  if ENABLE_NLS
 #   include <libintl.h> /* FIXME: INFRINGES ON USER NAME SPACE */
 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
@@ -587,8 +516,7 @@ b4_percent_code_get[]dnl
   | Symbol types.  |
   `---------------*/
 
   | Symbol types.  |
   `---------------*/
 
-]b4_lex_symbol_if([], [b4_public_types_define
-b4_symbol_constructor_define])[
+]b4_lex_symbol_if([], [b4_public_types_define])[
 
   // stack_symbol_type.
   ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type ()
 
   // stack_symbol_type.
   ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type ()
@@ -722,6 +650,28 @@ b4_symbol_constructor_define])[
   }
 #endif
 
   }
 #endif
 
+  inline ]b4_parser_class_name[::state_type
+  ]b4_parser_class_name[::yy_lr_goto_state_ (state_type yystate, int yylhs)
+  {
+    int yyr = yypgoto_[yylhs - yyntokens_] + yystate;
+    if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
+      return yytable_[yyr];
+    else
+      return yydefgoto_[yylhs - yyntokens_];
+  }
+
+  inline bool
+  ]b4_parser_class_name[::yy_pact_value_is_default_ (int yyvalue)
+  {
+    return yyvalue == yypact_ninf_;
+  }
+
+  inline bool
+  ]b4_parser_class_name[::yy_table_value_is_error_ (int yyvalue)
+  {
+    return yyvalue == yytable_ninf_;
+  }
+
   int
   ]b4_parser_class_name[::parse ()
   {
   int
   ]b4_parser_class_name[::parse ()
   {
@@ -731,7 +681,6 @@ b4_symbol_constructor_define])[
     /* State.  */
     int yyn;
     int yylen = 0;
     /* State.  */
     int yyn;
     int yylen = 0;
-    int yystate = 0;
 
     /* Error handling.  */
     int yynerrs_ = 0;
 
     /* Error handling.  */
     int yynerrs_ = 0;
@@ -766,14 +715,12 @@ m4_popdef([b4_at_dollar])])dnl
     yystack_ = stack_type (0);
     yypush_ (0, 0, yyla);
 
     yystack_ = stack_type (0);
     yypush_ (0, 0, yyla);
 
-    // A new state was pushed on the stack.
-    // Invariant: yystate == yystack_[0].state, i.e.,
-    // yystate was just pushed onto the state stack.
+    // A new symbol was pushed on the stack.
   yynewstate:
   yynewstate:
-    YYCDEBUG << "Entering state " << yystate << std::endl;
+    YYCDEBUG << "Entering state " << yystack_[0].state << std::endl;
 
     /* Accept?  */
 
     /* Accept?  */
-    if (yystate == yyfinal_)
+    if (yystack_[0].state == yyfinal_)
       goto yyacceptlab;
 
     goto yybackup;
       goto yyacceptlab;
 
     goto yybackup;
@@ -782,8 +729,8 @@ m4_popdef([b4_at_dollar])])dnl
   yybackup:
 
     /* Try to take a decision without lookahead.  */
   yybackup:
 
     /* Try to take a decision without lookahead.  */
-    yyn = yypact_[yystate];
-    if (yyn == yypact_ninf_)
+    yyn = yypact_[yystack_[0].state];
+    if (yy_pact_value_is_default_ (yyn))
       goto yydefault;
 
     /* Read a lookahead token.  */
       goto yydefault;
 
     /* Read a lookahead token.  */
@@ -811,7 +758,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
     yyn = yytable_[yyn];
     if (yyn <= 0)
       {
     yyn = yytable_[yyn];
     if (yyn <= 0)
       {
-       if (yyn == 0 || yyn == yytable_ninf_)
+       if (yy_table_value_is_error_ (yyn))
          goto yyerrlab;
        yyn = -yyn;
        goto yyreduce;
          goto yyerrlab;
        yyn = -yyn;
        goto yyreduce;
@@ -826,15 +773,14 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
       --yyerrstatus_;
 
     /* Shift the lookahead token.  */
       --yyerrstatus_;
 
     /* Shift the lookahead token.  */
-    yystate = yyn;
-    yypush_ ("Shifting", yystate, yyla);
+    yypush_ ("Shifting", yyn, yyla);
     goto yynewstate;
 
   /*-----------------------------------------------------------.
   | yydefault -- do the default action for the current state.  |
   `-----------------------------------------------------------*/
   yydefault:
     goto yynewstate;
 
   /*-----------------------------------------------------------.
   | yydefault -- do the default action for the current state.  |
   `-----------------------------------------------------------*/
   yydefault:
-    yyn = yydefact_[yystate];
+    yyn = yydefact_[yystack_[0].state];
     if (yyn == 0)
       goto yyerrlab;
     goto yyreduce;
     if (yyn == 0)
       goto yyerrlab;
     goto yyreduce;
@@ -843,11 +789,12 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
   | yyreduce -- Do a reduction.  |
   `-----------------------------*/
   yyreduce:
   | yyreduce -- Do a reduction.  |
   `-----------------------------*/
   yyreduce:
-    yylen = yyr2_[yyn];]b4_variant_if([
+    yylen = yyr2_[yyn];
+    yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([
     /* Variants are always initialized to an empty instance of the
        correct type. The default $$=$1 action is NOT applied when using
        variants.  */
     /* Variants are always initialized to an empty instance of the
        correct type. The default $$=$1 action is NOT applied when using
        variants.  */
-    ]b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build]),[
+    b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])],[
     /* If YYLEN is nonzero, implement the default value of the action:
        `$$ = $1'.  Otherwise, use the top of the stack.
 
     /* If YYLEN is nonzero, implement the default value of the action:
        `$$ = $1'.  Otherwise, use the top of the stack.
 
@@ -868,21 +815,21 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
 
     // Perform the reduction.
     YY_REDUCE_PRINT (yyn);
 
     // Perform the reduction.
     YY_REDUCE_PRINT (yyn);
-    switch (yyn)
+    try
+    {
+      switch (yyn)
       {
 ]b4_user_actions[
        default:
           break;
       }
       {
 ]b4_user_actions[
        default:
           break;
       }
-    // Compute post-reduction state.
-    yyn = yyr1_[yyn];
-    yystate = yypgoto_[yyn - yyntokens_] + yystack_[yylen].state;
-    if (0 <= yystate && yystate <= yylast_
-       && yycheck_[yystate] == yystack_[yylen].state)
-      yystate = yytable_[yystate];
-    else
-      yystate = yydefgoto_[yyn - yyntokens_];
-    yylhs.state = yystate;
+    }
+    catch (const syntax_error& yyexc)
+    {
+      error (]b4_args(b4_locations_if([yyexc.location]),
+                      [[yyexc.what()]])[);
+      YYERROR;
+    }
     YY_SYMBOL_PRINT ("-> $$ =", yylhs);
 ]b4_variant_if([[
     // Destroy the rhs symbols.
     YY_SYMBOL_PRINT ("-> $$ =", yylhs);
 ]b4_variant_if([[
     // Destroy the rhs symbols.
@@ -916,7 +863,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
       {
        ++yynerrs_;
        error (]b4_args(b4_locations_if([yyla.location]),
       {
        ++yynerrs_;
        error (]b4_args(b4_locations_if([yyla.location]),
-                        [yysyntax_error_ (yystate, yyla.type)])[);
+                        [[yysyntax_error_ (yystack_[0].state, yyla.type)]])[);
       }
 
 ]b4_locations_if([[
       }
 
 ]b4_locations_if([[
@@ -929,7 +876,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
         /* Return failure if at end of input.  */
         if (yyla.type == yyeof_)
           YYABORT;
         /* Return failure if at end of input.  */
         if (yyla.type == yyeof_)
           YYABORT;
-        else
+        else if (!yyempty)
           {
             yy_destroy_ ("Error: discarding", yyla);
             yyempty = true;
           {
             yy_destroy_ ("Error: discarding", yyla);
             yyempty = true;
@@ -950,15 +897,14 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
        YYERROR and the label yyerrorlab therefore never appears in user
        code.  */
     if (false)
        YYERROR and the label yyerrorlab therefore never appears in user
        code.  */
     if (false)
-      goto yyerrorlab;
-
-]b4_locations_if([[
-    yyerror_range[0].location = yystack_[yylen - 1].location;]])[
+      goto yyerrorlab;]b4_locations_if([[
+    yyerror_range[0].location = yystack_[yylen - 1].location;]])b4_variant_if([[
+    /* $$ was initialized before running the user action.  */
+    yy_destroy_ ("Error: discarding", yylhs);]])[
     /* Do not reclaim the symbols of the rule which action triggered
        this YYERROR.  */
     yypop_ (yylen);
     yylen = 0;
     /* Do not reclaim the symbols of the rule which action triggered
        this YYERROR.  */
     yypop_ (yylen);
     yylen = 0;
-    yystate = yystack_[0].state;
     goto yyerrlab1;
 
   /*-------------------------------------------------------------.
     goto yyerrlab1;
 
   /*-------------------------------------------------------------.
@@ -970,8 +916,8 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
       stack_symbol_type error_token;
       for (;;)
         {
       stack_symbol_type error_token;
       for (;;)
         {
-          yyn = yypact_[yystate];
-          if (yyn != yypact_ninf_)
+          yyn = yypact_[yystack_[0].state];
+          if (!yy_pact_value_is_default_ (yyn))
             {
               yyn += yyterror_;
               if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
             {
               yyn += yyterror_;
               if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
@@ -989,7 +935,6 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
           yyerror_range[0].location = yystack_[0].location;]])[
           yy_destroy_ ("Error: popping", yystack_[0]);
           yypop_ ();
           yyerror_range[0].location = yystack_[0].location;]])[
           yy_destroy_ ("Error: popping", yystack_[0]);
           yypop_ ();
-          yystate = yystack_[0].state;
           YY_STACK_PRINT ();
         }
 ]b4_locations_if([[
           YY_STACK_PRINT ();
         }
 ]b4_locations_if([[
@@ -997,7 +942,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
       YYLLOC_DEFAULT (error_token.location, (yyerror_range - 1), 2);]])[
 
       /* Shift the error token.  */
       YYLLOC_DEFAULT (error_token.location, (yyerror_range - 1), 2);]])[
 
       /* Shift the error token.  */
-      error_token.state = yystate = yyn;
+      error_token.state = yyn;
       yypush_ ("Shifting", error_token);
     }
     goto yynewstate;
       yypush_ ("Shifting", error_token);
     }
     goto yynewstate;
@@ -1031,7 +976,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
   // Generate an error message.
   std::string
   ]b4_parser_class_name[::yysyntax_error_ (]dnl
   // Generate an error message.
   std::string
   ]b4_parser_class_name[::yysyntax_error_ (]dnl
-b4_error_verbose_if([int yystate, int yytoken],
+b4_error_verbose_if([state_type yystate, int yytoken],
                     [int, int])[)
   {
     std::string yyres;]b4_error_verbose_if([[
                     [int, int])[)
   {
     std::string yyres;]b4_error_verbose_if([[
@@ -1039,7 +984,8 @@ b4_error_verbose_if([int yystate, int yytoken],
     if (yypact_ninf_ < yyn && yyn <= yylast_)
       {
        /* Start YYX at -YYN if negative to avoid negative indexes in
     if (yypact_ninf_ < yyn && yyn <= yylast_)
       {
        /* Start YYX at -YYN if negative to avoid negative indexes in
-          YYCHECK.  */
+          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 yyxbegin = yyn < 0 ? -yyn : 0;
 
        /* Stay within bounds of both yycheck and yytname.  */
@@ -1055,7 +1001,8 @@ b4_error_verbose_if([int yystate, int yytoken],
         char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
         yyarg[yycount++] = yytname_[yytoken];
        for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
         char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
         yyarg[yycount++] = yytname_[yytoken];
        for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
-         if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_)
+         if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_
+             && !yy_table_value_is_error_ (yytable_[yyx + yyn]))
           {
             if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
             {
           {
             if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
             {