Share b4_yytranslate_define.
[bison/ericb.git] / data / c++.m4
blobc43a4df25d7de5e5447ba2a2e35f652829c19ae1
1                                                             -*- Autoconf -*-
3 # C++ skeleton for Bison
5 # Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
6 # Free Software Foundation, Inc.
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 m4_include(b4_pkgdatadir/[c.m4])
23 ## ---------------- ##
24 ## Default values.  ##
25 ## ---------------- ##
27 # Default parser class name.
28 b4_percent_define_default([[parser_class_name]], [[parser]])
29 b4_percent_define_default([[location_type]], [[location]])
30 b4_percent_define_default([[filename_type]], [[std::string]])
31 b4_percent_define_default([[namespace]], m4_defn([b4_prefix]))
32 b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
33 b4_percent_define_default([[define_location_comparison]],
34                           [m4_if(b4_percent_define_get([[filename_type]]),
35                                  [std::string], [[true]], [[false]])])
38 ## ----------- ##
39 ## Namespace.  ##
40 ## ----------- ##
42 m4_define([b4_namespace_ref], [b4_percent_define_get([[namespace]])])
44 # Don't permit an empty b4_namespace_ref.  Any `::parser::foo' appended to it
45 # would compile as an absolute reference with `parser' in the global namespace.
46 # b4_namespace_open would open an anonymous namespace and thus establish
47 # internal linkage.  This would compile.  However, it's cryptic, and internal
48 # linkage for the parser would be specified in all translation units that
49 # include the header, which is always generated.  If we ever need to permit
50 # internal linkage somehow, surely we can find a cleaner approach.
51 m4_if(m4_bregexp(b4_namespace_ref, [^[   ]*$]), [-1], [],
52 [b4_complain_at(b4_percent_define_get_loc([[namespace]]),
53                 [[namespace reference is empty]])])
55 # Instead of assuming the C++ compiler will do it, Bison should reject any
56 # invalid b4_namepsace_ref that would be converted to a valid
57 # b4_namespace_open.  The problem is that Bison doesn't always output
58 # b4_namespace_ref to uncommented code but should reserve the ability to do so
59 # in future releases without risking breaking any existing user grammars.
60 # Specifically, don't allow empty names as b4_namespace_open would just convert
61 # those into anonymous namespaces, and that might tempt some users.
62 m4_if(m4_bregexp(b4_namespace_ref, [::[  ]*::]), [-1], [],
63 [b4_complain_at(b4_percent_define_get_loc([[namespace]]),
64                 [[namespace reference has consecutive "::"]])])
65 m4_if(m4_bregexp(b4_namespace_ref, [::[  ]*$]), [-1], [],
66 [b4_complain_at(b4_percent_define_get_loc([[namespace]]),
67                 [[namespace reference has a trailing "::"]])])
69 m4_define([b4_namespace_open],
70 [b4_user_code([b4_percent_define_get_syncline([[namespace]])
71 [namespace ]m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref),
72                                                 [^\(.\)[         ]*::], [\1])),
73                          [::], [ { namespace ])[ {]])])
75 m4_define([b4_namespace_close],
76 [b4_user_code([b4_percent_define_get_syncline([[namespace]])
77 m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref),
78                                     [^\(.\)[     ]*\(::\)?\([^][:]\|:[^][:]\)*],
79                                     [\1])),
80              [::\([^][:]\|:[^][:]\)*], [} ])[} // ]b4_namespace_ref])])
83 # b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
84 # -----------------------------------------------------
85 # Output the definition of the tokens as enums.
86 m4_define([b4_token_enums],
87 [/* Tokens.  */
88    enum yytokentype {
89 m4_map_sep([     b4_token_enum], [,
91            [$@])
92    };
96 ## ----------------- ##
97 ## Semantic Values.  ##
98 ## ----------------- ##
100 # b4_semantic_type_declare
101 # ------------------------
102 # Declare semantic_type.
103 m4_define([b4_semantic_type_declare],
104 [    /// Symbol semantic values.
105 m4_ifdef([b4_stype],
106 [    union semantic_type
107     {b4_user_stype
108     };],
109 [m4_if(b4_tag_seen_flag, 0,
110 [[    typedef int semantic_type;]],
111 [[    typedef YYSTYPE semantic_type;]])])])
114 # b4_public_types_declare
115 # -----------------------
116 # Define the public types: token, semantic value, location, and so forth.
117 # Depending on %define token_lex, may be output in the header or source file.
118 m4_define([b4_public_types_declare],
119 [[#ifndef YYSTYPE
120 ]b4_semantic_type_declare[
121 #else
122     typedef YYSTYPE semantic_type;
123 #endif]b4_locations_if([
124     /// Symbol locations.
125     typedef b4_percent_define_get([[location_type]]) location_type;])[
127     /// Tokens.
128     struct token
129     {
130       ]b4_token_enums(b4_tokens)[
131     };
133     /// Token type.
134     typedef token::yytokentype token_type;
136     /// A complete symbol, with its type.
137     template <typename Exact>
138     struct symbol_base_type
139     {
140       /// Default constructor.
141       inline symbol_base_type ();
143       /// Constructor.]b4_locations_if([
144       inline symbol_base_type (const location_type& l)])[;
145       inline symbol_base_type (]b4_args(
146         [const semantic_type& v],
147         b4_locations_if([const location_type& l]))[);
149       /// Return this with its exact type.
150       const Exact& self () const;
151       Exact& self ();
153       /// Return the type of this symbol.
154       int type_get () const;
156       /// The semantic value.
157       semantic_type value;]b4_locations_if([
159       /// The location.
160       location_type location;])[
161     };
163     /// External form of a symbol: its type and attributes.
164     struct symbol_type : symbol_base_type<symbol_type>
165     {
166       /// The parent class.
167       typedef symbol_base_type<symbol_type> super_type;
169       /// Default constructor.
170       inline symbol_type ();
172       /// Constructor.
173       inline symbol_type (]b4_args([int t],
174                                    [const semantic_type& v],
175                                    b4_locations_if([const location_type& l]))[);
177       inline symbol_type (]b4_args([int t],
178                                    b4_locations_if([const location_type& l]))[);
180       /// The symbol type.
181       int type;
183       /// Return the type corresponding to this state.
184       inline int type_get_ () const;
186       /// Its token.
187       inline token_type token () const;
188     };
189 ]b4_symbol_constructor_declare])
192 # b4_public_types_define
193 # ----------------------
194 # Provide the implementation needed by the public types.
195 m4_define([b4_public_types_define],
196 [[  // symbol_base_type.
197   template <typename Exact>
198   ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type ()
199     : value()]b4_locations_if([
200     , location()])[
201   {
202   }]b4_locations_if([[
204   template <typename Exact>
205   ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type (const location_type& l)
206     : value()
207     , location(l)
208   {
209   }]])[
211   template <typename Exact>
212   ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type (]b4_args(
213           [const semantic_type& v],
214           b4_locations_if([const location_type& l]))[)
215     : value(v)]b4_locations_if([
216     , location(l)])[
217   {
218   }
220   template <typename Exact>
221   const Exact&
222   ]b4_parser_class_name[::symbol_base_type<Exact>::self () const
223   {
224     return static_cast<const Exact&>(*this);
225   }
227   template <typename Exact>
228   Exact&
229   ]b4_parser_class_name[::symbol_base_type<Exact>::self ()
230   {
231     return static_cast<Exact&>(*this);
232   }
234   template <typename Exact>
235   int
236   ]b4_parser_class_name[::symbol_base_type<Exact>::type_get () const
237   {
238     return self ().type_get_ ();
239   }
241   // symbol_type.
242   ]b4_parser_class_name[::symbol_type::symbol_type ()
243     : super_type ()
244     , type ()
245   {
246   }
248   ]b4_parser_class_name[::symbol_type::symbol_type (]b4_args(
249                 [int t],
250                 b4_locations_if([const location_type& l]))[)
251     : super_type (]b4_locations_if([l])[)
252     , type (t)
253   {
254   }
256   ]b4_parser_class_name[::symbol_type::symbol_type (]b4_args(
257                  [int t],
258                  [const semantic_type& v],
259                  b4_locations_if([const location_type& l]))[)
260     : super_type (v]b4_locations_if([, l])[)
261     , type (t)
262   {
263   }
265   int
266   ]b4_parser_class_name[::symbol_type::type_get_ () const
267   {
268     return type;
269   }
270 ]b4_lex_symbol_if([[
271   ]b4_parser_class_name[::token_type
272   ]b4_parser_class_name[::symbol_type::token () const
273   {
274     // YYTOKNUM[NUM] -- (External) token number corresponding to the
275     // (internal) symbol number NUM (which must be that of a token).  */
276     static
277     const ]b4_int_type_for([b4_toknum])[
278     yytoken_number_[] =
279     {
280   ]b4_toknum[
281     };
282     return static_cast<token_type> (yytoken_number_[type]);
283   }
284 ]])[]dnl
285 b4_symbol_constructor_define])
288 # b4_symbol_constructor_declare
289 # b4_symbol_constructor_define
290 # -----------------------------
291 # Declare/define symbol constructors for all the value types.
292 # Use at class-level.  Redefined in variant.hh.
293 m4_define([b4_symbol_constructor_declare], [])
294 m4_define([b4_symbol_constructor_define], [])
297 # b4_yytranslate_define
298 # ---------------------
299 # Define yytranslate_.  Sometimes used in the header file,
300 # sometimes in the cc file.
301 m4_define([b4_yytranslate_define],
302 [[  // Symbol number corresponding to token number t.
303   ]b4_parser_class_name[::token_number_type
304   ]b4_parser_class_name[::yytranslate_ (]b4_lex_symbol_if([token_type],
305                                                           [int])[ t)
306   {
307     static
308     const token_number_type
309     translate_table[] =
310     {
311 ]b4_translate[
312     };
313     const unsigned int user_token_number_max_ = ]b4_user_token_number_max[;
314     const token_number_type undef_token_ = ]b4_undef_token_number[;
316     if (static_cast<int>(t) <= yyeof_)
317       return yyeof_;
318     else if (static_cast<unsigned int> (t) <= user_token_number_max_)
319       return translate_table[t];
320     else
321       return undef_token_;
322   }
326 # b4_lhs_value([TYPE])
327 # --------------------
328 # Expansion of $<TYPE>$.
329 m4_define([b4_lhs_value],
330 [b4_symbol_value([yyval], [$1])])
333 # b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
334 # --------------------------------------
335 # Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
336 # symbols on RHS.
337 m4_define([b4_rhs_value],
338 [b4_symbol_value([yysemantic_stack_@{($1) - ($2)@}], [$3])])
341 # b4_lhs_location()
342 # -----------------
343 # Expansion of @$.
344 m4_define([b4_lhs_location],
345 [(yyloc)])
348 # b4_rhs_location(RULE-LENGTH, NUM)
349 # ---------------------------------
350 # Expansion of @NUM, where the current rule has RULE-LENGTH symbols
351 # on RHS.
352 m4_define([b4_rhs_location],
353 [(yylocation_stack_@{($1) - ($2)@})])
356 # b4_parse_param_decl
357 # -------------------
358 # Extra formal arguments of the constructor.
359 # Change the parameter names from "foo" into "foo_yyarg", so that
360 # there is no collision bw the user chosen attribute name, and the
361 # argument name in the constructor.
362 m4_define([b4_parse_param_decl],
363 [m4_ifset([b4_parse_param],
364           [m4_map_sep([b4_parse_param_decl_1], [, ], [b4_parse_param])])])
366 m4_define([b4_parse_param_decl_1],
367 [$1_yyarg])
371 # b4_parse_param_cons
372 # -------------------
373 # Extra initialisations of the constructor.
374 m4_define([b4_parse_param_cons],
375           [m4_ifset([b4_parse_param],
376                     [
377       b4_cc_constructor_calls(b4_parse_param)])])
378 m4_define([b4_cc_constructor_calls],
379           [m4_map_sep([b4_cc_constructor_call], [,
380       ], [$@])])
381 m4_define([b4_cc_constructor_call],
382           [$2 ($2_yyarg)])
384 # b4_parse_param_vars
385 # -------------------
386 # Extra instance variables.
387 m4_define([b4_parse_param_vars],
388           [m4_ifset([b4_parse_param],
389                     [
390     /* User arguments.  */
391 b4_cc_var_decls(b4_parse_param)])])
392 m4_define([b4_cc_var_decls],
393           [m4_map_sep([b4_cc_var_decl], [
394 ], [$@])])
395 m4_define([b4_cc_var_decl],
396           [    $1;])