X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/de35dd590c99b1dce0a507349c8006100fce7c15..2bd435c36c0dfdefb07cef05dec851ec75bab20b:/data/lalr1.cc diff --git a/data/lalr1.cc b/data/lalr1.cc index d8782fae..237b246f 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -1,125 +1,88 @@ -m4_divert(-1) - # C++ skeleton for Bison -# Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# Copyright (C) 2002-2012 Free Software Foundation, Inc. -# This program is free software; you can redistribute it and/or modify +# 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 -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. - +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. - +# # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301 USA +# along with this program. If not, see . m4_include(b4_pkgdatadir/[c++.m4]) -# Backward compatibility. -m4_define([b4_location_constructors]) -m4_include(b4_pkgdatadir/[location.cc]) - -# We do want M4 expansion after # for CPP macros. -m4_changecom() -m4_divert(0)dnl -m4_if(b4_defines_flag, 0, [], -[@output @output_header_name@ -b4_copyright([C++ Skeleton parser for LALR(1) parsing with Bison], - [2002, 2003, 2004, 2005, 2006]) -dnl FIXME: This is wrong, we want computed header guards. -[ -/* C++ LALR(1) parser skeleton written by Akim Demaille. */ -#ifndef PARSER_HEADER_H -# define PARSER_HEADER_H +m4_define([b4_parser_class_name], + [b4_percent_define_get([[parser_class_name]])]) -#include -#include -#include "stack.hh" +# The header is mandatory. +b4_defines_if([], + [b4_fatal([b4_skeleton[: using %%defines is mandatory]])]) -namespace yy -{ - class position; - class location; -} +b4_percent_define_ifdef([[api.location.type]], [], + [# Backward compatibility. + m4_define([b4_location_constructors]) + m4_include(b4_pkgdatadir/[location.cc])]) +m4_include(b4_pkgdatadir/[stack.hh]) -/* First part of user declarations. */ -]b4_pre_prologue[ +b4_defines_if( +[b4_output_begin([b4_spec_defines_file]) +b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++], + [2002-2012]) +[ +/** + ** \file ]b4_spec_defines_file[ + ** Define the ]b4_namespace_ref[::parser class. + */ -]/* Line __line__ of lalr1.cc. */ -b4_syncline([@oline@], [@ofile@])[ +/* C++ LALR(1) parser skeleton written by Akim Demaille. */ -]dnl Include location.hh here: it might depend on headers included above. -[#include "location.hh" +]b4_cpp_guard_open([b4_spec_defines_file])[ -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG ]b4_debug[ -#endif +]b4_percent_code_get([[requires]])[ -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE ]b4_error_verbose[ -#endif +#include +#include +#include "stack.hh" +]b4_percent_define_ifdef([[api.location.type]], [], + [[#include "location.hh"]])[ -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE ]b4_token_table[ -#endif +]b4_YYDEBUG_define[ -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ -do { \ - if (N) \ - { \ - (Current).begin = (Rhs)[1].begin; \ - (Current).end = (Rhs)[N].end; \ - } \ - else \ - { \ - (Current).begin = (Current).end = (Rhs)[0].end; \ - } \ -} while (false) -#endif - -namespace yy -{ +]b4_namespace_open[ /// A Bison parser. class ]b4_parser_class_name[ { public: /// Symbol semantic values. -#ifndef YYSTYPE +#ifndef ]b4_api_PREFIX[STYPE ]m4_ifdef([b4_stype], [ union semantic_type -b4_stype -/* Line __line__ of lalr1.cc. */ -b4_syncline([@oline@], [@ofile@]) - ;], -[ typedef int semantic_type;])[ + { +b4_user_stype + };], +[m4_if(b4_tag_seen_flag, 0, +[[ typedef int semantic_type;]], +[[ typedef ]b4_api_PREFIX[STYPE semantic_type;]])])[ #else - typedef YYSTYPE semantic_type; + typedef ]b4_api_PREFIX[STYPE semantic_type; #endif /// Symbol locations. - typedef ]b4_location_type[ location_type; + typedef ]b4_percent_define_get([[api.location.type]], + [[location]])[ location_type; /// Tokens. struct token { ]b4_token_enums(b4_tokens)[ }; + /// Token type. + typedef token::yytokentype token_type; /// Build a parser object. ]b4_parser_class_name[ (]b4_parse_param_decl[); @@ -129,6 +92,7 @@ b4_syncline([@oline@], [@ofile@]) /// \returns 0 iff parsing succeeded. virtual int parse (); +#if ]b4_api_PREFIX[DEBUG /// The current debugging stream. std::ostream& debug_stream () const; /// Set the current debugging stream. @@ -140,6 +104,7 @@ b4_syncline([@oline@], [@ofile@]) debug_level_type debug_level () const; /// Set the current debugging level. void set_debug_level (debug_level_type l); +#endif private: /// Report a syntax error. @@ -149,11 +114,10 @@ b4_syncline([@oline@], [@ofile@]) /// Generate an error message. /// \param state the state where the error occurred. - /// \param tok the look-ahead token. - virtual std::string yysyntax_error_ (int yystate]dnl -b4_error_verbose_if([, int tok])[); + /// \param tok the lookahead token. + virtual std::string yysyntax_error_ (int yystate, int tok); -#if YYDEBUG +#if ]b4_api_PREFIX[DEBUG /// \brief Report a symbol value on the debug stream. /// \param yytype The token type. /// \param yyvaluep Its semantic value. @@ -168,7 +132,7 @@ b4_error_verbose_if([, int tok])[); virtual void yy_symbol_print_ (int yytype, const semantic_type* yyvaluep, const location_type* yylocationp); -#endif /* ! YYDEBUG */ +#endif /// State numbers. @@ -187,6 +151,14 @@ b4_error_verbose_if([, int tok])[); /// The location stack. location_stack_type yylocation_stack_; + /// 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; /* Tables. */ @@ -194,7 +166,7 @@ b4_error_verbose_if([, int tok])[); static const ]b4_int_type_for([b4_pact])[ yypact_[]; static const ]b4_int_type(b4_pact_ninf, b4_pact_ninf)[ yypact_ninf_; - /// For a state, default rule to reduce. + /// For a state, default reduction number. /// Unless\a yytable_ specifies something else to do. /// Zero means the default is an error. static const ]b4_int_type_for([b4_defact])[ yydefact_[]; @@ -218,19 +190,15 @@ b4_error_verbose_if([, int tok])[); /// For a rule, its LHS. static const ]b4_int_type_for([b4_r1])[ yyr1_[]; /// For a rule, its RHS length. - static const ]b4_int_type_for([b4_r2])[ yyr2_[]; + static const ]b4_int_type_for([b4_r2])[ yyr2_[]; ]b4_error_verbose_if([ -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE - /// For a symbol, its name in clear. - static const char* const yytname_[]; -#endif - -#if YYERROR_VERBOSE /// Convert the symbol name \a n to a form suitable for a diagnostic. - virtual std::string yytnamerr_ (const char *n); -#endif + static std::string yytnamerr_ (const char *n);])[ -#if YYDEBUG +]b4_token_table_if([], [[#if ]b4_api_PREFIX[DEBUG]])[ + /// For a symbol, its name in clear. + static const char* const yytname_[]; +]b4_token_table_if([[#if ]b4_api_PREFIX[DEBUG]])[ /// A type to store symbol numbers and -1. typedef ]b4_int_type_for([b4_rhs])[ rhs_number_type; /// A `-1'-separated list of the rules' RHS. @@ -245,13 +213,18 @@ b4_error_verbose_if([, int tok])[); virtual void yy_reduce_print_ (int r); /// Print the state stack on the debug stream. virtual void yystack_print_ (); + + /* Debugging. */ + int yydebug_; + std::ostream* yycdebug_; #endif - /// Convert a scanner token number to a symbol number. - token_number_type yytranslate_ (int token); + /// Convert a scanner token number \a t to a symbol number. + token_number_type yytranslate_ (int t); /// \brief Reclaim the memory associated to a symbol. /// \param yymsg Why this token is reclaimed. + /// If null, do not display the symbol, just free it. /// \param yytype The symbol type. /// \param yyvaluep Its semantic value. /// \param yylocationp Its location. @@ -275,44 +248,47 @@ b4_error_verbose_if([, int tok])[); static const int yyntokens_; static const unsigned int yyuser_token_number_max_; static const token_number_type yyundef_token_; - - /* Debugging. */ - int yydebug_; - std::ostream* yycdebug_; - ]b4_parse_param_vars[ }; -} +]b4_namespace_close[ -]m4_ifset([b4_global_tokens_and_yystype], +]b4_percent_define_flag_if([[global_tokens_and_yystype]], [b4_token_defines(b4_tokens) -#ifndef YYSTYPE +#ifndef ]b4_api_PREFIX[STYPE /* Redirection for backward compatibility. */ -# define YYSTYPE yy::b4_parser_class_name::semantic_type +# define ]b4_api_PREFIX[STYPE b4_namespace_ref::b4_parser_class_name::semantic_type #endif ])[ -#endif /* ! defined PARSER_HEADER_H */] -])dnl -@output @output_parser_name@ -b4_copyright([C++ Skeleton parser for LALR(1) parsing with Bison], - [2002, 2003, 2004, 2005, 2006]) -m4_if(b4_prefix[], [yy], [], +]b4_percent_code_get([[provides]])[ +]b4_cpp_guard_close([b4_spec_defines_file]) +b4_output_end() +]) + + +b4_output_begin([b4_parser_file_name]) +b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++], + [2002-2012]) +b4_percent_code_get([[top]])[]dnl +m4_if(b4_prefix, [yy], [], [ // Take the name prefix into account. -#define yylex b4_prefix[]lex]) -m4_if(b4_defines_flag, 0, [], -[ -#include @output_header_name@])[ +#define yylex b4_prefix[]lex])[ + +/* First part of user declarations. */ +]b4_user_pre_prologue[ + +]b4_defines_if([[ +#include "@basename(]b4_spec_defines_file[@)"]])[ /* User implementation prologue. */ -]b4_post_prologue[ +]b4_user_post_prologue[ +]b4_percent_code_get[ -]/* Line __line__ of lalr1.cc. */ -b4_syncline([@oline@], [@ofile@])[ +]b4_null_define[ #ifndef YY_ -# if YYENABLE_NLS +# if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* FIXME: INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) @@ -323,16 +299,17 @@ b4_syncline([@oline@], [@ofile@])[ # endif #endif +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +]b4_yylloc_default_define[ + /* Suppress unused-variable warnings by "using" E. */ #define YYUSE(e) ((void) (e)) -/* A pseudo ostream that takes yydebug_ into account. */ -# define YYCDEBUG \ - for (bool yydebugcond_ = yydebug_; yydebugcond_; yydebugcond_ = false) \ - (*yycdebug_) - /* Enable debugging if requested. */ -#if YYDEBUG +#if ]b4_api_PREFIX[DEBUG + +/* A pseudo ostream that takes yydebug_ into account. */ +# define YYCDEBUG if (yydebug_) (*yycdebug_) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ @@ -356,65 +333,70 @@ do { \ yystack_print_ (); \ } while (false) -#else /* !YYDEBUG */ +#else /* !]b4_api_PREFIX[DEBUG */ + +# define YYCDEBUG if (false) std::cerr +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) YYUSE(Type) +# define YY_REDUCE_PRINT(Rule) static_cast(0) +# define YY_STACK_PRINT() static_cast(0) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_REDUCE_PRINT(Rule) -# define YY_STACK_PRINT() +#endif /* !]b4_api_PREFIX[DEBUG */ -#endif /* !YYDEBUG */ +#define yyerrok (yyerrstatus_ = 0) +#define yyclearin (yychar = yyempty_) #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab +#define YYRECOVERING() (!!yyerrstatus_) -#if YYERROR_VERBOSE - -/* Return YYSTR after stripping away unnecessary quotes and - backslashes, so that it's suitable for yyerror. The heuristic is - that double-quoting is unnecessary unless the string contains an - apostrophe, a comma, or backslash (other than backslash-backslash). - YYSTR is taken from yytname. */ -std::string -yy::]b4_parser_class_name[::yytnamerr_ (const char *yystr) -{ - if (*yystr == '"') - { - std::string yyr = ""; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - yyr += *yyp; - break; - - case '"': - return yyr; - } - do_not_strip_quotes: ; - } +]b4_namespace_open[]b4_error_verbose_if([[ - return yystr; -} + /* Return YYSTR after stripping away unnecessary quotes and + backslashes, so that it's suitable for yyerror. The heuristic is + that double-quoting is unnecessary unless the string contains an + apostrophe, a comma, or backslash (other than backslash-backslash). + YYSTR is taken from yytname. */ + std::string + ]b4_parser_class_name[::yytnamerr_ (const char *yystr) + { + if (*yystr == '"') + { + std::string yyr = ""; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + yyr += *yyp; + break; + + case '"': + return yyr; + } + do_not_strip_quotes: ; + } -#endif + return yystr; + } +]])[ -namespace yy -{ /// Build a parser object. - ]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[) - : yydebug_ (false), - yycdebug_ (&std::cerr)]b4_parse_param_cons[ + ]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [ + :])[ +#if ]b4_api_PREFIX[DEBUG + ]m4_ifset([b4_parse_param], [ ], [ :])[yydebug_ (false), + yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[ +#endif]b4_parse_param_cons[ { } @@ -422,7 +404,7 @@ namespace yy { } -#if YYDEBUG +#if ]b4_api_PREFIX[DEBUG /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ @@ -433,6 +415,9 @@ namespace yy { YYUSE (yylocationp); YYUSE (yyvaluep); + std::ostream& yyo = debug_stream (); + std::ostream& yyoutput = yyo; + YYUSE (yyoutput); switch (yytype) { ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl @@ -452,7 +437,7 @@ namespace yy yy_symbol_value_print_ (yytype, yyvaluep, yylocationp); *yycdebug_ << ')'; } -#endif /* ! YYDEBUG */ +#endif void ]b4_parser_class_name[::yydestruct_ (const char* yymsg, @@ -462,7 +447,8 @@ namespace yy YYUSE (yymsg); YYUSE (yyvaluep); - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + if (yymsg) + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { @@ -480,6 +466,7 @@ namespace yy yylocation_stack_.pop (n); } +#if ]b4_api_PREFIX[DEBUG std::ostream& ]b4_parser_class_name[::debug_stream () const { @@ -504,30 +491,43 @@ namespace yy { yydebug_ = l; } +#endif + 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 () { - /// Look-ahead and look-ahead in internal form. + /// Lookahead and lookahead in internal form. int yychar = yyempty_; int yytoken = 0; - /* State. */ + // State. int yyn; int yylen = 0; int yystate = 0; - /* Error handling. */ + // Error handling. int yynerrs_ = 0; int yyerrstatus_ = 0; - /// Semantic value of the look-ahead. - semantic_type yylval; - /// Location of the look-ahead. + /// Semantic value of the lookahead. + static semantic_type yyval_default; + semantic_type yylval = yyval_default; + /// Location of the lookahead. location_type yylloc; /// The locations where the error started and ended. - location yyerror_range[2]; + location_type yyerror_range[3]; /// $$. semantic_type yyval; @@ -536,17 +536,17 @@ namespace yy int yyresult; + // FIXME: This shoud be completely indented. It is not yet to + // avoid gratuitous conflicts when merging into the master branch. + try + { YYCDEBUG << "Starting parse" << std::endl; ]m4_ifdef([b4_initial_action], [ -m4_pushdef([b4_at_dollar], [yylloc])dnl -m4_pushdef([b4_dollar_dollar], [yylval])dnl - /* User initialization code. */ - b4_initial_action -m4_popdef([b4_dollar_dollar])dnl -m4_popdef([b4_at_dollar])dnl - /* Line __line__ of yacc.c. */ -b4_syncline([@oline@], [@ofile@])])dnl +b4_dollar_pushdef([yylval], [], [yylloc])dnl +/* User initialization code. */ +b4_user_initial_action +b4_dollar_popdef])[]dnl [ /* Initialize the stacks. The initial state will be pushed in yynewstate, since the latter expects the semantical and the @@ -562,27 +562,31 @@ b4_syncline([@oline@], [@ofile@])])dnl yynewstate: yystate_stack_.push (yystate); YYCDEBUG << "Entering state " << yystate << std::endl; + + /* Accept? */ + if (yystate == yyfinal_) + goto yyacceptlab; + goto yybackup; /* Backup. */ yybackup: - /* Try to take a decision without look-ahead. */ + /* Try to take a decision without lookahead. */ yyn = yypact_[yystate]; - if (yyn == yypact_ninf_) + if (yy_pact_value_is_default_ (yyn)) goto yydefault; - /* Read a look-ahead token. */ + /* Read a lookahead token. */ if (yychar == yyempty_) { - YYCDEBUG << "Reading a token: "; - yychar = ]b4_c_function_call([yylex], [int], - [[YYSTYPE*], [&yylval]][]dnl -b4_location_if([, [[location*], [&yylloc]]])dnl + YYCDEBUG << "Reading a token: "; + yychar = ]b4_c_function_call([yylex], [int], + [b4_api_PREFIX[STYPE*], [&yylval]][]dnl +b4_locations_if([, [[location*], [&yylloc]]])dnl m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; } - /* Convert token to internal form. */ if (yychar <= yyeof_) { @@ -605,22 +609,17 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; yyn = yytable_[yyn]; if (yyn <= 0) { - if (yyn == 0 || yyn == yytable_ninf_) - goto yyerrlab; + if (yy_table_value_is_error_ (yyn)) + goto yyerrlab; yyn = -yyn; goto yyreduce; } - /* Accept? */ - if (yyn == yyfinal_) - goto yyacceptlab; - - /* Shift the look-ahead token. */ + /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the token being shifted unless it is eof. */ - if (yychar != yyeof_) - yychar = yyempty_; + /* Discard the token being shifted. */ + yychar = yyempty_; yysemantic_stack_.push (yylval); yylocation_stack_.push (yylloc); @@ -658,18 +657,32 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; else yyval = yysemantic_stack_[0]; + // Compute the default @@$. { slice slice (yylocation_stack_, yylen); YYLLOC_DEFAULT (yyloc, slice, yylen); } + + // Perform the reduction. YY_REDUCE_PRINT (yyn); switch (yyn) { - ]b4_actions - /* Line __line__ of lalr1.cc. */ -b4_syncline([@oline@], [@ofile@])[ - default: break; + ]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. In the case of YYABORT or YYACCEPT, an incorrect + destructor might then be invoked immediately. In the case of + YYERROR, 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); yypop_ (yylen); @@ -693,34 +706,38 @@ b4_syncline([@oline@], [@ofile@])[ | 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_) { ++yynerrs_; - error (yylloc, yysyntax_error_ (yystate]dnl -b4_error_verbose_if([, yytoken])[)); + if (yychar == yyempty_) + yytoken = yyempty_; + error (yylloc, yysyntax_error_ (yystate, yytoken)); } - yyerror_range[0] = yylloc; + yyerror_range[1] = yylloc; if (yyerrstatus_ == 3) { - /* If just tried and failed to reuse look-ahead token after an - error, discard it. */ - - if (yychar <= yyeof_) - { - /* Return failure if at end of input. */ - if (yychar == yyeof_) - YYABORT; - } - else - { - yydestruct_ ("Error: discarding", yytoken, &yylval, &yylloc); - yychar = yyempty_; - } + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + if (yychar <= yyeof_) + { + /* Return failure if at end of input. */ + if (yychar == yyeof_) + YYABORT; + } + else + { + yydestruct_ ("Error: discarding", yytoken, &yylval, &yylloc); + yychar = yyempty_; + } } - /* Else will try to reuse look-ahead token after shifting the error + /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; @@ -736,7 +753,7 @@ b4_error_verbose_if([, yytoken])[)); if (false) goto yyerrorlab; - yyerror_range[0] = yylocation_stack_[yylen - 1]; + yyerror_range[1] = yylocation_stack_[yylen - 1]; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ yypop_ (yylen); @@ -753,7 +770,7 @@ b4_error_verbose_if([, yytoken])[)); 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_) @@ -766,9 +783,9 @@ b4_error_verbose_if([, yytoken])[)); /* Pop the current state because it cannot handle the error token. */ if (yystate_stack_.height () == 1) - YYABORT; + YYABORT; - yyerror_range[0] = yylocation_stack_[0]; + yyerror_range[1] = yylocation_stack_[0]; yydestruct_ ("Error: popping", yystos_[yystate], &yysemantic_stack_[0], &yylocation_stack_[0]); @@ -777,19 +794,16 @@ b4_error_verbose_if([, yytoken])[)); YY_STACK_PRINT (); } - if (yyn == yyfinal_) - goto yyacceptlab; - - yyerror_range[1] = yylloc; + yyerror_range[2] = yylloc; // Using YYLLOC is tempting, but would change the location of - // the look-ahead. YYLOC is available though. - YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); + // the lookahead. YYLOC is available though. + YYLLOC_DEFAULT (yyloc, yyerror_range, 2); yysemantic_stack_.push (yylval); yylocation_stack_.push (yyloc); /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos_[yyn], - &yysemantic_stack_[0], &yylocation_stack_[0]); + &yysemantic_stack_[0], &yylocation_stack_[0]); yystate = yyn; goto yynewstate; @@ -805,72 +819,152 @@ b4_error_verbose_if([, yytoken])[)); goto yyreturn; yyreturn: - if (yychar != yyeof_ && yychar != yyempty_) - yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); + if (yychar != yyempty_) + { + /* 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, + &yylloc); + } /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ yypop_ (yylen); - while (yystate_stack_.height () != 1) + while (1 < yystate_stack_.height ()) { - yydestruct_ ("Cleanup: popping", - yystos_[yystate_stack_[0]], - &yysemantic_stack_[0], - &yylocation_stack_[0]); - yypop_ (); + yydestruct_ ("Cleanup: popping", + yystos_[yystate_stack_[0]], + &yysemantic_stack_[0], + &yylocation_stack_[0]); + yypop_ (); } return yyresult; + } + catch (...) + { + YYCDEBUG << "Exception caught: cleaning lookahead and stack" + << std::endl; + // Do not try to display the values of the reclaimed symbols, + // as their printer might throw an exception. + if (yychar != yyempty_) + { + /* Make sure we have latest lookahead translation. See + comments at user semantic actions for why this is + necessary. */ + yytoken = yytranslate_ (yychar); + yydestruct_ (YY_NULL, yytoken, &yylval, &yylloc); + } + + while (1 < yystate_stack_.height ()) + { + yydestruct_ (YY_NULL, + yystos_[yystate_stack_[0]], + &yysemantic_stack_[0], + &yylocation_stack_[0]); + yypop_ (); + } + throw; + } } // Generate an error message. std::string - ]b4_parser_class_name[::yysyntax_error_ (int yystate]dnl -b4_error_verbose_if([, int tok])[) - { - std::string res; - YYUSE (yystate); -#if YYERROR_VERBOSE - int yyn = yypact_[yystate]; - if (yypact_ninf_ < yyn && yyn < yylast_) + ]b4_parser_class_name[::yysyntax_error_ (]dnl +b4_error_verbose_if([int yystate, int yytoken], + [int, int])[) + {]b4_error_verbose_if([[ + std::string yyres; + // Number of reported tokens (one for the "unexpected", one per + // "expected"). + size_t yycount = 0; + // Its maximum. + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + // Arguments of yyformat. + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + + /* 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 yytoken) 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. + - 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 (yytoken != yyempty_) { - /* 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; - 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. It should work like yacc.c does it. - // That is, first build a string that looks like this: - // "syntax error, unexpected %s or %s or %s" - // Then, invoke YY_ on this string. - // Finally, use the string as a format to output - // yytname_[tok], etc. - // Until this gets fixed, this message appears in English only. - res = "syntax error, unexpected "; - res += yytnamerr_ (yytname_[tok]); - if (count < 5) - { - count = 0; - for (int x = yyxbegin; x < yyxend; ++x) - if (yycheck_[x + yyn] == x && x != yyterror_) - { - res += (!count++) ? ", expecting " : " or "; - res += yytnamerr_ (yytname_[x]); - } - } + yyarg[yycount++] = yytname_[yytoken]; + int yyn = yypact_[yystate]; + if (!yy_pact_value_is_default_ (yyn)) + { + /* 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_; + for (int yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_ + && !yy_table_value_is_error_ (yytable_[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + break; + } + else + yyarg[yycount++] = yytname_[yyx]; + } + } } - else -#endif - res = YY_("syntax error"); - return res; + + char const* yyformat = YY_NULL; + switch (yycount) + { +#define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +#undef YYCASE_ + } + + // Argument number. + size_t yyi = 0; + for (char const* yyp = yyformat; *yyp; ++yyp) + if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount) + { + yyres += yytnamerr_ (yyarg[yyi++]); + ++yyp; + } + else + yyres += *yyp; + return yyres;]], [[ + return YY_("syntax error");]])[ } @@ -883,9 +977,9 @@ b4_error_verbose_if([, int tok])[) ]b4_pact[ }; - /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE - doesn't specify something else to do. Zero means the default is an - error. */ + /* YYDEFACT[S] -- default reduction number in state S. Performed when + YYTABLE doesn't specify something else to do. Zero means the + default is an error. */ const ]b4_int_type_for([b4_defact])[ ]b4_parser_class_name[::yydefact_[] = { @@ -908,7 +1002,7 @@ b4_error_verbose_if([, int tok])[) /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. */ + number is the opposite. If YYTABLE_NINF_, syntax error. */ const ]b4_int_type(b4_table_ninf, b4_table_ninf) b4_parser_class_name::yytable_ninf_ = b4_table_ninf[; const ]b4_int_type_for([b4_table])[ ]b4_parser_class_name[::yytable_[] = @@ -931,7 +1025,7 @@ b4_error_verbose_if([, int tok])[) ]b4_stos[ }; -#if YYDEBUG +#if ]b4_api_PREFIX[DEBUG /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding to YYLEX-NUM. */ const ]b4_int_type_for([b4_toknum])[ @@ -955,7 +1049,7 @@ b4_error_verbose_if([, int tok])[) ]b4_r2[ }; -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +]b4_token_table_if([], [[#if ]b4_api_PREFIX[DEBUG]])[ /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at \a yyntokens_, nonterminals. */ const char* @@ -963,9 +1057,8 @@ b4_error_verbose_if([, int tok])[) { ]b4_tname[ }; -#endif -#if YYDEBUG +]b4_token_table_if([[#if ]b4_api_PREFIX[DEBUG]])[ /* YYRHS -- A `-1'-separated list of the rules' RHS. */ const ]b4_parser_class_name[::rhs_number_type ]b4_parser_class_name[::yyrhs_[] = @@ -1007,7 +1100,7 @@ b4_error_verbose_if([, int tok])[) int yynrhs = yyr2_[yyrule]; /* Print the symbols being reduced, and their result. */ *yycdebug_ << "Reducing stack by rule " << yyrule - 1 - << " (line " << yylno << "), "; + << " (line " << yylno << "):" << std::endl; /* The symbols being reduced. */ for (int yyi = 0; yyi < yynrhs; yyi++) YY_SYMBOL_PRINT (" $" << yyi + 1 << " =", @@ -1015,11 +1108,11 @@ b4_error_verbose_if([, int tok])[) &]b4_rhs_value(yynrhs, yyi + 1)[, &]b4_rhs_location(yynrhs, yyi + 1)[); } -#endif // YYDEBUG +#endif // ]b4_api_PREFIX[DEBUG /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ ]b4_parser_class_name[::token_number_type - ]b4_parser_class_name[::yytranslate_ (int token) + ]b4_parser_class_name[::yytranslate_ (int t) { static const token_number_type @@ -1027,8 +1120,8 @@ b4_error_verbose_if([, int tok])[) { ]b4_translate[ }; - if ((unsigned int) token <= yyuser_token_number_max_) - return translate_table[token]; + if ((unsigned int) t <= yyuser_token_number_max_) + return translate_table[t]; else return yyundef_token_; } @@ -1045,107 +1138,6 @@ b4_error_verbose_if([, int tok])[) const unsigned int ]b4_parser_class_name[::yyuser_token_number_max_ = ]b4_user_token_number_max[; const ]b4_parser_class_name[::token_number_type ]b4_parser_class_name[::yyundef_token_ = ]b4_undef_token_number[; -} // namespace yy - -]b4_epilogue -dnl -@output b4_dir_prefix[]stack.hh -b4_copyright([stack handling for Bison C++ parsers], - [2002, 2003, 2004, 2005, 2006])[ - -#ifndef BISON_STACK_HH -# define BISON_STACK_HH - -#include - -namespace yy -{ - template > - class stack - { - public: - - // Hide our reversed order. - typedef typename S::reverse_iterator iterator; - typedef typename S::const_reverse_iterator const_iterator; - - stack () : seq_ () - { - } - - stack (unsigned int n) : seq_ (n) - { - } - - inline - T& - operator [] (unsigned int i) - { - return seq_[i]; - } - - inline - const T& - operator [] (unsigned int i) const - { - return seq_[i]; - } - - inline - void - push (const T& t) - { - seq_.push_front (t); - } - - inline - void - pop (unsigned int n = 1) - { - for (; n; --n) - seq_.pop_front (); - } - - inline - unsigned int - height () const - { - return seq_.size (); - } - - inline const_iterator begin () const { return seq_.rbegin (); } - inline const_iterator end () const { return seq_.rend (); } - - private: - - S seq_; - }; - - /// Present a slice of the top of a stack. - template > - class slice - { - public: - - slice (const S& stack, - unsigned int range) : stack_ (stack), - range_ (range) - { - } - - inline - const T& - operator [] (unsigned int i) const - { - return stack_[range_ - i]; - } - - private: - - const S& stack_; - unsigned int range_; - }; -} - -#endif // not BISON_STACK_HH] -m4_divert(-1) +]b4_namespace_close[ +]b4_epilogue[]dnl +b4_output_end()