# C++ skeleton for Bison
-# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-# 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// ])])
+
+## -------- ##
+## Checks. ##
+## -------- ##
+
+b4_percent_define_check_kind([api.namespace], [code], [deprecated])
+b4_percent_define_check_kind([parser_class_name], [code], [deprecated])
+
## ---------------- ##
## Default values. ##
## ---------------- ##
b4_percent_define_default([[parser_class_name]], [[parser]])
-b4_percent_define_default([[location_type]], [[location]])
+
+# Don't do that so that we remember whether we're using a user
+# request, or the default value.
+#
+# b4_percent_define_default([[api.location.type]], [[location]])
+
b4_percent_define_default([[filename_type]], [[std::string]])
+# Make it a warning for those who used betas of Bison 3.0.
b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
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.
+# 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.
# b4_namespace_open would open an anonymous namespace and thus establish
# internal linkage. This would compile. However, it's cryptic, and internal
# linkage for the parser would be specified in all translation units that
[::\([^][:]\|:[^:]\)*], [} ])[} // ]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
])
+
+
## ----------------- ##
## Semantic Values. ##
## ----------------- ##
-# b4_semantic_type_declare
-# ------------------------
+
+
+# b4_value_type_declare
+# ---------------------
# Declare semantic_type.
-m4_define([b4_semantic_type_declare],
+m4_define([b4_value_type_declare],
+[b4_value_type_setup[]dnl
[ /// 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 YYSTYPE semantic_type;]])])])
+]m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
+[code],
+[[ typedef ]b4_percent_define_get([[api.value.type]])[ semantic_type;]],
+[m4_bmatch(b4_percent_define_get([[api.value.type]]),
+[union\|union-directive],
+[[ union semantic_type
+ {
+ ]b4_user_union_members[
+ };]])])dnl
+])
# 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 YYSTYPE
-]b4_semantic_type_declare[
+[[#ifndef ]b4_api_PREFIX[STYPE
+]b4_value_type_declare[
#else
- typedef YYSTYPE semantic_type;
+ typedef ]b4_api_PREFIX[STYPE semantic_type;
#endif]b4_locations_if([
/// Symbol locations.
- typedef b4_percent_define_get([[location_type]]) location_type;])[
+ typedef b4_percent_define_get([[api.location.type]],
+ [[location]]) location_type;])[
/// Syntax errors thrown from user actions.
struct syntax_error : std::runtime_error
/// 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.
- inline symbol_type (]b4_args([int t],
- [const semantic_type& v],
- b4_locations_if([const location_type& l]))[);
+ /// Copy constructor.
+ by_type (const by_type& other);
- inline symbol_type (]b4_args([int 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);
+
+ /// Steal the symbol type from \a that.
+ void move (by_type& that);
- /// Return the type corresponding to this state.
- inline int type_get_ () const;
+ /// The (internal) type number (corresponding to \a type).
+ /// -1 when this symbol is empty.
+ symbol_number_type type_get () const;
- /// Its token.
- inline token_type token () const;
+ /// The token.
+ 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(
- [int t],
- b4_locations_if([const location_type& l]))[)
- : super_type (]b4_locations_if([l])[)
- , type (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(
- [int t],
- [const semantic_type& v],
- b4_locations_if([const location_type& l]))[)
- : super_type (v]b4_locations_if([, l])[)
- , type (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
# 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. */
+ [
+ // 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;])
+
+
+## ---------##
+## Values. ##
+## ---------##
+
+# b4_yylloc_default_define
+# ------------------------
+# Define YYLLOC_DEFAULT.
+m4_define([b4_yylloc_default_define],
+[[/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+# ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (N) \
+ { \
+ (Current).begin = YYRHSLOC (Rhs, 1).begin; \
+ (Current).end = YYRHSLOC (Rhs, N).end; \
+ } \
+ else \
+ { \
+ (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end; \
+ } \
+ while (/*CONSTCOND*/ false)
+# endif
+]])
+
+## -------- ##
+## Checks. ##
+## -------- ##
+
+b4_token_ctor_if([b4_variant_if([],
+ [b4_fatal_at(b4_percent_define_get_loc(api.token.constructor),
+ [cannot use '%s' without '%s'],
+ [%define api.token.constructor],
+ [%define api.value.type variant]))])])