From 2873fdf8b1f91a9cbc8d258367c920eb637a0099 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 18 Aug 2008 15:48:36 +0200 Subject: [PATCH 1/1] Introduce make_symbol. make_symbol provides a means to construct a full symbol (kind, value, location) in a single shot. It is meant to be a Symbol constructor, parameterized by the symbol kind so that overloading would prevent incorrect kind/value pairs. Unfortunately parameterized constructors do not work well in C++ (unless the parameter also appears as an argument, which is not acceptable), hence the use of a function instead of a constructor. * data/lalr1.cc (b4_symbol_constructor_declaration_) (b4_symbol_constructor_declarations) (b4_symbol_constructor_specialization_) (b4_symbol_constructor_specializations) (b4_symbol_constructor_definition_) (b4_symbol_constructor_definitions): New. Use them where appropriate to generate declaration, declaration of the specializations, and implementations of the templated overloaded function "make_symbol". (variant::variant): Always define a default ctor. Also provide a copy ctor. (symbol_base_type, symbol_type): New ctor overloads for value-less symbols. (symbol_type): Now public, so that functions such as yylex can use it. --- ChangeLog | 27 +++++++++++ data/lalr1.cc | 126 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 147 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2aa7ec7f..b76264cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2008-11-11 Akim Demaille + + Introduce make_symbol. + make_symbol provides a means to construct a full symbol (kind, value, + location) in a single shot. It is meant to be a Symbol constructor, + parameterized by the symbol kind so that overloading would prevent + incorrect kind/value pairs. Unfortunately parameterized constructors do + not work well in C++ (unless the parameter also appears as an argument, + which is not acceptable), hence the use of a function instead of a + constructor. + + * data/lalr1.cc (b4_symbol_constructor_declaration_) + (b4_symbol_constructor_declarations) + (b4_symbol_constructor_specialization_) + (b4_symbol_constructor_specializations) + (b4_symbol_constructor_definition_) + (b4_symbol_constructor_definitions): New. + Use them where appropriate to generate declaration, declaration of + the specializations, and implementations of the templated + overloaded function "make_symbol". + (variant::variant): Always define a default ctor. + Also provide a copy ctor. + (symbol_base_type, symbol_type): New ctor overloads for value-less + symbols. + (symbol_type): Now public, so that functions such as yylex can use + it. + 2008-11-11 Akim Demaille Inform m4 whether a tag is a valid id. diff --git a/data/lalr1.cc b/data/lalr1.cc index b00212e8..4915caa2 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -166,6 +166,86 @@ m4_define([b4_type_action_], ])]) +# 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 @@ -262,11 +342,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 @@ -288,6 +369,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& @@ -520,6 +610,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. @@ -553,6 +644,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 { @@ -566,6 +658,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; @@ -573,6 +668,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 { @@ -632,7 +730,7 @@ m4_ifdef([b4_stype], ]b4_parse_param_vars[ }; - +]b4_symbol_constructor_specializations[ ]b4_namespace_close[ ]b4_percent_define_flag_if([[global_tokens_and_yystype]], @@ -794,6 +892,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) @@ -829,6 +934,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) @@ -842,6 +954,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 () -- 2.47.2