X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/8e0a5e9e735620ef5196a155eed1f8cf4d3aab5f..429b4848d42f0a70b568e7927261a065d4134535:/data/lalr1.cc diff --git a/data/lalr1.cc b/data/lalr1.cc index 8dcce38a..7195c28d 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -1,30 +1,117 @@ -m4_divert(-1) - # C++ skeleton for Bison -# Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# 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]) -b4_check_percent_code_qualifiers([[requires]], [[provides]], [[top]]) + +# How the semantic value is extracted when using variants. +b4_variant_if([ + # b4_symbol_value(VAL, [TYPE]) + # ---------------------------- + m4_define([b4_symbol_value], + [m4_ifval([$2], + [$1.as<$2>()], + [$1])]) +]) # b4_variant_if + + +# b4_symbol_actions(FILENAME, LINENO, +# SYMBOL-TAG, SYMBOL-NUM, +# SYMBOL-ACTION, SYMBOL-TYPENAME) +# ------------------------------------------------- +# Same as in C, but using references instead of pointers. +m4_define([b4_symbol_actions], +[m4_pushdef([b4_dollar_dollar], + [b4_symbol_value([yyvalue], [$6])])dnl +m4_pushdef([b4_at_dollar], [yylocation])dnl + case $4: // $3 +b4_syncline([$2], [$1]) + $5; +b4_syncline([@oline@], [@ofile@]) + break; +m4_popdef([b4_at_dollar])dnl +m4_popdef([b4_dollar_dollar])dnl +]) + + +# b4_symbol_action_(SYMBOL-TAG, SYMBOL-NUM, SYMBOL-TYPENAME) +# ---------------------------------------------------------- +# Invoke b4_dollar_dollar(SYMBOL_TYPENAME) for each symbol. +m4_define([b4_symbol_action_], +[m4_ifval($3, +[ case $2: // $1 + b4_dollar_dollar($@); + break; +])]) + + +# b4_symbol_variant(YYTYPE, YYVAL, ACTION) +# ---------------------------------------- +# Run some ACTION ("build", or "destroy") on YYVAL of symbol type +# YYTYPE. +m4_define([b4_symbol_variant], +[m4_pushdef([b4_dollar_dollar], + [$2.$3<$][3>()])dnl + switch ($1) + { +m4_map([b4_symbol_action_], m4_defn([b4_type_names])) + default: + break; + } +m4_popdef([b4_dollar_dollar])dnl +]) + + +# _b4_char_sizeof_counter +# ----------------------- +# A counter used by _b4_char_sizeof_dummy to create fresh symbols. +m4_define([_b4_char_sizeof_counter], +[0]) + +# _b4_char_sizeof_dummy +# --------------------- +# At each call return a new C++ identifier. +m4_define([_b4_char_sizeof_dummy], +[m4_define([_b4_char_sizeof_counter], m4_incr(_b4_char_sizeof_counter))dnl +dummy[]_b4_char_sizeof_counter]) + + +# b4_char_sizeof(SYMBOL-TAG, SYMBOL-NUM, SYMBOL-TYPENAME) +# ------------------------------------------------------- +# To be mapped on the list of type names to produce: +# +# char dummy1[sizeof(type_name_1)]; +# char dummy2[sizeof(type_name_2)]; +# +# for defined type names. +# $3 is doubly-quoted, do not quote it again. +m4_define([b4_char_sizeof], +[m4_ifval($3, +[ + char _b4_char_sizeof_dummy@{sizeof($3)@}; // $1])dnl +]) + + +m4_define([b4_parser_class_name], + [b4_percent_define_get([[parser_class_name]])]) # The header is mandatory. b4_defines_if([], - [m4_fatal(b4_skeleton[: using %defines is mandatory])]) + [b4_fatal([b4_skeleton[: using %%defines is mandatory]])]) # Backward compatibility. m4_define([b4_location_constructors]) @@ -32,11 +119,11 @@ m4_include(b4_pkgdatadir/[location.cc]) # We do want M4 expansion after # for CPP macros. m4_changecom() -m4_divert(0)dnl +m4_divert_push(0)dnl b4_defines_if( -[@output b4_spec_defines_file +[@output(b4_spec_defines_file@) b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++], - [2002, 2003, 2004, 2005, 2006]) + [2002, 2003, 2004, 2005, 2006, 2007, 2008]) dnl FIXME: This is wrong, we want computed header guards. [ /* C++ LALR(1) parser skeleton written by Akim Demaille. */ @@ -44,19 +131,61 @@ dnl FIXME: This is wrong, we want computed header guards. #ifndef PARSER_HEADER_H # define PARSER_HEADER_H -]m4_ifdef([b4_percent_code_requires], -[[/* Copy the %code "requires" blocks. */ -]b4_user_code([b4_percent_code_requires])])[ +]b4_percent_code_get([[requires]])[ #include #include #include "stack.hh" -namespace ]b4_namespace[ -{ +]b4_namespace_open[ class position; class location; -} +]b4_variant_if([[ + /// A char[S] buffer to store and retrieve objects. + /// + /// Sort of a variant, but does not keep track of the nature + /// of the stored data, since that knowledge is available + /// via the current state. + template + struct variant + { + /// Instantiate a \a T in here. + template + inline void + build() + { + new (buffer) T; + } + + /// Destroy the stored \a T. + template + inline void + destroy() + { + reinterpret_cast(buffer).~T(); + } + + /// Accessor to a built \a T. + template + inline T& + as() + { + return reinterpret_cast(buffer); + } + + /// Const accessor to a built \a T (for %printer). + template + inline const T& + as() const + { + return reinterpret_cast(buffer); + } + + /// A buffer large enough to store any of the semantic values. + char buffer[S]; + }; +]])[ +]b4_namespace_close[ #include "location.hh" @@ -97,27 +226,34 @@ do { \ } while (false) #endif -namespace ]b4_namespace[ -{ +]b4_namespace_open[ /// A Bison parser. class ]b4_parser_class_name[ { public: - /// Symbol semantic values. #ifndef YYSTYPE -]m4_ifdef([b4_stype], +]b4_variant_if( +[ /// An auxiliary type to compute the largest semantic type. + union union_type + {]m4_map([b4_char_sizeof], m4_defn([b4_type_names]))[ + }; + + /// Symbol semantic values. + typedef variant semantic_type;], +[ /// Symbol semantic values. +m4_ifdef([b4_stype], [ union semantic_type -b4_user_stype - ;], + {b4_user_stype + };], [m4_if(b4_tag_seen_flag, 0, [[ typedef int semantic_type;]], -[[ typedef YYSTYPE semantic_type;]])])[ +[[ typedef YYSTYPE semantic_type;]])])])[ #else typedef YYSTYPE semantic_type; #endif /// Symbol locations. - typedef ]b4_location_type[ location_type; + typedef ]b4_percent_define_get([[location_type]])[ location_type; /// Tokens. struct token { @@ -134,6 +270,7 @@ b4_user_stype /// \returns 0 iff parsing succeeded. virtual int parse (); +#if YYDEBUG /// The current debugging stream. std::ostream& debug_stream () const; /// Set the current debugging stream. @@ -145,6 +282,7 @@ b4_user_stype 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. @@ -161,18 +299,18 @@ b4_error_verbose_if([, int tok])[); #if YYDEBUG /// \brief Report a symbol value on the debug stream. /// \param yytype The token type. - /// \param yyvaluep Its semantic value. - /// \param yylocationp Its location. + /// \param yyvalue Its semantic value. + /// \param yylocation Its location. virtual void yy_symbol_value_print_ (int yytype, - const semantic_type* yyvaluep, - const location_type* yylocationp); + const semantic_type& yyvalue, + const location_type& yylocation); /// \brief Report a symbol on the debug stream. /// \param yytype The token type. - /// \param yyvaluep Its semantic value. - /// \param yylocationp Its location. + /// \param yyvalue Its semantic value. + /// \param yylocation Its location. virtual void yy_symbol_print_ (int yytype, - const semantic_type* yyvaluep, - const location_type* yylocationp); + const semantic_type& yyvalue, + const location_type& yylocation); #endif @@ -262,12 +400,17 @@ b4_error_verbose_if([, int tok])[); /// \brief Reclaim the memory associated to a symbol. /// \param yymsg Why this token is reclaimed. /// \param yytype The symbol type. - /// \param yyvaluep Its semantic value. - /// \param yylocationp Its location. + /// \param yyvalue Its semantic value. + /// \param yylocation Its location. inline void yydestruct_ (const char* yymsg, int yytype, - semantic_type* yyvaluep, - location_type* yylocationp); + semantic_type& yyvalue, + location_type& yylocation); + + /// Push a new state on the stack. + /// \warning the contents of \a v is stolen. + inline void yypush_ (state_type s, + semantic_type& v, const location_type& l); /// Pop \a n symbols the three stacks. inline void yypop_ (unsigned int n = 1); @@ -286,28 +429,24 @@ b4_error_verbose_if([, int tok])[); static const token_number_type yyundef_token_; ]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 /* Redirection for backward compatibility. */ -# define YYSTYPE b4_namespace::b4_parser_class_name::semantic_type +# define YYSTYPE b4_namespace_ref::b4_parser_class_name::semantic_type #endif ]) -m4_ifdef([b4_percent_code_provides], -[[/* Copy the %code "provides" blocks. */ -]b4_user_code([b4_percent_code_provides])])[]dnl +b4_percent_code_get([[provides]])[]dnl [#endif /* ! defined PARSER_HEADER_H */] ])dnl -@output b4_parser_file_name +@output(b4_parser_file_name@) b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++], - [2002, 2003, 2004, 2005, 2006]) -m4_ifdef([b4_percent_code_top], -[[/* Copy the %code "top" blocks. */ -]b4_user_code([b4_percent_code_top])])[]dnl + [2002, 2003, 2004, 2005, 2006, 2007, 2008]) +b4_percent_code_get([[top]])[]dnl m4_if(b4_prefix, [yy], [], [ // Take the name prefix into account. @@ -321,10 +460,7 @@ b4_defines_if([[ /* User implementation prologue. */ ]b4_user_post_prologue -m4_ifdef([b4_percent_code], -[[/* Copy the unqualified %code blocks. */ -]b4_user_code([b4_percent_code]) -])[]dnl +b4_percent_code_get[]dnl [#ifndef YY_ # if YYENABLE_NLS @@ -378,12 +514,15 @@ do { \ #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_) -namespace ]b4_namespace[ -{ +]b4_namespace_open[ #if YYERROR_VERBOSE /* Return YYSTR after stripping away unnecessary quotes and @@ -446,10 +585,10 @@ namespace ]b4_namespace[ inline void ]b4_parser_class_name[::yy_symbol_value_print_ (int yytype, - const semantic_type* yyvaluep, const location_type* yylocationp) + const semantic_type& yyvalue, const location_type& yylocation) { - YYUSE (yylocationp); - YYUSE (yyvaluep); + YYUSE (yylocation); + YYUSE (yyvalue); switch (yytype) { ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl @@ -461,25 +600,25 @@ namespace ]b4_namespace[ void ]b4_parser_class_name[::yy_symbol_print_ (int yytype, - const semantic_type* yyvaluep, const location_type* yylocationp) + const semantic_type& yyvalue, const location_type& yylocation) { *yycdebug_ << (yytype < yyntokens_ ? "token" : "nterm") << ' ' << yytname_[yytype] << " (" - << *yylocationp << ": "; - yy_symbol_value_print_ (yytype, yyvaluep, yylocationp); + << yylocation << ": "; + yy_symbol_value_print_ (yytype, yyvalue, yylocation); *yycdebug_ << ')'; } #endif void ]b4_parser_class_name[::yydestruct_ (const char* yymsg, - int yytype, semantic_type* yyvaluep, location_type* yylocationp) + int yytype, semantic_type& yyvalue, location_type& yylocation) { - YYUSE (yylocationp); YYUSE (yymsg); - YYUSE (yyvaluep); + YYUSE (yyvalue); + YYUSE (yylocation); - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + YY_SYMBOL_PRINT (yymsg, yytype, yyvalue, yylocation); switch (yytype) { @@ -489,6 +628,15 @@ namespace ]b4_namespace[ } } + void + ]b4_parser_class_name[::yypush_ (state_type s, + semantic_type& v, const location_type& l) + { + yystate_stack_.push (s); + yysemantic_stack_.push (v); + yylocation_stack_.push (l); + } + void ]b4_parser_class_name[::yypop_ (unsigned int n) { @@ -545,7 +693,7 @@ namespace ]b4_namespace[ /// Location of the lookahead. location_type yylloc; /// The locations where the error started and ended. - location yyerror_range[2]; + location_type yyerror_range[2]; /// $$. semantic_type yyval; @@ -571,12 +719,12 @@ m4_popdef([b4_at_dollar])])dnl yystate_stack_ = state_stack_type (0); yysemantic_stack_ = semantic_stack_type (0); yylocation_stack_ = location_stack_type (0); - yysemantic_stack_.push (yylval); - yylocation_stack_.push (yylloc); + yypush_ (yystate, yylval, yylloc); - /* New state. */ + // A new state was pushed on the stack. + // Invariant: yystate == yystack_[0].state, i.e., + // yystate was just pushed onto the state stack. yynewstate: - yystate_stack_.push (yystate); YYCDEBUG << "Entering state " << yystate << std::endl; /* Accept? */ @@ -613,7 +761,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; else { yytoken = yytranslate_ (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + YY_SYMBOL_PRINT ("Next token is", yytoken, yylval, yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to @@ -633,20 +781,18 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; } /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + YY_SYMBOL_PRINT ("Shifting", yytoken, yylval, yylloc); /* Discard the token being shifted. */ yychar = yyempty_; - yysemantic_stack_.push (yylval); - yylocation_stack_.push (yylloc); - /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus_) --yyerrstatus_; yystate = yyn; + yypush_ (yystate, yylval, yylloc); goto yynewstate; /*-----------------------------------------------------------. @@ -662,7 +808,11 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: - yylen = yyr2_[yyn]; + yylen = yyr2_[yyn];]b4_variant_if([ + /* Variants are always initialized to an empty instance of the + correct type. The default $$=$1 rule is NOT applied when using + variants */ + ]b4_symbol_variant([[yyr1_@{yyn@}]], [yyval], [build])[],[ /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, use the top of the stack. @@ -670,9 +820,9 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; This behavior is undocumented and Bison users should not rely upon it. */ if (yylen) - yyval = yysemantic_stack_[yylen - 1]; + yyval = yysemantic_stack_@{yylen - 1@}; else - yyval = yysemantic_stack_[0]; + yyval = yysemantic_stack_@{0@};])[ { slice slice (yylocation_stack_, yylen); @@ -682,17 +832,15 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; switch (yyn) { ]b4_user_actions[ - default: break; + default: + break; } - YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], &yyval, &yyloc); + YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], yyval, yyloc); yypop_ (yylen); yylen = 0; YY_STACK_PRINT (); - yysemantic_stack_.push (yyval); - yylocation_stack_.push (yyloc); - /* Shift the result of the reduction. */ yyn = yyr1_[yyn]; yystate = yypgoto_[yyn - yyntokens_] + yystate_stack_[0]; @@ -701,6 +849,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; yystate = yytable_[yystate]; else yystate = yydefgoto_[yyn - yyntokens_]; + yypush_ (yystate, yyval, yyloc); goto yynewstate; /*------------------------------------. @@ -729,7 +878,7 @@ b4_error_verbose_if([, yytoken])[)); } else { - yydestruct_ ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct_ ("Error: discarding", yytoken, yylval, yylloc); yychar = yyempty_; } } @@ -779,13 +928,13 @@ b4_error_verbose_if([, yytoken])[)); } /* Pop the current state because it cannot handle the error token. */ - if (yystate_stack_.height () == 1) + if (yystate_stack_.size () == 1) YYABORT; yyerror_range[0] = yylocation_stack_[0]; yydestruct_ ("Error: popping", yystos_[yystate], - &yysemantic_stack_[0], &yylocation_stack_[0]); + yysemantic_stack_[0], yylocation_stack_[0]); yypop_ (); yystate = yystate_stack_[0]; YY_STACK_PRINT (); @@ -795,14 +944,13 @@ b4_error_verbose_if([, yytoken])[)); // Using YYLLOC is tempting, but would change the location of // the lookahead. YYLOC is available though. YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 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; + yypush_ (yystate, yylval, yyloc); goto yynewstate; /* Accept. */ @@ -817,17 +965,17 @@ b4_error_verbose_if([, yytoken])[)); yyreturn: if (yychar != yyempty_) - yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); + 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 (yystate_stack_.size () != 1) { yydestruct_ ("Cleanup: popping", - yystos_[yystate_stack_[0]], - &yysemantic_stack_[0], - &yylocation_stack_[0]); + yystos_[yystate_stack_[0]], + yysemantic_stack_[0], + yylocation_stack_[0]); yypop_ (); } @@ -1018,13 +1166,13 @@ 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 << " =", yyrhs_[yyprhs_[yyrule] + yyi], - &]b4_rhs_value(yynrhs, yyi + 1)[, - &]b4_rhs_location(yynrhs, yyi + 1)[); + ]b4_rhs_value(yynrhs, yyi + 1)[, + ]b4_rhs_location(yynrhs, yyi + 1)[); } #endif // YYDEBUG @@ -1056,21 +1204,20 @@ 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 ]b4_namespace[ +]b4_namespace_close[ ]b4_epilogue dnl -@output b4_dir_prefix[]stack.hh +@output(b4_dir_prefix[]stack.hh@) b4_copyright([Stack handling for Bison parsers in C++], - [2002, 2003, 2004, 2005, 2006])[ + [2002, 2003, 2004, 2005, 2006, 2007, 2008])[ #ifndef BISON_STACK_HH # define BISON_STACK_HH #include -namespace ]b4_namespace[ -{ +]b4_namespace_open[ template > class stack { @@ -1118,17 +1265,17 @@ namespace ]b4_namespace[ } inline - unsigned int - height () const + typename S::size_type + size () const { return seq_.size (); } inline const_iterator begin () const { return seq_.rbegin (); } - inline const_iterator end () const { return seq_.rend (); } + inline const_iterator end () const { return seq_.rend (); } private: - + /// The wrapped container. S seq_; }; @@ -1156,7 +1303,8 @@ namespace ]b4_namespace[ const S& stack_; unsigned int range_; }; -} +]b4_namespace_close[ -#endif // not BISON_STACK_HH] -m4_divert(-1) +#endif // not BISON_STACK_HH[]dnl +] +m4_divert_pop(0)