+# b4_subtract(LHS, RHS)
+# ---------------------
+# Evaluate LHS - RHS if they are integer literals, otherwise expand
+# to (LHS) - (RHS).
+m4_define([b4_subtract],
+[m4_bmatch([$1$2], [^[0123456789]*$],
+ [m4_eval([$1 - $2])],
+ [($1) - ($2)])])
+
+
+# b4_args(ARG1, ...)
+# _b4_args(ARG1, ...)
+# -------------------
+# Join with comma, skipping empty arguments.
+# b4_args calls itself recursively until it sees the first non-empty
+# argument, then calls _b4_args which prepends each non-empty argument
+# with a comma.
+m4_define([b4_args],
+[m4_if([$#$1],
+ [1], [],
+ [m4_ifval([$1],
+ [$1[]_$0(m4_shift($@))],
+ [$0(m4_shift($@))])])])
+
+# _b4_args(ARGS1, ...)
+# --------------------
+m4_define([_b4_args],
+[m4_if([$#$1],
+ [1], [],
+ [m4_ifval([$1], [, $1])[]$0(m4_shift($@))])])
+
+
+# b4_table_define(TABLE-NAME, CONTENT)
+# ------------------------------------
+# Define "parser::yy<TABLE-NAME>_" which contents is CONTENT.
+m4_define([b4_table_define],
+[const b4_int_type_for([$2])
+ b4_parser_class_name::yy$1_[[]] =
+ {
+ $2
+ }dnl
+])
+
+# b4_symbol_value_template(VAL, [TYPE])
+# -------------------------------------
+# Same as b4_symbol_value, but used in a template method.
+m4_copy([b4_symbol_value], [b4_symbol_value_template])
+
+# How the semantic value is extracted when using variants.
+b4_variant_if([
+ # b4_symbol_value(VAL, [TYPE])
+ # ----------------------------
+ m4_define([b4_symbol_value],
+ [m4_ifval([$2],
+ [$1.as< $2 >()],
+ [$1])])
+
+ # b4_symbol_value_template(VAL, [TYPE])
+ # -------------------------------------
+ # Same as b4_symbol_value, but used in a template method.
+ m4_define([b4_symbol_value_template],
+ [m4_ifval([$2],
+ [$1.template as< $2 >()],
+ [$1])])
+]) # 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],
+[b4_percent_define_ifdef([[assert]], [$1], [$2])])
+
+
+# b4_lhs_value([TYPE])
+# --------------------
+# Expansion of $<TYPE>$.
+m4_define([b4_lhs_value],
+[b4_symbol_value([yylhs.value], [$1])])
+
+
+# b4_lhs_location()
+# -----------------
+# Expansion of @$.
+m4_define([b4_lhs_location],
+[yylhs.location])
+
+
+# b4_rhs_data(RULE-LENGTH, NUM)
+# -----------------------------
+# Return the data corresponding to the symbol #NUM, where the current
+# rule has RULE-LENGTH symbols on RHS.
+m4_define([b4_rhs_data],
+ [yystack_@{b4_subtract($@)@}])
+
+
+# b4_rhs_state(RULE-LENGTH, NUM)
+# -----------------------------
+# The state corresponding to the symbol #NUM, where the current
+# rule has RULE-LENGTH symbols on RHS.
+m4_define([b4_rhs_state],
+ [b4_rhs_data([$1], [$2]).state])
+
+
+# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
+# --------------------------------------
+# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
+# symbols on RHS.
+m4_define([b4_rhs_value],
+ [b4_symbol_value([b4_rhs_data([$1], [$2]).value], [$3])])
+
+
+# b4_rhs_location(RULE-LENGTH, NUM)
+# ---------------------------------
+# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
+# on RHS.
+m4_define([b4_rhs_location],
+ [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(NUM, FIELD)
+# ---------------------
+# Recover a FIELD about symbol #NUM. Thanks to m4_indir, fails if
+# undefined. If FIELD = id, prepend the prefix.
+m4_define([b4_symbol],
+[m4_case([$2],
+ [id], [m4_do([b4_percent_define_get([token.prefix])],
+ [b4_symbol_([$1], [id])])],
+ [b4_symbol_($@)])])
+
+
+# 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],
+[m4_map([b4_symbol_case_], [$@])[]dnl
+ b4_dollar_dollar([b4_symbol([$1], [number])],
+ [b4_symbol([$1], [tag])],
+ [b4_symbol([$1], [type])]);
+ break;
+
+])])
+
+
+# b4_symbol_constructor_declaration_(SYMBOL-NUMBER)
+# -------------------------------------------------
+# 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_],
+[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
+[ static inline
+ symbol_type
+ make_[]b4_symbol_([$1], [id]) (dnl
+b4_args(b4_symbol_if([$1], [has_type],
+ [const b4_symbol([$1], [type])& v]),
+ b4_locations_if([const location_type& l])));
+
+])])])
+
+
+# b4_symbol_constructor_declarations
+# ----------------------------------
+# Declare symbol constructors for all the value types.
+# Use at class-level.
+m4_define([b4_symbol_constructor_declarations],
+[b4_variant_if([
+ // Symbol constructors declarations.
+m4_map([b4_symbol_constructor_declaration_], m4_defn([b4_symbol_numbers]))])])
+
+
+
+# b4_symbol_constructor_definition_(SYMBOL-NUMBER)
+# ------------------------------------------------
+# Define symbol constructor for this SYMBOL-NUMBER.
+m4_define([b4_symbol_constructor_definition_],
+[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
+[ b4_parser_class_name::symbol_type
+ b4_parser_class_name::make_[]b4_symbol_([$1], [id]) (dnl
+b4_args(b4_symbol_if([$1], [has_type],
+ [const b4_symbol([$1], [type])& v]),
+ b4_locations_if([const location_type& l])))
+ {
+ return symbol_type (b4_args([yytranslate_ (token::b4_symbol([$1], [id]))],
+ b4_symbol_if([$1], [has_type], [v]),
+ b4_locations_if([l])));
+ }
+
+])])])
+
+
+# b4_symbol_constructor_definitions
+# ----------------------------------
+# Define the overloaded versions of make_symbol for all the value types.
+m4_define([b4_symbol_constructor_definitions],
+[[ // symbol_base_type.
+ template <typename Exact>
+ ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type ()
+ : value()]b4_locations_if([
+ , location()])[
+ {
+ }]b4_locations_if([[
+
+ template <typename Exact>
+ ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type (const location_type& l)
+ : value()
+ , location(l)
+ {
+ }]])[
+
+ template <typename Exact>
+ ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type (]b4_args(
+ [const semantic_type& v],
+ b4_locations_if([const location_type& l]))[)
+ : value(v)]b4_locations_if([
+ , location(l)])[
+ {
+ }
+
+ template <typename Exact>
+ const Exact&
+ ]b4_parser_class_name[::symbol_base_type<Exact>::self () const
+ {
+ return static_cast<const Exact&>(*this);
+ }
+
+ template <typename Exact>
+ Exact&
+ ]b4_parser_class_name[::symbol_base_type<Exact>::self ()
+ {
+ return static_cast<Exact&>(*this);
+ }
+
+ template <typename Exact>
+ int
+ ]b4_parser_class_name[::symbol_base_type<Exact>::type_get () const
+ {
+ return self ().type_get_ ();
+ }
+
+ // symbol_type.
+ ]b4_parser_class_name[::symbol_type::symbol_type ()
+ : super_type ()
+ , type ()
+ {
+ }
+
+ ]b4_parser_class_name[::symbol_type::symbol_type (]b4_args(
+ [int t],
+ b4_locations_if([const location_type& l]))[)
+ : super_type (]b4_locations_if([l])[)
+ , type (t)
+ {
+ }
+
+ ]b4_parser_class_name[::symbol_type::symbol_type (]b4_args(
+ [int t],
+ [const semantic_type& v],
+ b4_locations_if([const location_type& l]))[)
+ : super_type (v]b4_locations_if([, l])[)
+ , type (t)
+ {
+ }
+
+ int
+ ]b4_parser_class_name[::symbol_type::type_get_ () const
+ {
+ return type;
+ }
+]b4_lex_symbol_if([[
+ ]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<token_type> (yytoken_number_[type]);
+ }
+]])[
+
+]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)
+# ---------------------------
+# A comment describing this symbol.
+m4_define([b4_char_sizeof_],
+[ // b4_symbol([$1], [tag])
+])
+
+# b4_char_sizeof(SYMBOL-NUMS)
+# --------------------------
+# 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.
+m4_define([b4_char_sizeof],
+[b4_symbol_if([$1], [has_type],
+[
+m4_map([b4_char_sizeof_], [$@])dnl
+ char _b4_char_sizeof_dummy@{sizeof([b4_symbol([$1], [type])])@};
+])])
+
+
+# b4_yytranslate_definition
+# -------------------------
+# Define yytranslate_. Sometimes we want it in the header file,
+# sometimes the cc file suffices.
+m4_define([b4_yytranslate_definition],
+[[ // 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<int>(t) <= yyeof_)
+ return yyeof_;
+ else if (static_cast<unsigned int> (t) <= user_token_number_max_)
+ return translate_table[t];
+ else
+ return undef_token_;
+ }
+]])
+
+
+m4_pushdef([b4_copyright_years],
+ [2002, 2003, 2004, 2005, 2006, 2007, 2008])
+
+m4_define([b4_parser_class_name],
+ [b4_percent_define_get([[parser_class_name]])])
+