X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/c932d6135ca3e508f7136810b9b0bf79725290b9..22b081deb7ab1d0ec7a279e5213fa7fdc2c85207:/data/c%20%20.m4/bison.git/blobdiff_plain/c932d6135ca3e508f7136810b9b0bf79725290b9..22b081deb7ab1d0ec7a279e5213fa7fdc2c85207:/data/c++.m4 diff --git a/data/c++.m4 b/data/c++.m4 index 8470ebe9..f1468c70 100644 --- a/data/c++.m4 +++ b/data/c++.m4 @@ -23,7 +23,6 @@ m4_include(b4_pkgdatadir/[c.m4]) ## Default values. ## ## ---------------- ## -# Default parser class name. b4_percent_define_default([[parser_class_name]], [[parser]]) # Don't do that so that we remember whether we're using a user @@ -32,18 +31,21 @@ b4_percent_define_default([[parser_class_name]], [[parser]]) # b4_percent_define_default([[location_type]], [[location]]) b4_percent_define_default([[filename_type]], [[std::string]]) -b4_percent_define_default([[namespace]], m4_defn([b4_prefix])) +b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix])) + b4_percent_define_default([[global_tokens_and_yystype]], [[false]]) b4_percent_define_default([[define_location_comparison]], [m4_if(b4_percent_define_get([[filename_type]]), [std::string], [[true]], [[false]])]) + ## ----------- ## ## Namespace. ## ## ----------- ## -m4_define([b4_namespace_ref], [b4_percent_define_get([[namespace]])]) +m4_define([b4_namespace_ref], [b4_percent_define_get([[api.namespace]])]) + # Don't permit an empty b4_namespace_ref. Any `::parser::foo' appended to it # would compile as an absolute reference with `parser' in the global namespace. @@ -53,7 +55,7 @@ m4_define([b4_namespace_ref], [b4_percent_define_get([[namespace]])]) # include the header, which is always generated. If we ever need to permit # internal linkage somehow, surely we can find a cleaner approach. m4_if(m4_bregexp(b4_namespace_ref, [^[ ]*$]), [-1], [], -[b4_complain_at(b4_percent_define_get_loc([[namespace]]), +[b4_complain_at(b4_percent_define_get_loc([[api.namespace]]), [[namespace reference is empty]])]) # Instead of assuming the C++ compiler will do it, Bison should reject any @@ -64,20 +66,20 @@ m4_if(m4_bregexp(b4_namespace_ref, [^[ ]*$]), [-1], [], # Specifically, don't allow empty names as b4_namespace_open would just convert # those into anonymous namespaces, and that might tempt some users. m4_if(m4_bregexp(b4_namespace_ref, [::[ ]*::]), [-1], [], -[b4_complain_at(b4_percent_define_get_loc([[namespace]]), +[b4_complain_at(b4_percent_define_get_loc([[api.namespace]]), [[namespace reference has consecutive "::"]])]) m4_if(m4_bregexp(b4_namespace_ref, [::[ ]*$]), [-1], [], -[b4_complain_at(b4_percent_define_get_loc([[namespace]]), +[b4_complain_at(b4_percent_define_get_loc([[api.namespace]]), [[namespace reference has a trailing "::"]])]) m4_define([b4_namespace_open], -[b4_user_code([b4_percent_define_get_syncline([[namespace]]) +[b4_user_code([b4_percent_define_get_syncline([[api.namespace]]) [namespace ]m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref), [^\(.\)[ ]*::], [\1])), [::], [ { namespace ])[ {]])]) m4_define([b4_namespace_close], -[b4_user_code([b4_percent_define_get_syncline([[namespace]]) +[b4_user_code([b4_percent_define_get_syncline([[api.namespace]]) m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref[ ]), [^\(.\)[ ]*\(::\)?\([^][:]\|:[^:]\)*], [\1])), @@ -97,16 +99,269 @@ m4_map_sep([ b4_token_enum], [, ]) + + ## ----------------- ## ## Semantic Values. ## ## ----------------- ## +# b4_semantic_type_declare +# ------------------------ +# Declare semantic_type. +m4_define([b4_semantic_type_declare], +[ /// Symbol semantic values. +m4_ifdef([b4_stype], +[ union semantic_type + {b4_user_stype + };], +[m4_if(b4_tag_seen_flag, 0, +[[ typedef int semantic_type;]], +[[ typedef YYSTYPE semantic_type;]])])]) + + +# b4_public_types_declare +# ----------------------- +# Define the public types: token, semantic value, location, and so forth. +# Depending on %define token_lex, may be output in the header or source file. +m4_define([b4_public_types_declare], +[[#ifndef YYSTYPE +]b4_semantic_type_declare[ +#else + typedef YYSTYPE semantic_type; +#endif]b4_locations_if([ + /// Symbol locations. + typedef b4_percent_define_get([[location_type]], + [[location]]) location_type;])[ + + /// Syntax errors thrown from user actions. + struct syntax_error : std::runtime_error + { + syntax_error (]b4_locations_if([const location_type& l, ])[const std::string& m);]b4_locations_if([ + location_type location;])[ + }; + + /// Tokens. + struct token + { + ]b4_token_enums(b4_tokens)[ + }; + + /// Token type. + typedef token::yytokentype token_type; + + /// A complete symbol, with its type. + template + struct symbol_base_type + { + /// Default constructor. + inline symbol_base_type (); + + /// Constructor.]b4_locations_if([ + inline symbol_base_type (const location_type& l)])[; + inline symbol_base_type (]b4_args( + [const semantic_type& v], + b4_locations_if([const location_type& l]))[); + + /// 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;]b4_locations_if([ + + /// The location. + location_type location;])[ + }; + + /// External form of a symbol: its type and attributes. + struct symbol_type : symbol_base_type + { + /// The parent class. + typedef symbol_base_type super_type; + + /// Default constructor. + inline symbol_type (); + + /// Constructor for tokens with semantic value. + inline symbol_type (]b4_args([token_type t], + [const semantic_type& v], + b4_locations_if([const location_type& l]))[); + + /// Constructor for valueless tokens. + inline symbol_type (]b4_args([token_type t], + b4_locations_if([const location_type& l]))[); + + /// The symbol type. + int type; + + /// The symbol type. + inline int type_get_ () const; + + /// The token. + inline token_type token () const; + }; +]b4_symbol_constructor_declare]) + + +# b4_public_types_define +# ---------------------- +# Provide the implementation needed by the public types. +m4_define([b4_public_types_define], +[[ inline + ]b4_parser_class_name[::syntax_error::syntax_error (]b4_locations_if([const location_type& l, ])[const std::string& m) + : std::runtime_error (m)]b4_locations_if([ + , location (l)])[ + {} + + // symbol_base_type. + template + inline + ]b4_parser_class_name[::symbol_base_type::symbol_base_type () + : value()]b4_locations_if([ + , location()])[ + { + }]b4_locations_if([[ + + template + inline + ]b4_parser_class_name[::symbol_base_type::symbol_base_type (const location_type& l) + : value() + , location(l) + { + }]])[ + + template + inline + ]b4_parser_class_name[::symbol_base_type::symbol_base_type (]b4_args( + [const semantic_type& v], + b4_locations_if([const location_type& l]))[) + : value(v)]b4_locations_if([ + , location(l)])[ + { + } + + template + inline + const Exact& + ]b4_parser_class_name[::symbol_base_type::self () const + { + return static_cast(*this); + } + + template + inline + Exact& + ]b4_parser_class_name[::symbol_base_type::self () + { + return static_cast(*this); + } + + template + inline + int + ]b4_parser_class_name[::symbol_base_type::type_get () const + { + return self ().type_get_ (); + } + + // symbol_type. + inline + ]b4_parser_class_name[::symbol_type::symbol_type () + : super_type () + , type () + { + } + + inline + ]b4_parser_class_name[::symbol_type::symbol_type (]b4_args( + [token_type t], + b4_locations_if([const location_type& l]))[) + : super_type (]b4_locations_if([l])[) + , type (yytranslate_ (t)) + { + } + + inline + ]b4_parser_class_name[::symbol_type::symbol_type (]b4_args( + [token_type t], + [const semantic_type& v], + b4_locations_if([const location_type& l]))[) + : super_type (v]b4_locations_if([, l])[) + , type (yytranslate_ (t)) + { + } + + inline + int + ]b4_parser_class_name[::symbol_type::type_get_ () const + { + return type; + } +]b4_lex_symbol_if([[ + inline + ]b4_parser_class_name[::token_type + ]b4_parser_class_name[::symbol_type::token () const + { + // YYTOKNUM[NUM] -- (External) token number corresponding to the + // (internal) symbol number NUM (which must be that of a token). */ + static + const ]b4_int_type_for([b4_toknum])[ + yytoken_number_[] = + { + ]b4_toknum[ + }; + return static_cast (yytoken_number_[type]); + } +]])[]dnl +b4_symbol_constructor_define]) + + +# b4_symbol_constructor_declare +# b4_symbol_constructor_define +# ----------------------------- +# Declare/define symbol constructors for all the value types. +# Use at class-level. Redefined in variant.hh. +m4_define([b4_symbol_constructor_declare], []) +m4_define([b4_symbol_constructor_define], []) + + +# b4_yytranslate_define +# --------------------- +# Define yytranslate_. Sometimes used in the header file, +# sometimes in the cc file. +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(t) <= yyeof_) + return yyeof_; + else if (static_cast (t) <= user_token_number_max_) + return translate_table[t]; + else + return undef_token_; + } +]]) + # b4_lhs_value([TYPE]) # -------------------- # Expansion of $$. m4_define([b4_lhs_value], -[(yyval[]m4_ifval([$1], [.$1]))]) +[b4_symbol_value([yyval], [$1])]) # b4_rhs_value(RULE-LENGTH, NUM, [TYPE]) @@ -114,7 +369,8 @@ m4_define([b4_lhs_value], # Expansion of $NUM, where the current rule has RULE-LENGTH # symbols on RHS. m4_define([b4_rhs_value], -[(yysemantic_stack_@{($1) - ($2)@}m4_ifval([$3], [.$3]))]) +[b4_symbol_value([yysemantic_stack_@{($1) - ($2)@}], [$3])]) + # b4_lhs_location() # ----------------- @@ -151,24 +407,24 @@ m4_define([b4_parse_param_decl_1], # Extra initialisations of the constructor. m4_define([b4_parse_param_cons], [m4_ifset([b4_parse_param], - [ + [ b4_cc_constructor_calls(b4_parse_param)])]) m4_define([b4_cc_constructor_calls], - [m4_map_sep([b4_cc_constructor_call], [, + [m4_map_sep([b4_cc_constructor_call], [, ], [$@])]) m4_define([b4_cc_constructor_call], - [$2 ($2_yyarg)]) + [$2 ($2_yyarg)]) # b4_parse_param_vars # ------------------- # Extra instance variables. m4_define([b4_parse_param_vars], [m4_ifset([b4_parse_param], - [ + [ /* User arguments. */ b4_cc_var_decls(b4_parse_param)])]) m4_define([b4_cc_var_decls], - [m4_map_sep([b4_cc_var_decl], [ + [m4_map_sep([b4_cc_var_decl], [ ], [$@])]) m4_define([b4_cc_var_decl], - [ $1;]) + [ $1;])