X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/bc0b0477e2ad3f4caaeec8084d37b49400f4e0b5..11707b2b48fb781ff0e7fd3befdfb02f787a76e4:/data/lalr1.cc diff --git a/data/lalr1.cc b/data/lalr1.cc index 11490951..b00212e8 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -29,6 +29,11 @@ m4_define([b4_table_define], }dnl ]) +# b4_symbol_value_template(VAL, [TYPE]) +# ------------------------------------- +# Same as b4_symbol_value, but used in a template method. +m4_copy([b4_symbol_value], [b4_symbol_value_template]) + # How the semantic value is extracted when using variants. b4_variant_if([ # b4_symbol_value(VAL, [TYPE]) @@ -37,11 +42,19 @@ b4_variant_if([ [m4_ifval([$2], [$1.as<$2>()], [$1])]) + + # b4_symbol_value_template(VAL, [TYPE]) + # ------------------------------------- + # Same as b4_symbol_value, but used in a template method. + m4_define([b4_symbol_value_template], + [m4_ifval([$2], + [$1.template as<$2>()], + [$1])]) ]) # b4_variant_if # b4_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT]) -# ---------------------------------------------------- +# ------------------------------------------------ m4_define([b4_assert_if], [b4_percent_define_ifdef([[assert]], [$1], [$2])]) @@ -92,6 +105,25 @@ m4_define([b4_rhs_location], [b4_rhs_data([$1], [$2]).location]) +# b4_symbol(NUM, FIELD) +# --------------------- +# Recover a FIELD about symbol #NUM. Thanks to m4_indir, fails if +# undefined. +m4_define([b4_symbol], +[m4_indir([b4_symbol($1, $2)])]) + + +# b4_symbol_if(NUM, FIELD, IF-TRUE, IF-FALSE) +# ------------------------------------------- +# If FIELD about symbol #NUM is 1 expand IF-TRUE, if is 0, expand IF-FALSE. +# Otherwise an error. +m4_define([b4_symbol_if], +[m4_case(b4_symbol([$1], [$2]), + [1], [$3], + [0], [$4], + [m4_fatal([$0: field $2 of $1 is not a Boolean:] b4_symbol([$1], [$2]))])]) + + # b4_symbol_actions(FILENAME, LINENO, # SYMBOL-TAG, SYMBOL-NUM, # SYMBOL-ACTION, SYMBOL-TYPENAME) @@ -99,8 +131,8 @@ m4_define([b4_rhs_location], # Same as in C, but using references instead of pointers. m4_define([b4_symbol_actions], [m4_pushdef([b4_dollar_dollar], - [b4_symbol_value([yydata.value], [$6])])dnl -m4_pushdef([b4_at_dollar], [yydata.location])dnl + [b4_symbol_value_template([yysym.value], [$6])])dnl +m4_pushdef([b4_at_dollar], [yysym.location])dnl case $4: // $3 b4_syncline([$2], [$1]) $5; @@ -111,14 +143,26 @@ 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($@); +# b4_symbol_case_(SYMBOL-NUM) +# --------------------------- +# Issue a "case NUM" for SYMBOL-NUM. +m4_define([b4_symbol_case_], +[ case b4_symbol([$1], [number]): // b4_symbol([$1], [tag]) +]) + + +# b4_type_action_(NUMS) +# --------------------- +# Run actions for the symbol NUMS that all have the same type-name. +# Skip NUMS that have no type-name. +m4_define([b4_type_action_], +[b4_symbol_if([$1], [has_type_name], +[m4_map([b4_symbol_case_], [$@])[]dnl + b4_dollar_dollar([b4_symbol([$1], [number])], + [b4_symbol([$1], [tag])], + [b4_symbol([$1], [type_name])]); break; + ])]) @@ -131,9 +175,9 @@ m4_define([b4_symbol_variant], [$2.$3<$][3>(m4_shift3($@))])dnl switch ($1) { -m4_map([b4_symbol_action_], m4_defn([b4_type_names])) - default: - break; +m4_map([b4_type_action_], m4_defn([b4_type_names]))[]dnl + default: + break; } m4_popdef([b4_dollar_dollar])dnl ]) @@ -153,8 +197,8 @@ m4_define([_b4_char_sizeof_dummy], dummy[]_b4_char_sizeof_counter]) -# b4_char_sizeof(SYMBOL-TAG, SYMBOL-NUM, SYMBOL-TYPENAME) -# ------------------------------------------------------- +# b4_char_sizeof(SYMBOL-NUM) +# -------------------------- # To be mapped on the list of type names to produce: # # char dummy1[sizeof(type_name_1)]; @@ -163,9 +207,9 @@ dummy[]_b4_char_sizeof_counter]) # for defined type names. # $3 is doubly-quoted, do not quote it again. m4_define([b4_char_sizeof], -[m4_ifval($3, +[m4_ifval(b4_symbol([$1], [type_name]), [ - char _b4_char_sizeof_dummy@{sizeof($3)@}; // $1])dnl + char _b4_char_sizeof_dummy@{sizeof([b4_symbol([$1], [type_name])])@}; // b4_symbol([$1], [tag])])dnl ]) @@ -234,6 +278,16 @@ dnl FIXME: This is wrong, we want computed header guards. return *new (buffer) T; } + /// Instantiate a \a T in here from \a t. + template + inline T& + build(const T& t) + {]b4_assert_if([ + assert(!built); + built = true;])[ + return *new (buffer) T(t); + } + /// Accessor to a built \a T. template inline T& @@ -335,7 +389,7 @@ do { \ ]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]))[ + {]m4_map([b4_char_sizeof], m4_defn([b4_symbol_numbers]))[ }; /// Symbol semantic values. @@ -456,20 +510,24 @@ m4_ifdef([b4_stype], #endif /// Convert a scanner token number \a t to a symbol number. - token_number_type yytranslate_ (int t); + static inline token_number_type yytranslate_ (int t); - /// Element of the stack: a state and its attributes. - struct stack_symbol_type + /// A complete symbol, with its type. + template + struct symbol_base_type { /// Default constructor. - stack_symbol_type (); + inline symbol_base_type (); /// Constructor. - stack_symbol_type (state_type s, - const semantic_type& v, const location_type& l); + inline symbol_base_type (const semantic_type& v, const location_type& l); - /// The state. - state_type state; + /// Return this with its exact type. + const Exact& self () const; + Exact& self (); + + /// Return the type of this symbol. + int type_get () const; /// The semantic value. semantic_type value; @@ -479,31 +537,61 @@ m4_ifdef([b4_stype], }; #if YYDEBUG - /// \brief Report a symbol value on the debug stream as per %printer. - /// \param yytype The token type. - /// \param yydata Its semantic value and location. - virtual void yy_symbol_value_print_ (int yytype, - const stack_symbol_type& yydata); - /// \brief Report a symbol on the debug stream. - /// \param yytype The token type. - /// \param yydata Its semantic value and location. - virtual void yy_symbol_print_ (int yytype, - const stack_symbol_type& yydata); + /// \brief Display a symbol type, value and location. + /// \param yyo The output stream. + /// \param yysym The symbol. + template + void yy_print_ (std::ostream& yyo, + const symbol_base_type& yysym) const; #endif - /// \brief Reclaim the memory associated to a lookahead symbol. - /// \param yymsg Why this token is reclaimed. - /// If null, print nothing. - /// \param yytype The symbol type. - /// \param yydata Its semantic value and location. - inline void yydestruct_ (const char* yymsg, - int yytype, stack_symbol_type& yydata); + /// \brief Reclaim the memory associated to a symbol. + /// \param yymsg Why this token is reclaimed. + /// If null, print nothing. + /// \param s The symbol. + template + inline void yy_destroy_ (const char* yymsg, + symbol_base_type& yysym) const; + + /// Element of the stack: a state and its attributes. + struct symbol_type : symbol_base_type + { + /// The parent class. + typedef symbol_base_type super_type; + + /// Default constructor. + inline symbol_type (); + + /// Constructor. + inline symbol_type (int t, + const semantic_type& v, const location_type& l); + + /// The symbol type. + int type; + + /// Return the type corresponding to this state. + inline int type_get_ () const; + }; + + /// Element of the stack: a state and its attributes. + struct stack_symbol_type : symbol_base_type + { + /// The parent class. + typedef symbol_base_type super_type; + + /// Default constructor. + inline stack_symbol_type (); + + /// Constructor. + inline stack_symbol_type (state_type s, + const semantic_type& v, const location_type& l); + + /// The state. + state_type state; - /// \brief Reclaim the memory associated to a stack symbol. - /// \param yymsg Why this token is reclaimed. - /// If null, print nothing. - /// \param yysym Its kind, semantic value and location. - inline void yydestruct_ (const char* yymsg, stack_symbol_type& yysym); + /// Return the type corresponding to this state. + inline int type_get_ () const; + }; /// Stack type. typedef stack stack_type; @@ -518,23 +606,33 @@ m4_ifdef([b4_stype], /// \warning the contents of \a s.value is stolen. inline void yypush_ (const char* m, stack_symbol_type& s); + /// Push a new look ahead token on the state on the stack. + /// \param m a debug message to display + /// if null, no trace is output. + /// \param s the state + /// \param sym the symbol (for its value and location). + /// \warning the contents of \a s.value is stolen. + inline void yypush_ (const char* m, state_type s, symbol_type& sym); + /// Pop \a n symbols the three stacks. inline void yypop_ (unsigned int n = 1); /* Constants. */ - static const int yyeof_; - /* LAST_ -- Last index in TABLE_. */ - static const int yylast_; - static const int yynnts_; - static const int yyempty_; - static const int yyfinal_; - static const int yyterror_; - static const int yyerrcode_; - static const int yyntokens_; - static const unsigned int yyuser_token_number_max_; - static const token_number_type yyundef_token_; + enum + { + yyeof_ = 0, + yylast_ = ]b4_last[, //< Last index in yytable_. + yynnts_ = ]b4_nterms_number[, //< Number of nonterminal symbols. + yyempty_ = -2, + yyfinal_ = ]b4_final_state_number[, //< Termination state number. + yyterror_ = 1, + yyerrcode_ = 256, + yyntokens_ = ]b4_tokens_number[, //< Number of tokens. + }; + ]b4_parse_param_vars[ }; + ]b4_namespace_close[ ]b4_percent_define_flag_if([[global_tokens_and_yystype]], @@ -588,12 +686,12 @@ b4_percent_code_get[]dnl /* A pseudo ostream that takes yydebug_ into account. */ # define YYCDEBUG if (yydebug_) (*yycdebug_) -# define YY_SYMBOL_PRINT(Title, Type, Data) \ +# define YY_SYMBOL_PRINT(Title, Symbol) \ do { \ if (yydebug_) \ { \ *yycdebug_ << Title << ' '; \ - yy_symbol_print_ ((Type), (Data)); \ + yy_print_ (*yycdebug_, Symbol); \ *yycdebug_ << std::endl; \ } \ } while (false) @@ -613,9 +711,9 @@ b4_percent_code_get[]dnl #else /* !YYDEBUG */ # define YYCDEBUG if (false) std::cerr -# define YY_SYMBOL_PRINT(Title, Type, Data) static_cast(0) -# define YY_REDUCE_PRINT(Rule) static_cast(0) -# define YY_STACK_PRINT() static_cast(0) +# define YY_SYMBOL_PRINT(Title, Symbol) static_cast(0) +# define YY_REDUCE_PRINT(Rule) static_cast(0) +# define YY_STACK_PRINT() static_cast(0) #endif /* !YYDEBUG */ @@ -683,87 +781,151 @@ b4_percent_code_get[]dnl { } -#if YYDEBUG - /*--------------------------------. - | Print this symbol on YYOUTPUT. | - `--------------------------------*/ - inline void - ]b4_parser_class_name[::yy_symbol_value_print_ (int yytype, - const stack_symbol_type& yydata) + /*---------------. + | Symbol types. | + `---------------*/ + + // symbol_base_type. + template + ]b4_parser_class_name[::symbol_base_type::symbol_base_type () + : value() + , location() { - switch (yytype) - { - ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl -[ default: - break; - } } + template + ]b4_parser_class_name[::symbol_base_type::symbol_base_type (const semantic_type& v, const location_type& l) + : value(v) + , location(l) + { + } - void - ]b4_parser_class_name[::yy_symbol_print_ (int yytype, - const stack_symbol_type& yydata) + template + const Exact& + ]b4_parser_class_name[::symbol_base_type::self () const { - *yycdebug_ << (yytype < yyntokens_ ? "token" : "nterm") - << ' ' << yytname_[yytype] << " (" - << yydata.location << ": "; - yy_symbol_value_print_ (yytype, yydata); - *yycdebug_ << ')'; + return static_cast(*this); } -#endif - void - ]b4_parser_class_name[::yydestruct_ (const char* yymsg, - stack_symbol_type& yysym) + template + Exact& + ]b4_parser_class_name[::symbol_base_type::self () + { + return static_cast(*this); + } + + template + int + ]b4_parser_class_name[::symbol_base_type::type_get () const + { + return self ().type_get_ (); + } + + // symbol_type. + ]b4_parser_class_name[::symbol_type::symbol_type () + : super_type () + , type () + { + } + + ]b4_parser_class_name[::symbol_type::symbol_type (int t, + const semantic_type& v, const location_type& l) + : super_type (v, l) + , type (t) { - yydestruct_ (yymsg, yystos_[yysym.state], yysym); } + int + ]b4_parser_class_name[::symbol_type::type_get_ () const + { + return type; + } + + // stack_symbol_type. + ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type () + : super_type () + , state () + { + } + + ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type (state_type s, + const semantic_type& v, const location_type& l) + : super_type (v, l) + , state (s) + { + } + + int + ]b4_parser_class_name[::stack_symbol_type::type_get_ () const + { + return yystos_[state]; + } + + + template void - ]b4_parser_class_name[::yydestruct_ (const char* yymsg, - int yytype, stack_symbol_type& yydata) + ]b4_parser_class_name[::yy_destroy_ (const char* yymsg, + symbol_base_type& yysym) const { + int yytype = yysym.type_get (); YYUSE (yymsg); - if (yymsg) - YY_SYMBOL_PRINT (yymsg, yytype, yydata); + YY_SYMBOL_PRINT (yymsg, yysym); // User destructor. switch (yytype) { - ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_destructors]))[ +]m4_map([b4_symbol_actions], m4_defn([b4_symbol_destructors]))[ default: break; }]b4_variant_if([ // Type destructor. - b4_symbol_variant([[yytype]], [[yydata.value]], [[destroy]])])[ + b4_symbol_variant([[yytype]], [[yysym.value]], [[template destroy]])])[ } - ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type () - : state() - , value() - , location() +#if YYDEBUG + template + void + ]b4_parser_class_name[::yy_print_ (std::ostream& yyo, + const symbol_base_type& yysym) const { + int yytype = yysym.type_get (); + yyo << (yytype < yyntokens_ ? "token" : "nterm") + << ' ' << yytname_[yytype] << " (" + << yysym.location << ": "; + switch (yytype) + { +]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))[ + default: + break; + } + yyo << ')'; } +#endif - ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type (state_type s, - const semantic_type& v, const location_type& l) - : state(s) - , value(v) - , location(l) + void + ]b4_parser_class_name[::yypush_ (const char* m, state_type s, + symbol_type& sym) { + if (m) + YY_SYMBOL_PRINT (m, sym); +]b4_variant_if( +[[ yystack_.push (stack_symbol_type (s, semantic_type(), sym.location)); + ]b4_symbol_variant([[yystos_[s]]], [[yystack_[0].value]], + [build], [sym.value])], +[ yystack_.push (stack_symbol_type (s, sym.value, sym.location));])[ } void ]b4_parser_class_name[::yypush_ (const char* m, stack_symbol_type& s) { if (m) - YY_SYMBOL_PRINT (m, yystos_[s.state], s); + YY_SYMBOL_PRINT (m, s); ]b4_variant_if( -[[ yystack_.push (stack_symbol_type (s, semantic_type(), l)); - ]b4_symbol_variant([[yystos_[s]]], [[yystack_[0].value]], +[[ yystack_.push (stack_symbol_type (s.state, semantic_type(), s.location)); + ]b4_symbol_variant([[yystos_[s.state]]], [[yystack_[0].value]], [build], [s.value])], [ yystack_.push (s);])[ } @@ -804,9 +966,8 @@ b4_percent_code_get[]dnl int ]b4_parser_class_name[::parse () { - /// Lookahead and lookahead in internal form. + /// Coded type of the lookahead. int yychar = yyempty_; - int yytoken = 0; /* State. */ int yyn; @@ -818,7 +979,7 @@ b4_percent_code_get[]dnl int yyerrstatus_ = 0; /// The lookahead symbol. - stack_symbol_type yyla; + symbol_type yyla; /// The locations where the error started and ended. stack_symbol_type yyerror_range[2]; @@ -844,7 +1005,7 @@ m4_popdef([b4_at_dollar])])dnl location values to have been already stored, initialize these stacks with a primary value. */ yystack_ = stack_type (0); - yypush_ (0, yyla); + yypush_ (0, 0, yyla); // A new state was pushed on the stack. // Invariant: yystate == yystack_[0].state, i.e., @@ -876,23 +1037,22 @@ b4_locations_if([, [[location*], [&yyla.location]]])dnl m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; } - /* Convert token to internal form. */ if (yychar <= yyeof_) { - yychar = yytoken = yyeof_; + yychar = yyla.type = yyeof_; YYCDEBUG << "Now at end of input." << std::endl; } else { - yytoken = yytranslate_ (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, yyla); + yyla.type = yytranslate_ (yychar); + YY_SYMBOL_PRINT ("Next token is", yyla); } - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken) + /* If the proper action on seeing token YYLA.TYPE is to reduce or + to detect an error, take that action. */ + yyn += yyla.type; + if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type) goto yydefault; /* Reduce or error. */ @@ -914,8 +1074,8 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; --yyerrstatus_; /* Shift the lookahead token. */ - yyla.state = yystate = yyn; - yypush_ ("Shifting", yyla); + yystate = yyn; + yypush_ ("Shifting", yystate, yyla); goto yynewstate; /*-----------------------------------------------------------. @@ -957,7 +1117,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; YY_REDUCE_PRINT (yyn); switch (yyn) { - ]b4_user_actions[ +]b4_user_actions[ default: break; } @@ -970,7 +1130,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; else yystate = yydefgoto_[yyn - yyntokens_]; yylhs.state = yystate; - YY_SYMBOL_PRINT ("-> $$ =", yyn, yylhs); + YY_SYMBOL_PRINT ("-> $$ =", yylhs); ]b4_variant_if([[ // Destroy the lhs symbols. for (int i = 0; i < yylen; ++i) @@ -982,7 +1142,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; // do not try to report the content in the debug trace, it's // junk. Hence yymsg = 0. Besides, that keeps exactly the same // traces as with the other Bison skeletons. - yydestruct_ (0, yystack_[i]);]])[ + yy_destroy_ (0, yystack_[i]);]])[ yypop_ (yylen); yylen = 0; @@ -1000,7 +1160,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; if (!yyerrstatus_) { ++yynerrs_; - error (yyla.location, yysyntax_error_ (yystate, yytoken)); + error (yyla.location, yysyntax_error_ (yystate, yyla.type)); } yyerror_range[0].location = yyla.location; @@ -1017,7 +1177,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; } else { - yydestruct_ ("Error: discarding", yytoken, yyla); + yy_destroy_ ("Error: discarding", yyla); yychar = yyempty_; } } @@ -1072,7 +1232,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; YYABORT; yyerror_range[0].location = yystack_[0].location; - yydestruct_ ("Error: popping", yystack_[0]); + yy_destroy_ ("Error: popping", yystack_[0]); yypop_ (); yystate = yystack_[0].state; YY_STACK_PRINT (); @@ -1099,14 +1259,14 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; yyreturn: if (yychar != yyempty_) - yydestruct_ ("Cleanup: discarding lookahead", yytoken, yyla); + yy_destroy_ ("Cleanup: discarding lookahead", yyla); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ yypop_ (yylen); while (yystack_.size () != 1) { - yydestruct_ ("Cleanup: popping", yystack_[0]); + yy_destroy_ ("Cleanup: popping", yystack_[0]); yypop_ (); } @@ -1244,8 +1404,7 @@ b4_error_verbose_if([ tok])[) /* The symbols being reduced. */ for (int yyi = 0; yyi < yynrhs; yyi++) YY_SYMBOL_PRINT (" $" << yyi + 1 << " =", - ]yystos_@{b4_rhs_state(yynrhs, yyi + 1)@}[, - ]b4_rhs_data(yynrhs, yyi + 1)[); + ]b4_rhs_data(yynrhs, yyi + 1)[); } #endif // YYDEBUG @@ -1257,26 +1416,17 @@ b4_error_verbose_if([ tok])[) const token_number_type translate_table[] = { - ]b4_translate[ +]b4_translate[ }; - if ((unsigned int) t <= yyuser_token_number_max_) + 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 (t) <= user_token_number_max_) return translate_table[t]; else - return yyundef_token_; + return undef_token_; } - const int ]b4_parser_class_name[::yyeof_ = 0; - const int ]b4_parser_class_name[::yylast_ = ]b4_last[; - const int ]b4_parser_class_name[::yynnts_ = ]b4_nterms_number[; - const int ]b4_parser_class_name[::yyempty_ = -2; - const int ]b4_parser_class_name[::yyfinal_ = ]b4_final_state_number[; - const int ]b4_parser_class_name[::yyterror_ = 1; - const int ]b4_parser_class_name[::yyerrcode_ = 256; - const int ]b4_parser_class_name[::yyntokens_ = ]b4_tokens_number[; - - 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[; - ]b4_namespace_close[ ]b4_epilogue[]dnl