]> git.saurik.com Git - bison.git/blobdiff - data/c++.m4
build: restore C90 compatibility
[bison.git] / data / c++.m4
index 946d9b695cb8010f072ce5a26f925f1f2967d149..b034a4a629e66bb33f5d980e26d982b5917544c0 100644 (file)
@@ -2,8 +2,7 @@
 
 # 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// ])])
+
+
 ## ---------------- ##
 ## 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]])
 b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
 
@@ -82,19 +93,21 @@ m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref[ ]),
              [::\([^][:]\|:[^:]\)*], [} ])[} // ]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.  ##
 ## ----------------- ##
@@ -104,13 +117,14 @@ m4_map_sep([     b4_token_enum], [,
 # 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 YYSTYPE semantic_type;]])])])
+[[    typedef ]b4_api_PREFIX[STYPE semantic_type;]])])])
 
 
 # b4_public_types_declare
@@ -118,76 +132,117 @@ m4_ifdef([b4_stype],
 # 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
+[[#ifndef ]b4_api_PREFIX[STYPE
 ]b4_semantic_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
+    {
+      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)[
+      ]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);
+
+      /// The (internal) type number (corresponding to \a type).
+      /// -1 when this symbol is empty.
+      symbol_number_type type_get () const;
 
-      /// Return the type corresponding to this state.
-      inline int type_get_ () const;
+      /// The token.
+      token_type token () const;
 
-      /// Its token.
-      inline 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])
 
 
@@ -195,83 +250,122 @@ m4_define([b4_public_types_declare],
 # ----------------------
 # Provide the implementation needed by the public types.
 m4_define([b4_public_types_define],
-[[  // symbol_base_type.
-  template <typename Exact>
-  ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type ()
-    : value()]b4_locations_if([
-    , location()])[
+[[  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)])[
+  {}
+
+  // basic_symbol.
+  template <typename Base>
+  inline
+  ]b4_parser_class_name[::basic_symbol<Base>::basic_symbol ()
+    : value ()
+  {}
+
+  template <typename Base>
+  inline
+  ]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (const basic_symbol& other)
+    : Base (other)
+    , value ()]b4_locations_if([
+    , location (other.location)])[
   {
-  }]b4_locations_if([[
+    ]b4_variant_if([b4_symbol_variant([other.type_get ()], [value], [copy],
+                                      [other.value])],
+                   [value = other.value;])[
+  }
 
-  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(
+  template <typename Base>
+  inline
+  ]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)])[
-  {
-  }
-
-  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_ ();
-  }
+    : 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 Base>
+  inline
+  ]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;
+    }
 
-  // symbol_type.
-  ]b4_parser_class_name[::symbol_type::symbol_type ()
-    : super_type ()
-    , type ()
-  {
+    // Type destructor.
+  ]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[
   }
 
-  ]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)
+  template <typename Base>
+  inline
+  void
+  ]b4_parser_class_name[::basic_symbol<Base>::move (basic_symbol& s)
   {
+    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;])[
   }
 
-  ]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)
+  // by_type.
+  inline
+  ]b4_parser_class_name[::by_type::by_type ()
+     : type (empty)
+  {}
+
+  inline
+  ]b4_parser_class_name[::by_type::by_type (const by_type& other)
+    : type (other.type)
+  {}
+
+  inline
+  ]b4_parser_class_name[::by_type::by_type (token_type t)
+    : type (yytranslate_ (t))
+  {}
+
+  inline
+  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).  */
@@ -302,8 +396,9 @@ m4_define([b4_symbol_constructor_define], [])
 # 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
@@ -375,24 +470,53 @@ m4_define([b4_parse_param_decl_1],
 # 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
+]])