-[(yylocation_stack_@{m4_eval([$1 - $2])@})])
-
-
-# b4_parse_param_decl
-# -------------------
-# Extra formal arguments of the constructor.
-# Change the parameter names from "foo" into "foo_yyarg", so that
-# there is no collision bw the user chosen attribute name, and the
-# argument name in the constructor.
-m4_define([b4_parse_param_decl],
-[m4_ifset([b4_parse_param],
- [m4_map_sep([b4_parse_param_decl_1], [, ], [b4_parse_param])])])
-
-m4_define([b4_parse_param_decl_1],
-[$1_yyarg])
-
-
-
-# b4_parse_param_cons
-# -------------------
-# 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_define([b4_cc_constructor_call],
- [$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_define([b4_cc_var_decl],
- [ $1;])
+ [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)
+# -------------------------------------------------
+# Same as in C, but using references instead of pointers.
+m4_define([b4_symbol_actions],
+[m4_pushdef([b4_dollar_dollar],
+ [b4_symbol_value_template([yysym.value], [$6])])dnl
+m4_pushdef([b4_at_dollar], [yysym.location])dnl
+ case $4: // $3
+b4_syncline([$2], [$1])
+ $5;
+b4_syncline([@oline@], [@ofile@])
+ break;
+m4_popdef([b4_at_dollar])dnl
+m4_popdef([b4_dollar_dollar])dnl
+])
+
+
+# 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 <token_type>
+ 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 <b4_parser_class_name::token::b4_symbol([$1], [tag])> (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 <b4_parser_class_name::token::b4_symbol([$1], [tag])> (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
+# YYTYPE.
+m4_define([b4_symbol_variant],
+[m4_pushdef([b4_dollar_dollar],
+ [$2.$3<$][3>(m4_shift3($@))])dnl
+ switch ($1)
+ {
+m4_map([b4_type_action_], m4_defn([b4_type_names]))[]dnl
+ default:
+ break;
+ }
+m4_popdef([b4_dollar_dollar])dnl
+])
+
+
+# _b4_char_sizeof_counter
+# -----------------------
+# A counter used by _b4_char_sizeof_dummy to create fresh symbols.
+m4_define([_b4_char_sizeof_counter],
+[0])
+
+# _b4_char_sizeof_dummy
+# ---------------------
+# At each call return a new C++ identifier.
+m4_define([_b4_char_sizeof_dummy],
+[m4_define([_b4_char_sizeof_counter], m4_incr(_b4_char_sizeof_counter))dnl
+dummy[]_b4_char_sizeof_counter])
+
+
+# b4_char_sizeof(SYMBOL-NUM)
+# --------------------------
+# To be mapped on the list of type names to produce:
+#
+# char dummy1[sizeof(type_name_1)];
+# char dummy2[sizeof(type_name_2)];
+#
+# for defined type names.
+# $3 is doubly-quoted, do not quote it again.
+m4_define([b4_char_sizeof],
+[m4_ifval(b4_symbol([$1], [type_name]),
+[
+ char _b4_char_sizeof_dummy@{sizeof([b4_symbol([$1], [type_name])])@}; // b4_symbol([$1], [tag])])dnl
+])
+