# C++ skeleton for Bison
-# Copyright (C) 2002-2012 Free Software Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
m4_include(b4_pkgdatadir/[c.m4])
+# b4_comment(TEXT, [PREFIX])
+# --------------------------
+# Put TEXT in comment. Prefix all the output lines with PREFIX.
+m4_define([b4_comment],
+[b4_comment_([$1], [$2// ], [$2// ])])
+
+
## ---------------- ##
## Default values. ##
## ---------------- ##
# Don't do that so that we remember whether we're using a user
# request, or the default value.
#
-# b4_percent_define_default([[location_type]], [[location]])
+# b4_percent_define_default([[api.location.type]], [[location]])
b4_percent_define_default([[filename_type]], [[std::string]])
b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
[::\([^][:]\|:[^:]\)*], [} ])[} // ]b4_namespace_ref])])
-# b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
-# -----------------------------------------------------
+# b4_token_enums
+# --------------
# Output the definition of the tokens as enums.
m4_define([b4_token_enums],
-[/* Tokens. */
- enum yytokentype {
-m4_map_sep([ b4_token_enum], [,
-],
- [$@])
- };
+[[enum yytokentype
+ {
+ ]m4_join([,
+ ],
+ b4_symbol_map([b4_token_enum]))[
+ };]dnl
])
# Declare semantic_type.
m4_define([b4_semantic_type_declare],
[ /// Symbol semantic values.
-m4_ifdef([b4_stype],
+m4_ifdef([b4_union_members],
[ union semantic_type
- {b4_user_stype
+ {
+b4_user_union_members
};],
[m4_if(b4_tag_seen_flag, 0,
[[ typedef int semantic_type;]],
typedef ]b4_api_PREFIX[STYPE semantic_type;
#endif]b4_locations_if([
/// Symbol locations.
- typedef b4_percent_define_get([[location_type]],
+ typedef b4_percent_define_get([[api.location.type]],
[[location]]) location_type;])[
/// Syntax errors thrown from user actions.
/// Tokens.
struct token
{
- ]b4_token_enums(b4_tokens)[
+ ]b4_token_enums[
};
- /// Token type.
+ /// (External) token type, as returned by yylex.
typedef token::yytokentype token_type;
- /// A complete symbol, with its type.
- template <typename Exact>
- struct symbol_base_type
+ /// Internal symbol number.
+ typedef int symbol_number_type;
+
+ /// Internal symbol number for tokens (subsumed by symbol_number_type).
+ typedef ]b4_int_type_for([b4_translate])[ token_number_type;
+
+ /// A complete symbol.
+ ///
+ /// Expects its Base type to provide access to the symbol type
+ /// via type_get().
+ ///
+ /// Provide access to semantic value]b4_locations_if([ and location])[.
+ template <typename Base>
+ struct basic_symbol : Base
{
+ /// Alias to Base.
+ typedef Base super_type;
+
/// Default constructor.
- inline symbol_base_type ();
+ basic_symbol ();
- /// 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]))[);
+ /// Copy constructor.
+ basic_symbol (const basic_symbol& other);
+]b4_variant_if([[
+ /// Constructor for valueless symbols, and symbols from each type.
+]b4_type_foreach([b4_basic_symbol_constructor_declare])], [[
+ /// Constructor for valueless symbols.
+ basic_symbol (typename Base::kind_type t]b4_locations_if([,
+ const location_type& l])[);]])[
- /// Return this with its exact type.
- const Exact& self () const;
- Exact& self ();
+ /// Constructor for symbols with semantic value.
+ basic_symbol (typename Base::kind_type t,
+ const semantic_type& v]b4_locations_if([,
+ const location_type& l])[);
- /// Return the type of this symbol.
- int type_get () const;
+ ~basic_symbol ();
+
+ /// Destructive move, \a s is emptied into this.
+ void move (basic_symbol& s);
/// The semantic value.
semantic_type value;]b4_locations_if([
/// The location.
location_type location;])[
+
+ private:
+ /// Assignment operator.
+ basic_symbol& operator= (const basic_symbol& other);
};
- /// External form of a symbol: its type and attributes.
- struct symbol_type : symbol_base_type<symbol_type>
+ /// Type access provider for token (enum) based symbols.
+ struct by_type
{
- /// The parent class.
- typedef symbol_base_type<symbol_type> super_type;
-
/// Default constructor.
- inline symbol_type ();
+ by_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]))[);
+ /// Copy constructor.
+ by_type (const by_type& other);
- /// Constructor for valueless tokens.
- inline symbol_type (]b4_args([token_type t],
- b4_locations_if([const location_type& l]))[);
+ /// The symbol type as needed by the constructor.
+ typedef token_type kind_type;
- /// The symbol type.
- int type;
+ /// Constructor from (external) token numbers.
+ by_type (kind_type t);
- /// The symbol type.
- inline int type_get_ () const;
+ /// Steal the symbol type from \a that.
+ void move (by_type& that);
+
+ /// The (internal) type number (corresponding to \a type).
+ /// -1 when this symbol is empty.
+ symbol_number_type type_get () const;
/// The token.
- inline token_type token () const;
+ token_type token () const;
+
+ enum { empty = 0 };
+
+ /// The symbol type.
+ /// -1 when this symbol is empty.
+ token_number_type type;
};
+
+ /// "External" symbols: returned by the scanner.
+ typedef basic_symbol<by_type> symbol_type;
+
]b4_symbol_constructor_declare])
, location (l)])[
{}
- // symbol_base_type.
- template <typename Exact>
+ // basic_symbol.
+ template <typename Base>
inline
- ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type ()
- : value()]b4_locations_if([
- , location()])[
- {
- }]b4_locations_if([[
+ ]b4_parser_class_name[::basic_symbol<Base>::basic_symbol ()
+ : value ()
+ {}
- template <typename Exact>
+ template <typename Base>
inline
- ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type (const location_type& l)
- : value()
- , location(l)
+ ]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (const basic_symbol& other)
+ : Base (other)
+ , value ()]b4_locations_if([
+ , location (other.location)])[
{
- }]])[
+ ]b4_variant_if([b4_symbol_variant([other.type_get ()], [value], [copy],
+ [other.value])],
+ [value = other.value;])[
+ }
+
- template <typename Exact>
+ template <typename Base>
inline
- ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type (]b4_args(
+ ]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (]b4_join(
+ [typename Base::kind_type t],
[const semantic_type& v],
b4_locations_if([const location_type& l]))[)
- : value(v)]b4_locations_if([
- , location(l)])[
- {
- }
+ : Base (t)
+ , value (]b4_variant_if([], [v])[)]b4_locations_if([
+ , location (l)])[
+ {]b4_variant_if([[
+ (void) v;
+ ]b4_symbol_variant([this->type_get ()], [value], [copy], [v])])[}
+
+]b4_variant_if([[
+ // Implementation of basic_symbol constructor for each type.
+]b4_type_foreach([b4_basic_symbol_constructor_define])], [[
+ /// Constructor for valueless symbols.
+ template <typename Base>
+ inline
+ ]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (]b4_join(
+ [typename Base::kind_type t],
+ b4_locations_if([const location_type& l]))[)
+ : Base (t)
+ , value ()]b4_locations_if([
+ , location (l)])[
+ {}]])[
- template <typename Exact>
+ template <typename Base>
inline
- const Exact&
- ]b4_parser_class_name[::symbol_base_type<Exact>::self () const
- {
- return static_cast<const Exact&>(*this);
+ ]b4_parser_class_name[::basic_symbol<Base>::~basic_symbol ()
+ {]b4_variant_if([[
+ // User destructor.
+ symbol_number_type yytype = this->type_get ();
+ switch (yytype)
+ {
+]b4_symbol_foreach([b4_symbol_destructor])dnl
+[ default:
+ break;
+ }
+
+ // Type destructor.
+ ]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[
}
- template <typename Exact>
+ template <typename Base>
inline
- Exact&
- ]b4_parser_class_name[::symbol_base_type<Exact>::self ()
+ void
+ ]b4_parser_class_name[::basic_symbol<Base>::move (basic_symbol& s)
{
- return static_cast<Exact&>(*this);
+ super_type::move(s);
+ ]b4_variant_if([b4_symbol_variant([this->type_get ()], [value], [move],
+ [s.value])],
+ [value = s.value;])[]b4_locations_if([
+ location = s.location;])[
}
- template <typename Exact>
+ // by_type.
inline
- int
- ]b4_parser_class_name[::symbol_base_type<Exact>::type_get () const
- {
- return self ().type_get_ ();
- }
+ ]b4_parser_class_name[::by_type::by_type ()
+ : type (empty)
+ {}
- // symbol_type.
inline
- ]b4_parser_class_name[::symbol_type::symbol_type ()
- : super_type ()
- , type ()
- {
- }
+ ]b4_parser_class_name[::by_type::by_type (const by_type& other)
+ : type (other.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))
- {
- }
+ ]b4_parser_class_name[::by_type::by_type (token_type t)
+ : 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))
+ void
+ ]b4_parser_class_name[::by_type::move (by_type& that)
{
+ type = that.type;
+ that.type = empty;
}
inline
int
- ]b4_parser_class_name[::symbol_type::type_get_ () const
+ ]b4_parser_class_name[::by_type::type_get () const
{
return type;
}
-]b4_lex_symbol_if([[
+]b4_token_ctor_if([[
inline
]b4_parser_class_name[::token_type
- ]b4_parser_class_name[::symbol_type::token () const
+ ]b4_parser_class_name[::by_type::token () const
{
// YYTOKNUM[NUM] -- (External) token number corresponding to the
// (internal) symbol number NUM (which must be that of a token). */
# sometimes in the cc file.
m4_define([b4_yytranslate_define],
[[ // Symbol number corresponding to token number t.
+ inline
]b4_parser_class_name[::token_number_type
- ]b4_parser_class_name[::yytranslate_ (]b4_lex_symbol_if([token_type],
+ ]b4_parser_class_name[::yytranslate_ (]b4_token_ctor_if([token_type],
[int])[ t)
{
static
m4_define([b4_parse_param_vars],
[m4_ifset([b4_parse_param],
[
- /* User arguments. */
+ // User arguments.
b4_cc_var_decls(b4_parse_param)])])
m4_define([b4_cc_var_decls],
[m4_map_sep([b4_cc_var_decl], [