]> git.saurik.com Git - bison.git/blob - data/lalr1.cc
Formatting changes.
[bison.git] / data / lalr1.cc
1 # C++ skeleton for Bison
2
3 # Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 # 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 3 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, see <http://www.gnu.org/licenses/>.
18
19 m4_include(b4_pkgdatadir/[c++.m4])
20
21 # b4_table_define(TABLE-NAME, CONTENT)
22 # ------------------------------------
23 # Define "parser::yy<TABLE-NAME>_" which contents is CONTENT.
24 m4_define([b4_table_define],
25 [const b4_int_type_for([$2])
26 b4_parser_class_name::yy$1_[[]] =
27 {
28 $2
29 }dnl
30 ])
31
32 # b4_symbol_value_template(VAL, [TYPE])
33 # -------------------------------------
34 # Same as b4_symbol_value, but used in a template method.
35 m4_copy([b4_symbol_value], [b4_symbol_value_template])
36
37 # How the semantic value is extracted when using variants.
38 b4_variant_if([
39 # b4_symbol_value(VAL, [TYPE])
40 # ----------------------------
41 m4_define([b4_symbol_value],
42 [m4_ifval([$2],
43 [$1.as<$2>()],
44 [$1])])
45
46 # b4_symbol_value_template(VAL, [TYPE])
47 # -------------------------------------
48 # Same as b4_symbol_value, but used in a template method.
49 m4_define([b4_symbol_value_template],
50 [m4_ifval([$2],
51 [$1.template as<$2>()],
52 [$1])])
53 ]) # b4_variant_if
54
55
56 # b4_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT])
57 # ------------------------------------------------
58 m4_define([b4_assert_if],
59 [b4_percent_define_ifdef([[assert]], [$1], [$2])])
60
61
62 # b4_lhs_value([TYPE])
63 # --------------------
64 # Expansion of $<TYPE>$.
65 m4_define([b4_lhs_value],
66 [b4_symbol_value([yylhs.value], [$1])])
67
68
69 # b4_lhs_location()
70 # -----------------
71 # Expansion of @$.
72 m4_define([b4_lhs_location],
73 [yylhs.location])
74
75
76 # b4_rhs_data(RULE-LENGTH, NUM)
77 # -----------------------------
78 # Return the data corresponding to the symbol #NUM, where the current
79 # rule has RULE-LENGTH symbols on RHS.
80 m4_define([b4_rhs_data],
81 [yystack_@{($1) - ($2)@}])
82
83
84 # b4_rhs_state(RULE-LENGTH, NUM)
85 # -----------------------------
86 # The state corresponding to the symbol #NUM, where the current
87 # rule has RULE-LENGTH symbols on RHS.
88 m4_define([b4_rhs_state],
89 [b4_rhs_data([$1], [$2]).state])
90
91
92 # b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
93 # --------------------------------------
94 # Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
95 # symbols on RHS.
96 m4_define([b4_rhs_value],
97 [b4_symbol_value([b4_rhs_data([$1], [$2]).value], [$3])])
98
99
100 # b4_rhs_location(RULE-LENGTH, NUM)
101 # ---------------------------------
102 # Expansion of @NUM, where the current rule has RULE-LENGTH symbols
103 # on RHS.
104 m4_define([b4_rhs_location],
105 [b4_rhs_data([$1], [$2]).location])
106
107
108 # b4_symbol_actions(FILENAME, LINENO,
109 # SYMBOL-TAG, SYMBOL-NUM,
110 # SYMBOL-ACTION, SYMBOL-TYPENAME)
111 # -------------------------------------------------
112 # Same as in C, but using references instead of pointers.
113 m4_define([b4_symbol_actions],
114 [m4_pushdef([b4_dollar_dollar],
115 [b4_symbol_value_template([yysym.value], [$6])])dnl
116 m4_pushdef([b4_at_dollar], [yysym.location])dnl
117 case $4: // $3
118 b4_syncline([$2], [$1])
119 $5;
120 b4_syncline([@oline@], [@ofile@])
121 break;
122 m4_popdef([b4_at_dollar])dnl
123 m4_popdef([b4_dollar_dollar])dnl
124 ])
125
126
127 # b4_symbol_action_(SYMBOL-TAG, SYMBOL-NUM, SYMBOL-TYPENAME)
128 # ----------------------------------------------------------
129 # Invoke b4_dollar_dollar(SYMBOL_TYPENAME) for each symbol.
130 m4_define([b4_symbol_action_],
131 [m4_ifval($3,
132 [ case $2: // $1
133 b4_dollar_dollar($@);
134 break;
135 ])])
136
137
138 # b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS])
139 # ------------------------------------------------
140 # Run some ACTION ("build", or "destroy") on YYVAL of symbol type
141 # YYTYPE.
142 m4_define([b4_symbol_variant],
143 [m4_pushdef([b4_dollar_dollar],
144 [$2.$3<$][3>(m4_shift3($@))])dnl
145 switch ($1)
146 {
147 m4_map([b4_symbol_action_], m4_defn([b4_type_names]))
148 default:
149 break;
150 }
151 m4_popdef([b4_dollar_dollar])dnl
152 ])
153
154
155 # _b4_char_sizeof_counter
156 # -----------------------
157 # A counter used by _b4_char_sizeof_dummy to create fresh symbols.
158 m4_define([_b4_char_sizeof_counter],
159 [0])
160
161 # _b4_char_sizeof_dummy
162 # ---------------------
163 # At each call return a new C++ identifier.
164 m4_define([_b4_char_sizeof_dummy],
165 [m4_define([_b4_char_sizeof_counter], m4_incr(_b4_char_sizeof_counter))dnl
166 dummy[]_b4_char_sizeof_counter])
167
168
169 # b4_char_sizeof(SYMBOL-TAG, SYMBOL-NUM, SYMBOL-TYPENAME)
170 # -------------------------------------------------------
171 # To be mapped on the list of type names to produce:
172 #
173 # char dummy1[sizeof(type_name_1)];
174 # char dummy2[sizeof(type_name_2)];
175 #
176 # for defined type names.
177 # $3 is doubly-quoted, do not quote it again.
178 m4_define([b4_char_sizeof],
179 [m4_ifval($3,
180 [
181 char _b4_char_sizeof_dummy@{sizeof($3)@}; // $1])dnl
182 ])
183
184
185 m4_pushdef([b4_copyright_years],
186 [2002, 2003, 2004, 2005, 2006, 2007, 2008])
187
188 m4_define([b4_parser_class_name],
189 [b4_percent_define_get([[parser_class_name]])])
190
191 # The header is mandatory.
192 b4_defines_if([],
193 [b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
194
195 # Backward compatibility.
196 m4_define([b4_location_constructors])
197 m4_include(b4_pkgdatadir/[location.cc])
198
199 # We do want M4 expansion after # for CPP macros.
200 m4_changecom()
201 m4_divert_push(0)dnl
202 b4_defines_if(
203 [@output(b4_spec_defines_file@)@
204 b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
205 dnl FIXME: This is wrong, we want computed header guards.
206 [
207 /* C++ LALR(1) parser skeleton written by Akim Demaille. */
208
209 #ifndef PARSER_HEADER_H
210 # define PARSER_HEADER_H
211
212 ]b4_percent_code_get([[requires]])[
213
214 ]b4_assert_if([#include <cassert>])[
215 #include <string>
216 #include <iostream>
217 #include "stack.hh"
218
219 ]b4_namespace_open[
220 class position;
221 class location;
222 ]b4_variant_if(
223 [[
224 /// A char[S] buffer to store and retrieve objects.
225 ///
226 /// Sort of a variant, but does not keep track of the nature
227 /// of the stored data, since that knowledge is available
228 /// via the current state.
229 template <size_t S>
230 struct variant
231 {]b4_assert_if([
232 /// Whether something is contained.
233 bool built;
234
235 /// Initially uninitialized.
236 variant ()
237 : built(false)
238 {}])[
239
240 /// Instantiate a \a T in here.
241 template <typename T>
242 inline T&
243 build()
244 {]b4_assert_if([
245 assert(!built);
246 built = true;])[
247 return *new (buffer) T;
248 }
249
250 /// Accessor to a built \a T.
251 template <typename T>
252 inline T&
253 as()
254 {]b4_assert_if([
255 assert(built);])[
256 return reinterpret_cast<T&>(buffer);
257 }
258
259 /// Const accessor to a built \a T (for %printer).
260 template <typename T>
261 inline const T&
262 as() const
263 {]b4_assert_if([
264 assert(built);])[
265 return reinterpret_cast<const T&>(buffer);
266 }
267
268 /// Swap the content with \a other.
269 template <typename T>
270 inline void
271 swap(variant<S>& other)
272 {
273 std::swap(as<T>(), other.as<T>());
274 }
275
276 /// Assign the content of \a other to this.
277 /// Destroys \a other.
278 template <typename T>
279 inline void
280 build(variant<S>& other)
281 {
282 build<T>();
283 swap<T>(other);
284 other.destroy<T>();
285 }
286
287 /// Destroy the stored \a T.
288 template <typename T>
289 inline void
290 destroy()
291 {
292 as<T>().~T();]b4_assert_if([
293 built = false;])[
294 }
295
296 /// A buffer large enough to store any of the semantic values.
297 char buffer[S];
298 };
299 ]])[
300 ]b4_namespace_close[
301
302 #include "location.hh"
303
304 /* Enabling traces. */
305 #ifndef YYDEBUG
306 # define YYDEBUG ]b4_debug_flag[
307 #endif
308
309 /* Enabling verbose error messages. */
310 #ifdef YYERROR_VERBOSE
311 # undef YYERROR_VERBOSE
312 # define YYERROR_VERBOSE 1
313 #else
314 # define YYERROR_VERBOSE ]b4_error_verbose_flag[
315 #endif
316
317 /* Enabling the token table. */
318 #ifndef YYTOKEN_TABLE
319 # define YYTOKEN_TABLE ]b4_token_table[
320 #endif
321
322 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
323 If N is 0, then set CURRENT to the empty location which ends
324 the previous symbol: RHS[0] (always defined). */
325
326 #ifndef YYLLOC_DEFAULT
327 # define YYLLOC_DEFAULT(Current, Rhs, N) \
328 do { \
329 if (N) \
330 { \
331 (Current).begin = (Rhs)[1].location.begin; \
332 (Current).end = (Rhs)[N].location.end; \
333 } \
334 else \
335 { \
336 (Current).begin = (Current).end = (Rhs)[0].location.end; \
337 } \
338 } while (false)
339 #endif
340
341 ]b4_namespace_open[
342
343 /// A Bison parser.
344 class ]b4_parser_class_name[
345 {
346 public:
347 #ifndef YYSTYPE
348 ]b4_variant_if(
349 [ /// An auxiliary type to compute the largest semantic type.
350 union union_type
351 {]m4_map([b4_char_sizeof], m4_defn([b4_type_names]))[
352 };
353
354 /// Symbol semantic values.
355 typedef variant<sizeof(union_type)> semantic_type;],
356 [ /// Symbol semantic values.
357 m4_ifdef([b4_stype],
358 [ union semantic_type
359 {b4_user_stype
360 };],
361 [m4_if(b4_tag_seen_flag, 0,
362 [[ typedef int semantic_type;]],
363 [[ typedef YYSTYPE semantic_type;]])])])[
364 #else
365 typedef YYSTYPE semantic_type;
366 #endif
367 /// Symbol locations.
368 typedef ]b4_percent_define_get([[location_type]])[ location_type;
369 /// Tokens.
370 struct token
371 {
372 ]b4_token_enums(b4_tokens)[
373 };
374 /// Token type.
375 typedef token::yytokentype token_type;
376
377 /// Build a parser object.
378 ]b4_parser_class_name[ (]b4_parse_param_decl[);
379 virtual ~]b4_parser_class_name[ ();
380
381 /// Parse.
382 /// \returns 0 iff parsing succeeded.
383 virtual int parse ();
384
385 #if YYDEBUG
386 /// The current debugging stream.
387 std::ostream& debug_stream () const;
388 /// Set the current debugging stream.
389 void set_debug_stream (std::ostream &);
390
391 /// Type for debugging levels.
392 typedef int debug_level_type;
393 /// The current debugging level.
394 debug_level_type debug_level () const;
395 /// Set the current debugging level.
396 void set_debug_level (debug_level_type l);
397 #endif
398
399 private:
400 /// Report a syntax error.
401 /// \param loc where the syntax error is found.
402 /// \param msg a description of the syntax error.
403 virtual void error (const location_type& loc, const std::string& msg);
404
405 /// Generate an error message.
406 /// \param state the state where the error occurred.
407 /// \param tok the lookahead token.
408 virtual std::string yysyntax_error_ (int yystate, int tok);
409
410 /// State numbers.
411 typedef int state_type;
412
413 /// Internal symbol numbers.
414 typedef ]b4_int_type_for([b4_translate])[ token_number_type;
415 /* Tables. */
416 /// For a state, the index in \a yytable_ of its portion.
417 static const ]b4_int_type_for([b4_pact])[ yypact_[];
418 static const ]b4_int_type(b4_pact_ninf, b4_pact_ninf)[ yypact_ninf_;
419
420 /// For a state, default rule to reduce.
421 /// Unless\a yytable_ specifies something else to do.
422 /// Zero means the default is an error.
423 static const ]b4_int_type_for([b4_defact])[ yydefact_[];
424
425 static const ]b4_int_type_for([b4_pgoto])[ yypgoto_[];
426 static const ]b4_int_type_for([b4_defgoto])[ yydefgoto_[];
427
428 /// What to do in a state.
429 /// \a yytable_[yypact_[s]]: what to do in state \a s.
430 /// - if positive, shift that token.
431 /// - if negative, reduce the rule which number is the opposite.
432 /// - if zero, do what YYDEFACT says.
433 static const ]b4_int_type_for([b4_table])[ yytable_[];
434 static const ]b4_int_type(b4_table_ninf, b4_table_ninf)[ yytable_ninf_;
435
436 static const ]b4_int_type_for([b4_check])[ yycheck_[];
437
438 /// For a state, its accessing symbol.
439 static const ]b4_int_type_for([b4_stos])[ yystos_[];
440
441 /// For a rule, its LHS.
442 static const ]b4_int_type_for([b4_r1])[ yyr1_[];
443 /// For a rule, its RHS length.
444 static const ]b4_int_type_for([b4_r2])[ yyr2_[];
445
446 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
447 /// For a symbol, its name in clear.
448 static const char* const yytname_[];
449 #endif
450
451 #if YYERROR_VERBOSE
452 /// Convert the symbol name \a n to a form suitable for a diagnostic.
453 virtual std::string yytnamerr_ (const char *n);
454 #endif
455
456 #if YYDEBUG
457 /// For each rule, its source line number.
458 static const ]b4_int_type_for([b4_rline])[ yyrline_[];
459 /// For each scanner token number, its symbol number.
460 static const ]b4_int_type_for([b4_toknum])[ yytoken_number_[];
461 /// Report on the debug stream that the rule \a r is going to be reduced.
462 virtual void yy_reduce_print_ (int r);
463 /// Print the state stack on the debug stream.
464 virtual void yystack_print_ ();
465
466 /* Debugging. */
467 int yydebug_;
468 std::ostream* yycdebug_;
469 #endif
470
471 /// Convert a scanner token number \a t to a symbol number.
472 token_number_type yytranslate_ (int t);
473
474 /// A complete symbol, with its type.
475 template <typename Exact>
476 struct symbol_base_type
477 {
478 /// Default constructor.
479 inline symbol_base_type ();
480
481 /// Constructor.
482 inline symbol_base_type (const semantic_type& v, const location_type& l);
483
484 /// Return this with its exact type.
485 const Exact& self () const;
486 Exact& self ();
487
488 /// Return the type of this symbol.
489 int type_get () const;
490
491 /// The semantic value.
492 semantic_type value;
493
494 /// The location.
495 location_type location;
496 };
497
498 #if YYDEBUG
499 /// \brief Display a symbol type, value and location.
500 /// \param yyo The output stream.
501 /// \param yysym The symbol.
502 template <typename Exact>
503 void yy_print_ (std::ostream& yyo,
504 const symbol_base_type<Exact>& yysym) const;
505 #endif
506
507 /// \brief Reclaim the memory associated to a symbol.
508 /// \param yymsg Why this token is reclaimed.
509 /// If null, print nothing.
510 /// \param s The symbol.
511 template <typename Exact>
512 inline void yy_destroy_ (const char* yymsg,
513 symbol_base_type<Exact>& yysym) const;
514
515 /// Element of the stack: a state and its attributes.
516 struct symbol_type : symbol_base_type<symbol_type>
517 {
518 /// The parent class.
519 typedef symbol_base_type<symbol_type> super_type;
520
521 /// Default constructor.
522 inline symbol_type ();
523
524 /// Constructor.
525 inline symbol_type (int t,
526 const semantic_type& v, const location_type& l);
527
528 /// The symbol type.
529 int type;
530
531 /// Return the type corresponding to this state.
532 inline int type_get_ () const;
533 };
534
535 /// Element of the stack: a state and its attributes.
536 struct stack_symbol_type : symbol_base_type<stack_symbol_type>
537 {
538 /// The parent class.
539 typedef symbol_base_type<stack_symbol_type> super_type;
540
541 /// Default constructor.
542 inline stack_symbol_type ();
543
544 /// Constructor.
545 inline stack_symbol_type (state_type s,
546 const semantic_type& v, const location_type& l);
547
548 /// The state.
549 state_type state;
550
551 /// Return the type corresponding to this state.
552 inline int type_get_ () const;
553 };
554
555 /// Stack type.
556 typedef stack<stack_symbol_type> stack_type;
557
558 /// The stack.
559 stack_type yystack_;
560
561 /// Push a new state on the stack.
562 /// \param m a debug message to display
563 /// if null, no trace is output.
564 /// \param s the symbol
565 /// \warning the contents of \a s.value is stolen.
566 inline void yypush_ (const char* m, stack_symbol_type& s);
567
568 /// Push a new look ahead token on the state on the stack.
569 /// \param m a debug message to display
570 /// if null, no trace is output.
571 /// \param s the state
572 /// \param sym the symbol (for its value and location).
573 /// \warning the contents of \a s.value is stolen.
574 inline void yypush_ (const char* m, state_type s, symbol_type& sym);
575
576 /// Pop \a n symbols the three stacks.
577 inline void yypop_ (unsigned int n = 1);
578
579 /* Constants. */
580 static const int yyeof_;
581 /* LAST_ -- Last index in TABLE_. */
582 static const int yylast_;
583 static const int yynnts_;
584 static const int yyempty_;
585 static const int yyfinal_;
586 static const int yyterror_;
587 static const int yyerrcode_;
588 static const int yyntokens_;
589 static const unsigned int yyuser_token_number_max_;
590 static const token_number_type yyundef_token_;
591 ]b4_parse_param_vars[
592 };
593
594 ]b4_namespace_close[
595
596 ]b4_percent_define_flag_if([[global_tokens_and_yystype]],
597 [b4_token_defines(b4_tokens)
598
599 #ifndef YYSTYPE
600 /* Redirection for backward compatibility. */
601 # define YYSTYPE b4_namespace_ref::b4_parser_class_name::semantic_type
602 #endif
603 ])
604 b4_percent_code_get([[provides]])[]dnl
605
606 [#endif /* ! defined PARSER_HEADER_H */]
607 ])dnl
608 @output(b4_parser_file_name@)@
609 b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++])
610 b4_percent_code_get([[top]])[]dnl
611 m4_if(b4_prefix, [yy], [],
612 [
613 // Take the name prefix into account.
614 #define yylex b4_prefix[]lex])[
615
616 /* First part of user declarations. */
617 ]b4_user_pre_prologue
618
619 b4_defines_if([[
620 #include "@basename(]b4_spec_defines_file[@)"]])[
621
622 /* User implementation prologue. */
623 ]b4_user_post_prologue
624 b4_percent_code_get[]dnl
625
626 [#ifndef YY_
627 # if YYENABLE_NLS
628 # if ENABLE_NLS
629 # include <libintl.h> /* FIXME: INFRINGES ON USER NAME SPACE */
630 # define YY_(msgid) dgettext ("bison-runtime", msgid)
631 # endif
632 # endif
633 # ifndef YY_
634 # define YY_(msgid) msgid
635 # endif
636 #endif
637
638 /* Suppress unused-variable warnings by "using" E. */
639 #define YYUSE(e) ((void) (e))
640
641 /* Enable debugging if requested. */
642 #if YYDEBUG
643
644 /* A pseudo ostream that takes yydebug_ into account. */
645 # define YYCDEBUG if (yydebug_) (*yycdebug_)
646
647 # define YY_SYMBOL_PRINT(Title, Symbol) \
648 do { \
649 if (yydebug_) \
650 { \
651 *yycdebug_ << Title << ' '; \
652 yy_print_ (*yycdebug_, Symbol); \
653 *yycdebug_ << std::endl; \
654 } \
655 } while (false)
656
657 # define YY_REDUCE_PRINT(Rule) \
658 do { \
659 if (yydebug_) \
660 yy_reduce_print_ (Rule); \
661 } while (false)
662
663 # define YY_STACK_PRINT() \
664 do { \
665 if (yydebug_) \
666 yystack_print_ (); \
667 } while (false)
668
669 #else /* !YYDEBUG */
670
671 # define YYCDEBUG if (false) std::cerr
672 # define YY_SYMBOL_PRINT(Title, Symbol) static_cast<void>(0)
673 # define YY_REDUCE_PRINT(Rule) static_cast<void>(0)
674 # define YY_STACK_PRINT() static_cast<void>(0)
675
676 #endif /* !YYDEBUG */
677
678 #define yyerrok (yyerrstatus_ = 0)
679 #define yyclearin (yychar = yyempty_)
680
681 #define YYACCEPT goto yyacceptlab
682 #define YYABORT goto yyabortlab
683 #define YYERROR goto yyerrorlab
684 #define YYRECOVERING() (!!yyerrstatus_)
685
686 ]b4_namespace_open[
687 #if YYERROR_VERBOSE
688
689 /* Return YYSTR after stripping away unnecessary quotes and
690 backslashes, so that it's suitable for yyerror. The heuristic is
691 that double-quoting is unnecessary unless the string contains an
692 apostrophe, a comma, or backslash (other than backslash-backslash).
693 YYSTR is taken from yytname. */
694 std::string
695 ]b4_parser_class_name[::yytnamerr_ (const char *yystr)
696 {
697 if (*yystr == '"')
698 {
699 std::string yyr = "";
700 char const *yyp = yystr;
701
702 for (;;)
703 switch (*++yyp)
704 {
705 case '\'':
706 case ',':
707 goto do_not_strip_quotes;
708
709 case '\\':
710 if (*++yyp != '\\')
711 goto do_not_strip_quotes;
712 /* Fall through. */
713 default:
714 yyr += *yyp;
715 break;
716
717 case '"':
718 return yyr;
719 }
720 do_not_strip_quotes: ;
721 }
722
723 return yystr;
724 }
725
726 #endif
727
728 /// Build a parser object.
729 ]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
730 :])[
731 #if YYDEBUG
732 ]m4_ifset([b4_parse_param], [ ], [ :])[yydebug_ (false),
733 yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
734 #endif]b4_parse_param_cons[
735 {
736 }
737
738 ]b4_parser_class_name::~b4_parser_class_name[ ()
739 {
740 }
741
742
743 /*---------------.
744 | Symbol types. |
745 `---------------*/
746
747 // symbol_base_type.
748 template <typename Exact>
749 ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type ()
750 : value()
751 , location()
752 {
753 }
754
755 template <typename Exact>
756 ]b4_parser_class_name[::symbol_base_type<Exact>::symbol_base_type (const semantic_type& v, const location_type& l)
757 : value(v)
758 , location(l)
759 {
760 }
761
762 template <typename Exact>
763 const Exact&
764 ]b4_parser_class_name[::symbol_base_type<Exact>::self () const
765 {
766 return static_cast<const Exact&>(*this);
767 }
768
769 template <typename Exact>
770 Exact&
771 ]b4_parser_class_name[::symbol_base_type<Exact>::self ()
772 {
773 return static_cast<Exact&>(*this);
774 }
775
776 template <typename Exact>
777 int
778 ]b4_parser_class_name[::symbol_base_type<Exact>::type_get () const
779 {
780 return self ().type_get_ ();
781 }
782
783 // symbol_type.
784 ]b4_parser_class_name[::symbol_type::symbol_type ()
785 : super_type ()
786 , type ()
787 {
788 }
789
790 ]b4_parser_class_name[::symbol_type::symbol_type (int t,
791 const semantic_type& v, const location_type& l)
792 : super_type (v, l)
793 , type (t)
794 {
795 }
796
797 int
798 ]b4_parser_class_name[::symbol_type::type_get_ () const
799 {
800 return type;
801 }
802
803 // stack_symbol_type.
804 ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type ()
805 : super_type ()
806 , state ()
807 {
808 }
809
810 ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type (state_type s,
811 const semantic_type& v, const location_type& l)
812 : super_type (v, l)
813 , state (s)
814 {
815 }
816
817 int
818 ]b4_parser_class_name[::stack_symbol_type::type_get_ () const
819 {
820 return yystos_[state];
821 }
822
823
824 template <typename Exact>
825 void
826 ]b4_parser_class_name[::yy_destroy_ (const char* yymsg,
827 symbol_base_type<Exact>& yysym) const
828 {
829 int yytype = yysym.type_get ();
830 YYUSE (yymsg);
831 if (yymsg)
832 YY_SYMBOL_PRINT (yymsg, yysym);
833
834 // User destructor.
835 switch (yytype)
836 {
837 ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_destructors]))[
838 default:
839 break;
840 }]b4_variant_if([
841
842 // Type destructor.
843 b4_symbol_variant([[yytype]], [[yysym.value]], [[template destroy]])])[
844 }
845
846 #if YYDEBUG
847 template <typename Exact>
848 void
849 ]b4_parser_class_name[::yy_print_ (std::ostream& yyo,
850 const symbol_base_type<Exact>& yysym) const
851 {
852 int yytype = yysym.type_get ();
853 yyo << (yytype < yyntokens_ ? "token" : "nterm")
854 << ' ' << yytname_[yytype] << " ("
855 << yysym.location << ": ";
856 switch (yytype)
857 {
858 ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl
859 [ default:
860 break;
861 }
862 yyo << ')';
863 }
864 #endif
865
866 void
867 ]b4_parser_class_name[::yypush_ (const char* m, state_type s,
868 symbol_type& sym)
869 {
870 if (m)
871 YY_SYMBOL_PRINT (m, sym);
872 ]b4_variant_if(
873 [[ yystack_.push (stack_symbol_type (s, semantic_type(), sym.location));
874 ]b4_symbol_variant([[yystos_[s]]], [[yystack_[0].value]],
875 [build], [sym.value])],
876 [ yystack_.push (stack_symbol_type (s, sym.value, sym.location));])[
877 }
878
879 void
880 ]b4_parser_class_name[::yypush_ (const char* m, stack_symbol_type& s)
881 {
882 if (m)
883 YY_SYMBOL_PRINT (m, s);
884 ]b4_variant_if(
885 [[ yystack_.push (stack_symbol_type (s.state, semantic_type(), s.location));
886 ]b4_symbol_variant([[yystos_[s.state]]], [[yystack_[0].value]],
887 [build], [s.value])],
888 [ yystack_.push (s);])[
889 }
890
891 void
892 ]b4_parser_class_name[::yypop_ (unsigned int n)
893 {
894 yystack_.pop (n);
895 }
896
897 #if YYDEBUG
898 std::ostream&
899 ]b4_parser_class_name[::debug_stream () const
900 {
901 return *yycdebug_;
902 }
903
904 void
905 ]b4_parser_class_name[::set_debug_stream (std::ostream& o)
906 {
907 yycdebug_ = &o;
908 }
909
910
911 ]b4_parser_class_name[::debug_level_type
912 ]b4_parser_class_name[::debug_level () const
913 {
914 return yydebug_;
915 }
916
917 void
918 ]b4_parser_class_name[::set_debug_level (debug_level_type l)
919 {
920 yydebug_ = l;
921 }
922 #endif
923
924 int
925 ]b4_parser_class_name[::parse ()
926 {
927 /// Coded type of the lookahead.
928 int yychar = yyempty_;
929
930 /* State. */
931 int yyn;
932 int yylen = 0;
933 int yystate = 0;
934
935 /* Error handling. */
936 int yynerrs_ = 0;
937 int yyerrstatus_ = 0;
938
939 /// The lookahead symbol.
940 symbol_type yyla;
941
942 /// The locations where the error started and ended.
943 stack_symbol_type yyerror_range[2];
944
945 /// $$ and @@$.
946 stack_symbol_type yylhs;
947
948 /// The return value of parse().
949 int yyresult;
950
951 YYCDEBUG << "Starting parse" << std::endl;
952
953 ]m4_ifdef([b4_initial_action], [
954 m4_pushdef([b4_at_dollar], [yyla.location])dnl
955 m4_pushdef([b4_dollar_dollar], [yyla.value])dnl
956 /* User initialization code. */
957 b4_user_initial_action
958 m4_popdef([b4_dollar_dollar])dnl
959 m4_popdef([b4_at_dollar])])dnl
960
961 [ /* Initialize the stack. The initial state will be set in
962 yynewstate, since the latter expects the semantical and the
963 location values to have been already stored, initialize these
964 stacks with a primary value. */
965 yystack_ = stack_type (0);
966 yypush_ (0, 0, yyla);
967
968 // A new state was pushed on the stack.
969 // Invariant: yystate == yystack_[0].state, i.e.,
970 // yystate was just pushed onto the state stack.
971 yynewstate:
972 YYCDEBUG << "Entering state " << yystate << std::endl;
973
974 /* Accept? */
975 if (yystate == yyfinal_)
976 goto yyacceptlab;
977
978 goto yybackup;
979
980 /* Backup. */
981 yybackup:
982
983 /* Try to take a decision without lookahead. */
984 yyn = yypact_[yystate];
985 if (yyn == yypact_ninf_)
986 goto yydefault;
987
988 /* Read a lookahead token. */
989 if (yychar == yyempty_)
990 {
991 YYCDEBUG << "Reading a token: ";
992 yychar = ]b4_c_function_call([yylex], [int],
993 [[YYSTYPE*], [&yyla.value]][]dnl
994 b4_locations_if([, [[location*], [&yyla.location]]])dnl
995 m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
996 }
997
998
999 /* Convert token to internal form. */
1000 if (yychar <= yyeof_)
1001 {
1002 yychar = yyla.type = yyeof_;
1003 YYCDEBUG << "Now at end of input." << std::endl;
1004 }
1005 else
1006 {
1007 yyla.type = yytranslate_ (yychar);
1008 YY_SYMBOL_PRINT ("Next token is", yyla);
1009 }
1010
1011 /* If the proper action on seeing token YYLA.TYPE is to reduce or
1012 to detect an error, take that action. */
1013 yyn += yyla.type;
1014 if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type)
1015 goto yydefault;
1016
1017 /* Reduce or error. */
1018 yyn = yytable_[yyn];
1019 if (yyn <= 0)
1020 {
1021 if (yyn == 0 || yyn == yytable_ninf_)
1022 goto yyerrlab;
1023 yyn = -yyn;
1024 goto yyreduce;
1025 }
1026
1027 /* Discard the token being shifted. */
1028 yychar = yyempty_;
1029
1030 /* Count tokens shifted since error; after three, turn off error
1031 status. */
1032 if (yyerrstatus_)
1033 --yyerrstatus_;
1034
1035 /* Shift the lookahead token. */
1036 yystate = yyn;
1037 yypush_ ("Shifting", yystate, yyla);
1038 goto yynewstate;
1039
1040 /*-----------------------------------------------------------.
1041 | yydefault -- do the default action for the current state. |
1042 `-----------------------------------------------------------*/
1043 yydefault:
1044 yyn = yydefact_[yystate];
1045 if (yyn == 0)
1046 goto yyerrlab;
1047 goto yyreduce;
1048
1049 /*-----------------------------.
1050 | yyreduce -- Do a reduction. |
1051 `-----------------------------*/
1052 yyreduce:
1053 yylen = yyr2_[yyn];]b4_variant_if([
1054 /* Variants are always initialized to an empty instance of the
1055 correct type. The default $$=$1 rule is NOT applied when using
1056 variants */
1057 ]b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])[],[
1058 /* If YYLEN is nonzero, implement the default value of the action:
1059 `$$ = $1'. Otherwise, use the top of the stack.
1060
1061 Otherwise, the following line sets YYLHS.VALUE to garbage.
1062 This behavior is undocumented and Bison
1063 users should not rely upon it. */
1064 if (yylen)
1065 yylhs.value = yystack_@{yylen - 1@}.value;
1066 else
1067 yylhs.value = yystack_@{0@}.value;])[
1068
1069 // Compute the default @@$.
1070 {
1071 slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
1072 YYLLOC_DEFAULT (yylhs.location, slice, yylen);
1073 }
1074
1075 // Perform the reduction.
1076 YY_REDUCE_PRINT (yyn);
1077 switch (yyn)
1078 {
1079 ]b4_user_actions[
1080 default:
1081 break;
1082 }
1083 // Compute post-reduction state.
1084 yyn = yyr1_[yyn];
1085 yystate = yypgoto_[yyn - yyntokens_] + yystack_[yylen].state;
1086 if (0 <= yystate && yystate <= yylast_
1087 && yycheck_[yystate] == yystack_[yylen].state)
1088 yystate = yytable_[yystate];
1089 else
1090 yystate = yydefgoto_[yyn - yyntokens_];
1091 yylhs.state = yystate;
1092 YY_SYMBOL_PRINT ("-> $$ =", yylhs);
1093 ]b4_variant_if([[
1094 // Destroy the lhs symbols.
1095 for (int i = 0; i < yylen; ++i)
1096 // Destroy a variant which value may have be swapped with
1097 // yylhs.value. The value of yylhs.value (hence maybe one of
1098 // these lhs symbols) depends on what does the default
1099 // contruction for this type. In the case of pointers for
1100 // instance, nothing is done, so the value is junk. Therefore
1101 // do not try to report the content in the debug trace, it's
1102 // junk. Hence yymsg = 0. Besides, that keeps exactly the same
1103 // traces as with the other Bison skeletons.
1104 yy_destroy_ (0, yystack_[i]);]])[
1105
1106 yypop_ (yylen);
1107 yylen = 0;
1108 YY_STACK_PRINT ();
1109
1110 /* Shift the result of the reduction. */
1111 yypush_ (0, yylhs);
1112 goto yynewstate;
1113
1114 /*------------------------------------.
1115 | yyerrlab -- here on detecting error |
1116 `------------------------------------*/
1117 yyerrlab:
1118 /* If not already recovering from an error, report this error. */
1119 if (!yyerrstatus_)
1120 {
1121 ++yynerrs_;
1122 error (yyla.location, yysyntax_error_ (yystate, yyla.type));
1123 }
1124
1125 yyerror_range[0].location = yyla.location;
1126 if (yyerrstatus_ == 3)
1127 {
1128 /* If just tried and failed to reuse lookahead token after an
1129 error, discard it. */
1130
1131 if (yychar <= yyeof_)
1132 {
1133 /* Return failure if at end of input. */
1134 if (yychar == yyeof_)
1135 YYABORT;
1136 }
1137 else
1138 {
1139 yy_destroy_ ("Error: discarding", yyla);
1140 yychar = yyempty_;
1141 }
1142 }
1143
1144 /* Else will try to reuse lookahead token after shifting the error
1145 token. */
1146 goto yyerrlab1;
1147
1148
1149 /*---------------------------------------------------.
1150 | yyerrorlab -- error raised explicitly by YYERROR. |
1151 `---------------------------------------------------*/
1152 yyerrorlab:
1153
1154 /* Pacify compilers like GCC when the user code never invokes
1155 YYERROR and the label yyerrorlab therefore never appears in user
1156 code. */
1157 if (false)
1158 goto yyerrorlab;
1159
1160 yyerror_range[0].location = yystack_[yylen - 1].location;
1161 /* Do not reclaim the symbols of the rule which action triggered
1162 this YYERROR. */
1163 yypop_ (yylen);
1164 yylen = 0;
1165 yystate = yystack_[0].state;
1166 goto yyerrlab1;
1167
1168 /*-------------------------------------------------------------.
1169 | yyerrlab1 -- common code for both syntax error and YYERROR. |
1170 `-------------------------------------------------------------*/
1171 yyerrlab1:
1172 yyerrstatus_ = 3; /* Each real token shifted decrements this. */
1173 {
1174 stack_symbol_type error_token;
1175 for (;;)
1176 {
1177 yyn = yypact_[yystate];
1178 if (yyn != yypact_ninf_)
1179 {
1180 yyn += yyterror_;
1181 if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
1182 {
1183 yyn = yytable_[yyn];
1184 if (0 < yyn)
1185 break;
1186 }
1187 }
1188
1189 // Pop the current state because it cannot handle the error token.
1190 if (yystack_.size () == 1)
1191 YYABORT;
1192
1193 yyerror_range[0].location = yystack_[0].location;
1194 yy_destroy_ ("Error: popping", yystack_[0]);
1195 yypop_ ();
1196 yystate = yystack_[0].state;
1197 YY_STACK_PRINT ();
1198 }
1199
1200 yyerror_range[1].location = yyla.location;
1201 YYLLOC_DEFAULT (error_token.location, (yyerror_range - 1), 2);
1202
1203 /* Shift the error token. */
1204 error_token.state = yystate = yyn;
1205 yypush_ ("Shifting", error_token);
1206 }
1207 goto yynewstate;
1208
1209 /* Accept. */
1210 yyacceptlab:
1211 yyresult = 0;
1212 goto yyreturn;
1213
1214 /* Abort. */
1215 yyabortlab:
1216 yyresult = 1;
1217 goto yyreturn;
1218
1219 yyreturn:
1220 if (yychar != yyempty_)
1221 yy_destroy_ ("Cleanup: discarding lookahead", yyla);
1222
1223 /* Do not reclaim the symbols of the rule which action triggered
1224 this YYABORT or YYACCEPT. */
1225 yypop_ (yylen);
1226 while (yystack_.size () != 1)
1227 {
1228 yy_destroy_ ("Cleanup: popping", yystack_[0]);
1229 yypop_ ();
1230 }
1231
1232 return yyresult;
1233 }
1234
1235 // Generate an error message.
1236 std::string
1237 ]b4_parser_class_name[::yysyntax_error_ (int yystate, int]dnl
1238 b4_error_verbose_if([ tok])[)
1239 {
1240 std::string res;
1241 YYUSE (yystate);
1242 #if YYERROR_VERBOSE
1243 int yyn = yypact_[yystate];
1244 if (yypact_ninf_ < yyn && yyn <= yylast_)
1245 {
1246 /* Start YYX at -YYN if negative to avoid negative indexes in
1247 YYCHECK. */
1248 int yyxbegin = yyn < 0 ? -yyn : 0;
1249
1250 /* Stay within bounds of both yycheck and yytname. */
1251 int yychecklim = yylast_ - yyn + 1;
1252 int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
1253 int count = 0;
1254 for (int x = yyxbegin; x < yyxend; ++x)
1255 if (yycheck_[x + yyn] == x && x != yyterror_)
1256 ++count;
1257
1258 // FIXME: This method of building the message is not compatible
1259 // with internationalization. It should work like yacc.c does it.
1260 // That is, first build a string that looks like this:
1261 // "syntax error, unexpected %s or %s or %s"
1262 // Then, invoke YY_ on this string.
1263 // Finally, use the string as a format to output
1264 // yytname_[tok], etc.
1265 // Until this gets fixed, this message appears in English only.
1266 res = "syntax error, unexpected ";
1267 res += yytnamerr_ (yytname_[tok]);
1268 if (count < 5)
1269 {
1270 count = 0;
1271 for (int x = yyxbegin; x < yyxend; ++x)
1272 if (yycheck_[x + yyn] == x && x != yyterror_)
1273 {
1274 res += (!count++) ? ", expecting " : " or ";
1275 res += yytnamerr_ (yytname_[x]);
1276 }
1277 }
1278 }
1279 else
1280 #endif
1281 res = YY_("syntax error");
1282 return res;
1283 }
1284
1285
1286 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
1287 STATE-NUM. */
1288 const ]b4_int_type(b4_pact_ninf, b4_pact_ninf) b4_parser_class_name::yypact_ninf_ = b4_pact_ninf[;
1289 ]b4_table_define([pact], [b4_pact])[;
1290
1291 /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
1292 doesn't specify something else to do. Zero means the default is an
1293 error. */
1294 ]b4_table_define([defact], [b4_defact])[;
1295
1296 /* YYPGOTO[NTERM-NUM]. */
1297 ]b4_table_define([pgoto], [b4_pgoto])[;
1298
1299 /* YYDEFGOTO[NTERM-NUM]. */
1300 ]b4_table_define([defgoto], [b4_defgoto])[;
1301
1302 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
1303 positive, shift that token. If negative, reduce the rule which
1304 number is the opposite. If zero, do what YYDEFACT says. */
1305 const ]b4_int_type(b4_table_ninf, b4_table_ninf) b4_parser_class_name::yytable_ninf_ = b4_table_ninf[;
1306 ]b4_table_define([table], [b4_table])[;
1307
1308 /* YYCHECK. */
1309 ]b4_table_define([check], [b4_check])[;
1310
1311 /* STOS_[STATE-NUM] -- The (internal number of the) accessing
1312 symbol of state STATE-NUM. */
1313 ]b4_table_define([stos], [b4_stos])[;
1314
1315 #if YYDEBUG
1316 /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding
1317 to YYLEX-NUM. */
1318 ]b4_table_define([token_number], [b4_toknum])[;
1319 #endif
1320
1321 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
1322 ]b4_table_define([r1], [b4_r1])[;
1323
1324 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
1325 ]b4_table_define([r2], [b4_r2])[;
1326
1327 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
1328 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
1329 First, the terminals, then, starting at \a yyntokens_, nonterminals. */
1330 const char*
1331 const ]b4_parser_class_name[::yytname_[] =
1332 {
1333 ]b4_tname[
1334 };
1335 #endif
1336
1337 #if YYDEBUG
1338 /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
1339 ]b4_table_define([rline], [b4_rline])[;
1340
1341 // Print the state stack on the debug stream.
1342 void
1343 ]b4_parser_class_name[::yystack_print_ ()
1344 {
1345 *yycdebug_ << "Stack now";
1346 for (stack_type::const_iterator
1347 i = yystack_.begin (),
1348 i_end = yystack_.end ();
1349 i != i_end; ++i)
1350 *yycdebug_ << ' ' << i->state;
1351 *yycdebug_ << std::endl;
1352 }
1353
1354 // Report on the debug stream that the rule \a yyrule is going to be reduced.
1355 void
1356 ]b4_parser_class_name[::yy_reduce_print_ (int yyrule)
1357 {
1358 unsigned int yylno = yyrline_[yyrule];
1359 int yynrhs = yyr2_[yyrule];
1360 /* Print the symbols being reduced, and their result. */
1361 *yycdebug_ << "Reducing stack by rule " << yyrule - 1
1362 << " (line " << yylno << "):" << std::endl;
1363 /* The symbols being reduced. */
1364 for (int yyi = 0; yyi < yynrhs; yyi++)
1365 YY_SYMBOL_PRINT (" $" << yyi + 1 << " =",
1366 ]b4_rhs_data(yynrhs, yyi + 1)[);
1367 }
1368 #endif // YYDEBUG
1369
1370 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
1371 ]b4_parser_class_name[::token_number_type
1372 ]b4_parser_class_name[::yytranslate_ (int t)
1373 {
1374 static
1375 const token_number_type
1376 translate_table[] =
1377 {
1378 ]b4_translate[
1379 };
1380 if ((unsigned int) t <= yyuser_token_number_max_)
1381 return translate_table[t];
1382 else
1383 return yyundef_token_;
1384 }
1385
1386 const int ]b4_parser_class_name[::yyeof_ = 0;
1387 const int ]b4_parser_class_name[::yylast_ = ]b4_last[;
1388 const int ]b4_parser_class_name[::yynnts_ = ]b4_nterms_number[;
1389 const int ]b4_parser_class_name[::yyempty_ = -2;
1390 const int ]b4_parser_class_name[::yyfinal_ = ]b4_final_state_number[;
1391 const int ]b4_parser_class_name[::yyterror_ = 1;
1392 const int ]b4_parser_class_name[::yyerrcode_ = 256;
1393 const int ]b4_parser_class_name[::yyntokens_ = ]b4_tokens_number[;
1394
1395 const unsigned int ]b4_parser_class_name[::yyuser_token_number_max_ = ]b4_user_token_number_max[;
1396 const ]b4_parser_class_name[::token_number_type ]b4_parser_class_name[::yyundef_token_ = ]b4_undef_token_number[;
1397
1398 ]b4_namespace_close[
1399
1400 ]b4_epilogue[]dnl
1401 @output(b4_dir_prefix[]stack.hh@)@
1402 b4_copyright([Stack handling for Bison parsers in C++])[
1403
1404 #ifndef BISON_STACK_HH
1405 # define BISON_STACK_HH
1406
1407 #include <deque>
1408
1409 ]b4_namespace_open[
1410 template <class T, class S = std::deque<T> >
1411 class stack
1412 {
1413 public:
1414
1415 // Hide our reversed order.
1416 typedef typename S::reverse_iterator iterator;
1417 typedef typename S::const_reverse_iterator const_iterator;
1418
1419 stack () : seq_ ()
1420 {
1421 }
1422
1423 stack (unsigned int n) : seq_ (n)
1424 {
1425 }
1426
1427 inline
1428 T&
1429 operator [] (unsigned int i)
1430 {
1431 return seq_[i];
1432 }
1433
1434 inline
1435 const T&
1436 operator [] (unsigned int i) const
1437 {
1438 return seq_[i];
1439 }
1440
1441 inline
1442 void
1443 push (const T& t)
1444 {
1445 seq_.push_front (t);
1446 }
1447
1448 inline
1449 void
1450 pop (unsigned int n = 1)
1451 {
1452 for (; n; --n)
1453 seq_.pop_front ();
1454 }
1455
1456 inline
1457 typename S::size_type
1458 size () const
1459 {
1460 return seq_.size ();
1461 }
1462
1463 inline const_iterator begin () const { return seq_.rbegin (); }
1464 inline const_iterator end () const { return seq_.rend (); }
1465
1466 private:
1467 /// The wrapped container.
1468 S seq_;
1469 };
1470
1471 /// Present a slice of the top of a stack.
1472 template <class T, class S = stack<T> >
1473 class slice
1474 {
1475 public:
1476
1477 slice (const S& stack,
1478 unsigned int range) : stack_ (stack),
1479 range_ (range)
1480 {
1481 }
1482
1483 inline
1484 const T&
1485 operator [] (unsigned int i) const
1486 {
1487 return stack_[range_ - i];
1488 }
1489
1490 private:
1491
1492 const S& stack_;
1493 unsigned int range_;
1494 };
1495 ]b4_namespace_close[
1496
1497 #endif // not BISON_STACK_HH[]dnl
1498 ]
1499 m4_divert_pop(0)
1500 m4_popdef([b4_copyright_years])dnl