## 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
# 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.
# 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
# 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])),
## 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 ]b4_api_PREFIX[STYPE 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 ]b4_api_PREFIX[STYPE
+]b4_semantic_type_declare[
+#else
+ typedef ]b4_api_PREFIX[STYPE 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 <typename Exact>
+ 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<symbol_type>
+ {
+ /// The parent class.
+ typedef symbol_base_type<symbol_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 <typename Exact>
+ inline
+ ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type ()
+ : value()]b4_locations_if([
+ , location()])[
+ {
+ }]b4_locations_if([[
+
+ template <typename Exact>
+ inline
+ ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type (const location_type& l)
+ : value()
+ , location(l)
+ {
+ }]])[
+
+ template <typename Exact>
+ inline
+ ]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>
+ inline
+ const Exact&
+ ]b4_parser_class_name[::symbol_base_type<Exact>::self () const
+ {
+ return static_cast<const Exact&>(*this);
+ }
+
+ template <typename Exact>
+ inline
+ Exact&
+ ]b4_parser_class_name[::symbol_base_type<Exact>::self ()
+ {
+ return static_cast<Exact&>(*this);
+ }
+
+ template <typename Exact>
+ inline
+ int
+ ]b4_parser_class_name[::symbol_base_type<Exact>::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<token_type> (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<int>(t) <= yyeof_)
+ return yyeof_;
+ else if (static_cast<unsigned int> (t) <= user_token_number_max_)
+ return translate_table[t];
+ else
+ return undef_token_;
+ }
+]])
+
# b4_lhs_value([TYPE])
# --------------------
# Expansion of $<TYPE>$.
m4_define([b4_lhs_value],
-[(yyval[]m4_ifval([$1], [.$1]))])
+[b4_symbol_value([yyval], [$1])])
# 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],
-[(yysemantic_stack_@{($1) - ($2)@}m4_ifval([$3], [.$3]))])
+[b4_symbol_value([yysemantic_stack_@{($1) - ($2)@}], [$3])])
+
# b4_lhs_location()
# -----------------
# 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;])