Hi, using the lalr1.cc skeleton with api.value.type variant, Bison generates one symbol constructor for each value type.
This produces conflicts if two types are equivalent, but spelled differently so Bison can't see it (this might be as simple as int vs. int32_t or int64_t, depending on the ABI, a typedef, or something complex with templates). I reported a similar issue with the token constructors in https://lists.gnu.org/archive/html/bug-bison/2019-05/msg00044.html but this one is about all types, including nonterminals. While the token constructor issue is not an urgent problem to me, like I wrote then, this one is getting more pressing to me. On the bright side, as I noticed back then, an obstacle to changing the token constructors is their use of YYASSERT. The symbol constructors don't do this, so it seems to me we don't really need distinct ones for the various types (along with the SFINAE hacks I described there), but a single templated one plus an untyped one should do. The following patch works for me. I see no adverse effects in any of my parsers. The skeletons already use templates, so this should not introduce any new dependency. --- data/skeletons/c++.m4 +++ data/skeletons/c++.m4 @@ -329,8 +329,41 @@ basic_symbol (const basic_symbol& that);]b4_variant_if([[ /// Constructors for typed symbols. -]b4_type_foreach([b4_basic_symbol_constructor_define], [ -])], [[ +#if 201103L <= YY_CPLUSPLUS + basic_symbol (]b4_join( + [typename Base::kind_type t], + b4_locations_if([location_type&& l]))[) + : Base (t)][]b4_locations_if([ + , location (std::move (l))])[ + {} + + template <typename T> + basic_symbol (]b4_join( + [typename Base::kind_type t], + [T&& v], + b4_locations_if([location_type&& l]))[) + : Base (t) + , value (std::move (v))][]b4_locations_if([ + , location (std::move (l))])[ + {} +#else + basic_symbol (]b4_join( + [typename Base::kind_type t], + b4_locations_if([const location_type& l]))[) + : Base (t)][]b4_locations_if([ + , location (l)])[ + {} + template <typename T> + basic_symbol (]b4_join( + [typename Base::kind_type t], + [const T& v], + b4_locations_if([const location_type& l]))[) + : Base (t) + , value (v)][]b4_locations_if([ + , location (l)])[ + {} +#endif +]], [[ /// Constructor for valueless symbols. basic_symbol (typename Base::kind_type t]b4_locations_if([, YY_MOVE_REF (location_type) l])[); --- data/skeletons/variant.hh +++ data/skeletons/variant.hh @@ -491,32 +491,6 @@ ]])]) -# b4_basic_symbol_constructor_define(SYMBOL-NUM) -# ---------------------------------------------- -# Generate a constructor for basic_symbol from given type. -m4_define([b4_basic_symbol_constructor_define], -[[#if 201103L <= YY_CPLUSPLUS - basic_symbol (]b4_join( - [typename Base::kind_type t], - b4_symbol_if([$1], [has_type], [b4_symbol([$1], [type])&& v]), - b4_locations_if([location_type&& l]))[) - : Base (t)]b4_symbol_if([$1], [has_type], [ - , value (std::move (v))])[]b4_locations_if([ - , location (std::move (l))])[ - {} -#else - basic_symbol (]b4_join( - [typename Base::kind_type t], - b4_symbol_if([$1], [has_type], [const b4_symbol([$1], [type])& v]), - b4_locations_if([const location_type& l]))[) - : Base (t)]b4_symbol_if([$1], [has_type], [ - , value (v)])[]b4_locations_if([ - , location (l)])[ - {} -#endif -]]) - - # b4_token_constructor_define # --------------------------- # Define the overloaded versions of make_FOO for all the token kinds.