X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/d69c9694a7a7038b4c3eb20acbf8ba8354bcf7a1..a0ffc1751e712e55b27aa7349ec7db302557476b:/data/lalr1.cc diff --git a/data/lalr1.cc b/data/lalr1.cc index 7a048152..bacdf37c 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -53,6 +53,12 @@ b4_variant_if([ ]) # b4_variant_if +# b4_lex_symbol_if([IF-YYLEX-RETURNS-A-COMPLETE-SYMBOL], [IF-NOT]) +# ---------------------------------------------------------------- +m4_define([b4_lex_symbol_if], +[b4_percent_define_ifdef([[lex_symbol]], [$1], [$2])]) + + # b4_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT]) # ------------------------------------------------ m4_define([b4_assert_if], @@ -113,6 +119,17 @@ 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) @@ -132,19 +149,109 @@ m4_popdef([b4_dollar_dollar])dnl ]) -# b4_symbol_action_(NUM) -# ---------------------- -# Invoke b4_dollar_dollar(SYMBOL_TYPENAME) for each symbol. -m4_define([b4_symbol_action_], -[m4_ifval(b4_symbol([$1], [type_name]), +# 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; + ])]) +# b4_symbol_constructor_declaration_(SYMBOL-NUMBERS) +# ---------------------------------------------------- +# Declare the overloaded version of make_symbol for the (common) type of +# these SYMBOL-NUMBERS. Use at class-level. +m4_define([b4_symbol_constructor_declaration_], +[ template + static inline symbol_type + make_symbol (b4_symbol_if([$1], [has_type_name], + [const b4_symbol([$1], [type_name])& v, ])dnl +const location_type& l); + +]) + +# b4_symbol_constructor_declarations +# ---------------------------------- +# Declare the overloaded versions of make_symbol for all the value types. +# Use at class-level. +m4_define([b4_symbol_constructor_declarations], +[b4_variant_if([ + // Declaration of make_symbol for each value type. +m4_map([b4_symbol_constructor_declaration_], m4_defn([b4_type_names]))])]) + + + +# b4_symbol_constructor_specialization_(SYMBOL-NUMBER) +# ---------------------------------------------------- +# Declare the specialization of make_symbol for this each SYMBOL-NUMBER. +# Specializations cannot be declared at class-level, this must be done +# at namespace-level. +m4_define([b4_symbol_constructor_specialization_], +[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [tag_is_id], +[ template <> + inline + b4_parser_class_name::symbol_type + b4_parser_class_name::make_symbol (dnl +b4_symbol_if([$1], [has_type_name], + [const b4_symbol([$1], [type_name])& v, ])dnl +const b4_parser_class_name::location_type& l); +])])]) + +# b4_symbol_constructor_specializations +# ------------------------------------- +# Declare specializations of make_symbol. +m4_define([b4_symbol_constructor_specializations], +[b4_variant_if([ + // Specializations of make_symbol for each symbol type. +m4_map([b4_symbol_constructor_specialization_], + m4_defn([b4_symbol_numbers]))])dnl +]) + + + +# b4_symbol_constructor_definition_(SYMBOL-NUMBER) +# ------------------------------------------------ +# Define make_symbol for this SYMBOL-NUMBER. +m4_define([b4_symbol_constructor_definition_], +[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [tag_is_id], +[ template <> + b4_parser_class_name::symbol_type + b4_parser_class_name::make_symbol (dnl +b4_symbol_if([$1], [has_type_name], + [const b4_symbol([$1], [type_name])& v, ])dnl +const location_type& l) + { + return symbol_type (yytranslate_ (token::b4_symbol([$1], [tag])),dnl + b4_symbol_if([$1], [has_type_name], [v, ])l); + } + +])])]) + + +# b4_symbol_constructor_declarations +# ---------------------------------- +# Define the overloaded versions of make_symbol for all the value types. +m4_define([b4_symbol_constructor_definitions], +[b4_variant_if( +[ // Implementation of make_symbol for each symbol type. +m4_map([b4_symbol_constructor_definition_], m4_defn([b4_symbol_numbers]))])]) + + # b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS]) # ------------------------------------------------ # Run some ACTION ("build", or "destroy") on YYVAL of symbol type @@ -154,9 +261,9 @@ m4_define([b4_symbol_variant], [$2.$3<$][3>(m4_shift3($@))])dnl switch ($1) { -m4_map([b4_symbol_action_], m4_defn([b4_symbol_numbers])) - default: - break; +m4_map([b4_type_action_], m4_defn([b4_type_names]))[]dnl + default: + break; } m4_popdef([b4_dollar_dollar])dnl ]) @@ -241,11 +348,12 @@ dnl FIXME: This is wrong, we want computed header guards. {]b4_assert_if([ /// Whether something is contained. bool built; - - /// Initially uninitialized. - variant () - : built(false) - {}])[ +])[ + /// Empty construction. + inline + variant ()]b4_assert_if([ + : built(false)])[ + {} /// Instantiate a \a T in here. template @@ -267,6 +375,15 @@ dnl FIXME: This is wrong, we want computed header guards. return *new (buffer) T(t); } + /// Construct and fill. + template + inline + variant (const T& t)]b4_assert_if([ + : built(true)])[ + { + new (buffer) T(t); + } + /// Accessor to a built \a T. template inline T& @@ -489,7 +606,7 @@ 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); /// A complete symbol, with its type. template @@ -499,6 +616,7 @@ m4_ifdef([b4_stype], inline symbol_base_type (); /// Constructor. + inline symbol_base_type (const location_type& l); inline symbol_base_type (const semantic_type& v, const location_type& l); /// Return this with its exact type. @@ -532,6 +650,7 @@ m4_ifdef([b4_stype], inline void yy_destroy_ (const char* yymsg, symbol_base_type& yysym) const; + public: /// Element of the stack: a state and its attributes. struct symbol_type : symbol_base_type { @@ -545,6 +664,9 @@ m4_ifdef([b4_stype], inline symbol_type (int t, const semantic_type& v, const location_type& l); + inline symbol_type (int t, + const location_type& l); + /// The symbol type. int type; @@ -552,6 +674,9 @@ m4_ifdef([b4_stype], inline int type_get_ () const; }; +]b4_symbol_constructor_declarations[ + + private: /// Element of the stack: a state and its attributes. struct stack_symbol_type : symbol_base_type { @@ -597,20 +722,21 @@ m4_ifdef([b4_stype], 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_symbol_constructor_specializations[ ]b4_namespace_close[ ]b4_percent_define_flag_if([[global_tokens_and_yystype]], @@ -695,12 +821,12 @@ b4_percent_code_get[]dnl #endif /* !YYDEBUG */ -#define yyerrok (yyerrstatus_ = 0) -#define yyclearin (yychar = yyempty_) +#define yyerrok (yyerrstatus_ = 0) +#define yyclearin (yyempty = true) -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab #define YYRECOVERING() (!!yyerrstatus_) ]b4_namespace_open[ @@ -772,6 +898,13 @@ b4_percent_code_get[]dnl { } + template + ]b4_parser_class_name[::symbol_base_type::symbol_base_type (const location_type& l) + : value() + , location(l) + { + } + template ]b4_parser_class_name[::symbol_base_type::symbol_base_type (const semantic_type& v, const location_type& l) : value(v) @@ -807,6 +940,13 @@ b4_percent_code_get[]dnl { } + ]b4_parser_class_name[::symbol_type::symbol_type (int t, + const location_type& l) + : super_type (l) + , type (t) + { + } + ]b4_parser_class_name[::symbol_type::symbol_type (int t, const semantic_type& v, const location_type& l) : super_type (v, l) @@ -820,6 +960,8 @@ b4_percent_code_get[]dnl return type; } +]b4_symbol_constructor_definitions[ + // stack_symbol_type. ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type () : super_type () @@ -860,7 +1002,7 @@ b4_percent_code_get[]dnl }]b4_variant_if([ // Type destructor. - b4_symbol_variant([[yytype]], [[yysym.value]], [[template destroy]])])[ + b4_symbol_variant([[yytype]], [[yysym.value]], [[template destroy]])])[ } #if YYDEBUG @@ -875,8 +1017,8 @@ b4_percent_code_get[]dnl << yysym.location << ": "; switch (yytype) { -]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl -[ default: +]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))[ + default: break; } yyo << ')'; @@ -944,8 +1086,8 @@ b4_percent_code_get[]dnl int ]b4_parser_class_name[::parse () { - /// Coded type of the lookahead. - int yychar = yyempty_; + /// Whether yyla contains a lookahead. + bool yyempty = true; /* State. */ int yyn; @@ -1006,27 +1148,18 @@ m4_popdef([b4_at_dollar])])dnl goto yydefault; /* Read a lookahead token. */ - if (yychar == yyempty_) + if (yyempty) { - YYCDEBUG << "Reading a token: "; - yychar = ]b4_c_function_call([yylex], [int], + YYCDEBUG << "Reading a token: "; +]b4_lex_symbol_if( +[ yyla = yylex();], +[ yyla.type = yytranslate_ (b4_c_function_call([yylex], [int], [[YYSTYPE*], [&yyla.value]][]dnl b4_locations_if([, [[location*], [&yyla.location]]])dnl -m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; - } - - - /* Convert token to internal form. */ - if (yychar <= yyeof_) - { - yychar = yyla.type = yyeof_; - YYCDEBUG << "Now at end of input." << std::endl; - } - else - { - yyla.type = yytranslate_ (yychar); - YY_SYMBOL_PRINT ("Next token is", yyla); +m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[ + yyempty = false; } + YY_SYMBOL_PRINT ("Next token is", yyla); /* If the proper action on seeing token YYLA.TYPE is to reduce or to detect an error, take that action. */ @@ -1045,7 +1178,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; } /* Discard the token being shifted. */ - yychar = yyempty_; + yyempty = true; /* Count tokens shifted since error; after three, turn off error status. */ @@ -1096,7 +1229,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; YY_REDUCE_PRINT (yyn); switch (yyn) { - ]b4_user_actions[ +]b4_user_actions[ default: break; } @@ -1146,18 +1279,15 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; if (yyerrstatus_ == 3) { /* 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 - { - yy_destroy_ ("Error: discarding", yyla); - yychar = yyempty_; + error, discard it. */ + + /* Return failure if at end of input. */ + if (yyla.type == yyeof_) + YYABORT; + else + { + yy_destroy_ ("Error: discarding", yyla); + yyempty = true; } } @@ -1237,7 +1367,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; goto yyreturn; yyreturn: - if (yychar != yyempty_) + if (!yyempty) yy_destroy_ ("Cleanup: discarding lookahead", yyla); /* Do not reclaim the symbols of the rule which action triggered @@ -1255,9 +1385,9 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; // Generate an error message. std::string ]b4_parser_class_name[::yysyntax_error_ (int yystate, int]dnl -b4_error_verbose_if([ tok])[) +b4_error_verbose_if([ yytoken])[) { - std::string res; + std::string yyres; YYUSE (yystate); #if YYERROR_VERBOSE int yyn = yypact_[yystate]; @@ -1270,36 +1400,55 @@ b4_error_verbose_if([ tok])[) /* Stay within bounds of both yycheck and yytname. */ int yychecklim = yylast_ - yyn + 1; int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; - int count = 0; - for (int x = yyxbegin; x < yyxend; ++x) - if (yycheck_[x + yyn] == x && x != yyterror_) - ++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]); - } - } + + // Number of "expected" tokens. + size_t yycount = 0; + // Its maximum. + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + // Arguments of yyformat. + 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 (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + break; + } + else + yyarg[yycount++] = yytname_[yyx]; + } + + char const* yyformat = 0; + switch (yycount) + { +#define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + 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; } else #endif - res = YY_("syntax error"); - return res; + yyres = YY_("syntax error"); + return yyres; } @@ -1395,26 +1544,19 @@ 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 (t <= yyeof_) + return yyeof_; + else 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