]> git.saurik.com Git - bison.git/blob - data/glr.cc
9322cf5ed1fb0b1b6d728b1dacc3b7a92c908f1e
[bison.git] / data / glr.cc
1 m4_divert(-1) -*- C -*-
2
3 # C++ GLR skeleton for Bison
4 # Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301 USA
20
21
22 # This skeleton produces a C++ class that encapsulates a C glr parser.
23 # This is in order to reduce the maintenance burden. The glr.c
24 # skeleton is clean and pure enough so that there are no real
25 # problems. The C++ interface is the same as that of lalr1.cc. In
26 # fact, glr.c can replace yacc.c without the user noticing any
27 # difference, and similarly for glr.cc replacing lalr1.cc.
28 #
29 # The passing of parse-params
30 #
31 # The additional arguments are stored as members of the parser
32 # object, yyparser. The C routines need to carry yyparser
33 # throughout the C parser; that easy: just let yyparser become an
34 # additional parse-param. But because the C++ skeleton needs to
35 # know the "real" original parse-param, we save them
36 # (b4_parse_param_orig). Note that b4_parse_param is overquoted
37 # (and c.m4 strips one level of quotes). This is a PITA, and
38 # explains why there are so many levels of quotes.
39 #
40 # The locations
41 #
42 # We use location.cc just like lalr1.cc, but because glr.c stores
43 # the locations in a (C++) union, the position and location classes
44 # must not have a constructor. Therefore, contrary to lalr1.cc, we
45 # must not define "b4_location_constructors". As a consequence the
46 # user must initialize the first positions (in particular the
47 # filename member).
48
49
50 # We require a pure interface using locations.
51 m4_define([b4_location_flag], [1])
52 m4_define([b4_pure], [1])
53
54 m4_include(b4_pkgdatadir/[c++.m4])
55 m4_include(b4_pkgdatadir/[location.cc])
56
57
58 # Save the parse parameters.
59 m4_define([b4_parse_param_orig], m4_defn([b4_parse_param]))
60
61
62 # b4_yy_symbol_print_generate
63 # ---------------------------
64 # Bypass the default implementation to generate the "yy_symbol_print"
65 # and "yy_symbol_value_print" functions.
66 m4_define([b4_yy_symbol_print_generate],
67 [[
68 /*--------------------.
69 | Print this symbol. |
70 `--------------------*/
71
72 ]b4_c_ansi_function_def([yy_symbol_print],
73 [static void],
74 [[FILE *], []],
75 [[int yytype], [yytype]],
76 [[const b4_namespace::b4_parser_class_name::semantic_type *yyvaluep],
77 [yyvaluep]],
78 [[const b4_namespace::b4_parser_class_name::location_type *yylocationp],
79 [yylocationp]],
80 b4_parse_param)[
81 {
82 ]b4_parse_param_use[]dnl
83 [ yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_location_if([, yylocationp])[);
84 }
85 ]])
86
87
88 # Declare yyerror.
89 m4_append([b4_post_prologue],
90 [/* Line __line__ of glr.cc. */
91 b4_syncline([@oline@], [@ofile@])
92
93 b4_c_ansi_function_decl([yyerror],
94 [static void],
95 [[b4_namespace::b4_parser_class_name::location_type *yylocationp], [yylocationp]],
96 b4_parse_param,
97 [[const char* msg], [msg]])])
98
99
100 # Define yyerror.
101 m4_append([b4_epilogue],
102 [/* Line __line__ of glr.cc. */
103 b4_syncline([@oline@], [@ofile@])[
104 /*------------------.
105 | Report an error. |
106 `------------------*/
107
108 ]b4_c_ansi_function_def([yyerror],
109 [static void],
110 [[b4_namespace::b4_parser_class_name::location_type *yylocationp], [yylocationp]],
111 b4_parse_param,
112 [[const char* msg], [msg]])[
113 {
114 ]b4_parse_param_use[]dnl
115 [ yyparser.error (*yylocationp, msg);
116 }
117
118
119 namespace ]b4_namespace[
120 {
121 ]dnl In this section, the parse param are the original parse_params.
122 m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
123 [ /// Build a parser object.
124 ]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)
125 : yycdebug_ (&std::cerr)]b4_parse_param_cons[
126 {
127 }
128
129 ]b4_parser_class_name::~b4_parser_class_name[ ()
130 {
131 }
132
133 int
134 ]b4_parser_class_name[::parse ()
135 {
136 return ::yyparse (*this]b4_user_args[);
137 }
138
139 #if YYDEBUG
140 /*--------------------.
141 | Print this symbol. |
142 `--------------------*/
143
144 inline void
145 ]b4_parser_class_name[::yy_symbol_value_print_ (int yytype,
146 const semantic_type* yyvaluep, const location_type* yylocationp)
147 {
148 /* Pacify ``unused variable'' warnings. */
149 YYUSE (yyvaluep);
150 YYUSE (yylocationp);
151 switch (yytype)
152 {
153 ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl
154 [ default:
155 break;
156 }
157 }
158
159
160 void
161 ]b4_parser_class_name[::yy_symbol_print_ (int yytype,
162 const semantic_type* yyvaluep, const location_type* yylocationp)
163 {
164 *yycdebug_ << (yytype < YYNTOKENS ? "token" : "nterm")
165 << ' ' << yytname[yytype] << " ("
166 << *yylocationp << ": ";
167 yy_symbol_value_print_ (yytype, yyvaluep, yylocationp);
168 *yycdebug_ << ')';
169 }
170
171 std::ostream&
172 ]b4_parser_class_name[::debug_stream () const
173 {
174 return *yycdebug_;
175 }
176
177 void
178 ]b4_parser_class_name[::set_debug_stream (std::ostream& o)
179 {
180 yycdebug_ = &o;
181 }
182
183
184 ]b4_parser_class_name[::debug_level_type
185 ]b4_parser_class_name[::debug_level () const
186 {
187 return ::yydebug;
188 }
189
190 void
191 ]b4_parser_class_name[::set_debug_level (debug_level_type l)
192 {
193 ::yydebug = l;
194 }
195
196 #endif /* ! YYDEBUG */
197 ]m4_popdef([b4_parse_param])dnl
198 [} // namespace ]b4_namespace[
199
200 ]])
201
202
203 # Let glr.c believe that the user arguments include the parser itself.
204 m4_ifset([b4_parse_param],
205 [m4_pushdef([b4_parse_param],
206 m4_dquote([[[b4_namespace::b4_parser_class_name& yyparser], [[yyparser]]],]
207 m4_defn([b4_parse_param])))],
208 [m4_pushdef([b4_parse_param],
209 [[[[b4_namespace::b4_parser_class_name& yyparser], [[yyparser]]]]])
210 ])
211 m4_include(b4_pkgdatadir/[glr.c])
212 m4_popdef([b4_parse_param])
213
214
215 @output @output_header_name@
216 b4_copyright([Skeleton interface for Bison GLR parsers in C++],
217 [2002, 2003, 2004, 2005, 2006])
218 [
219 /* As a special exception, you may create a larger work that contains
220 part or all of the Bison parser skeleton and distribute that work
221 under terms of your choice, so long as that work isn't itself a
222 parser generator using the skeleton or a modified version thereof
223 as a parser skeleton. Alternatively, if you modify or redistribute
224 the parser skeleton itself, you may (at your option) remove this
225 special exception, which will cause the skeleton and the resulting
226 Bison output files to be licensed under the GNU General Public
227 License without this special exception.
228
229 This special exception was added by the Free Software Foundation in
230 version 2.2 of Bison. */
231
232 /* C++ GLR parser skeleton written by Akim Demaille. */
233
234 #ifndef PARSER_HEADER_H
235 # define PARSER_HEADER_H
236
237 #include <string>
238 #include <iostream>
239
240 /* Using locations. */
241 #define YYLSP_NEEDED ]b4_locations_flag[
242
243 namespace ]b4_namespace[
244 {
245 class position;
246 class location;
247 }
248
249 /* Copy the first part of user declarations. */
250 ]b4_pre_prologue[
251
252 ]/* Line __line__ of glr.cc. */
253 b4_syncline([@oline@], [@ofile@])[
254
255 #include "location.hh"
256
257 /* Enabling traces. */
258 #ifndef YYDEBUG
259 # define YYDEBUG ]b4_debug[
260 #endif
261
262 /* Enabling verbose error messages. */
263 #ifdef YYERROR_VERBOSE
264 # undef YYERROR_VERBOSE
265 # define YYERROR_VERBOSE 1
266 #else
267 # define YYERROR_VERBOSE ]b4_error_verbose[
268 #endif
269
270 /* Enabling the token table. */
271 #ifndef YYTOKEN_TABLE
272 # define YYTOKEN_TABLE ]b4_token_table[
273 #endif
274
275 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
276 If N is 0, then set CURRENT to the empty location which ends
277 the previous symbol: RHS[0] (always defined). */
278
279 #ifndef YYLLOC_DEFAULT
280 # define YYLLOC_DEFAULT(Current, Rhs, N) \
281 do \
282 if (N) \
283 { \
284 (Current).begin = YYRHSLOC (Rhs, 1).begin; \
285 (Current).end = YYRHSLOC (Rhs, N).end; \
286 } \
287 else \
288 { \
289 (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end; \
290 } \
291 while (/*CONSTCOND*/ 0)
292 #endif
293
294 namespace ]b4_namespace[
295 {
296 /// A Bison parser.
297 class ]b4_parser_class_name[
298 {
299 public:
300 /// Symbol semantic values.
301 #ifndef YYSTYPE
302 ]m4_ifdef([b4_stype],
303 [ union semantic_type
304 b4_stype
305 /* Line __line__ of lalr1.cc. */
306 b4_syncline([@oline@], [@ofile@])
307 ;],
308 [ typedef int semantic_type;])[
309 #else
310 typedef YYSTYPE semantic_type;
311 #endif
312 /// Symbol locations.
313 typedef ]b4_location_type[ location_type;
314 /// Tokens.
315 struct token
316 {
317 ]b4_token_enums(b4_tokens)[
318 };
319 /// Token type.
320 typedef token::yytokentype token_type;
321
322 /// Build a parser object.
323 ]b4_parser_class_name[ (]b4_parse_param_decl[);
324 virtual ~]b4_parser_class_name[ ();
325
326 /// Parse.
327 /// \returns 0 iff parsing succeeded.
328 virtual int parse ();
329
330 /// The current debugging stream.
331 std::ostream& debug_stream () const;
332 /// Set the current debugging stream.
333 void set_debug_stream (std::ostream &);
334
335 /// Type for debugging levels.
336 typedef int debug_level_type;
337 /// The current debugging level.
338 debug_level_type debug_level () const;
339 /// Set the current debugging level.
340 void set_debug_level (debug_level_type l);
341
342 private:
343
344 public:
345 /// Report a syntax error.
346 /// \param loc where the syntax error is found.
347 /// \param msg a description of the syntax error.
348 virtual void error (const location_type& loc, const std::string& msg);
349 private:
350
351 #if YYDEBUG
352 public:
353 /// \brief Report a symbol value on the debug stream.
354 /// \param yytype The token type.
355 /// \param yyvaluep Its semantic value.
356 /// \param yylocationp Its location.
357 virtual void yy_symbol_value_print_ (int yytype,
358 const semantic_type* yyvaluep,
359 const location_type* yylocationp);
360 /// \brief Report a symbol on the debug stream.
361 /// \param yytype The token type.
362 /// \param yyvaluep Its semantic value.
363 /// \param yylocationp Its location.
364 virtual void yy_symbol_print_ (int yytype,
365 const semantic_type* yyvaluep,
366 const location_type* yylocationp);
367 private:
368 #endif /* ! YYDEBUG */
369
370
371 /// \brief Reclaim the memory associated to a symbol.
372 /// \param yymsg Why this token is reclaimed.
373 /// \param yytype The symbol type.
374 /// \param yyvaluep Its semantic value.
375 /// \param yylocationp Its location.
376 inline void yydestruct_ (const char* yymsg,
377 int yytype,
378 semantic_type* yyvaluep,
379 location_type* yylocationp);
380
381 /* Debugging. */
382 std::ostream* yycdebug_;
383 ]b4_parse_param_vars[
384 };
385
386 ]dnl Redirections for glr.c.
387 m4_ifset([b4_global_tokens_and_yystype],
388 [b4_token_defines(b4_tokens)])
389 [
390 #ifndef YYSTYPE
391 # define YYSTYPE ]b4_namespace[::]b4_parser_class_name[::semantic_type
392 #endif
393 #ifndef YYLTYPE
394 # define YYLTYPE ]b4_namespace[::]b4_parser_class_name[::location_type
395 #endif
396
397 }
398
399 #endif /* ! defined PARSER_HEADER_H */]