]> git.saurik.com Git - bison.git/blob - data/lalr1.cc
* data/lalr1.cc: Use temporary variables instead of casts to
[bison.git] / data / lalr1.cc
1 m4_divert(-1)
2 # C++ skeleton for Bison
3 # Copyright (C) 2002, 2003 Free Software Foundation, Inc.
4
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 # 02111-1307 USA
19
20 ## ---------------- ##
21 ## Default values. ##
22 ## ---------------- ##
23
24 # Default Parser class name.
25 m4_define_default([b4_parser_class_name], [Parser])
26
27
28
29 ## ----------------- ##
30 ## Semantic Values. ##
31 ## ----------------- ##
32
33
34 # b4_lhs_value([TYPE])
35 # --------------------
36 # Expansion of $<TYPE>$.
37 m4_define([b4_lhs_value],
38 [yyval[]m4_ifval([$1], [.$1])])
39
40
41 # b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
42 # --------------------------------------
43 # Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
44 # symbols on RHS.
45 m4_define([b4_rhs_value],
46 [semantic_stack_@{m4_eval([$1 - $2])@}m4_ifval([$3], [.$3])])
47
48 m4_define_default([b4_location_type], [Location])
49
50 # b4_lhs_location()
51 # -----------------
52 # Expansion of @$.
53 m4_define([b4_lhs_location],
54 [yyloc])
55
56
57 # b4_rhs_location(RULE-LENGTH, NUM)
58 # ---------------------------------
59 # Expansion of @NUM, where the current rule has RULE-LENGTH symbols
60 # on RHS.
61 m4_define([b4_rhs_location],
62 [location_stack_@{m4_eval([$1 - $2])@}])
63
64
65 m4_define([b4_inherit],
66 [m4_ifdef([b4_root],
67 [: public b4_root
68 ],
69 [])])
70
71 m4_define([b4_param],
72 [m4_ifdef([b4_root],
73 [,
74 const Param& param],
75 [])])
76
77 m4_define([b4_constructor],
78 [m4_ifdef([b4_root],
79 [b4_root (param),
80 ],
81 [])])
82
83
84 # We do want M4 expansion after # for CPP macros.
85 m4_changecom()
86 m4_divert(0)dnl
87 m4_if(b4_defines_flag, 0, [],
88 [@output @output_header_name@
89 b4_copyright([C++ Skeleton parser for LALR(1) parsing with Bison],
90 [2002, 2003])[
91 /* FIXME: This is wrong, we want computed header guards.
92 I don't know why the macros are missing now. :( */
93 #ifndef PARSER_HEADER_H
94 # define PARSER_HEADER_H
95
96 #include "stack.hh"
97 #include "location.hh"
98
99 #include <string>
100 #include <iostream>
101
102 /* Using locations. */
103 #define YYLSP_NEEDED ]b4_locations_flag[
104
105 ]b4_token_defines(b4_tokens)[
106
107 /* Copy the first part of user declarations. */
108 ]b4_pre_prologue[
109
110 ]/* Line __line__ of lalr1.cc. */
111 b4_syncline([@oline@], [@ofile@])[
112
113 /* Enabling traces. */
114 #ifndef YYDEBUG
115 # define YYDEBUG ]b4_debug[
116 #endif
117
118 /* Enabling verbose error message. */
119 #ifndef YYERROR_VERBOSE
120 # define YYERROR_VERBOSE ]b4_error_verbose[
121 #endif
122
123 #ifndef YYSTYPE
124 ]m4_ifdef([b4_stype],
125 [b4_syncline([b4_stype_line], [b4_filename])
126 typedef union b4_stype yystype;
127 /* Line __line__ of lalr1.cc. */
128 b4_syncline([@oline@], [@ofile@])],
129 [typedef int yystype;])[
130 # define YYSTYPE yystype
131 #endif
132
133 /* Copy the second part of user declarations. */
134 ]b4_post_prologue[
135
136 ]/* Line __line__ of lalr1.cc. */
137 b4_syncline([@oline@], [@ofile@])[
138 #ifndef YYLLOC_DEFAULT
139 # define YYLLOC_DEFAULT(Current, Rhs, N) \
140 Current.end = Rhs[N].end;
141 #endif
142
143 namespace yy
144 {
145 class ]b4_parser_class_name[;
146
147 template < typename P >
148 struct Traits
149 {
150 };
151
152 template < >
153 struct Traits< ]b4_parser_class_name[ >
154 {
155 typedef ]b4_int_type_for([b4_translate])[ TokenNumberType;
156 typedef ]b4_int_type_for([b4_rhs])[ RhsNumberType;
157 typedef int StateType;
158 typedef yystype SemanticType;
159 typedef ]b4_location_type[ LocationType;
160 };
161 }
162
163 namespace yy
164 {
165 class ]b4_parser_class_name b4_inherit[
166 {
167 public:
168
169 typedef Traits< ]b4_parser_class_name[ >::TokenNumberType TokenNumberType;
170 typedef Traits< ]b4_parser_class_name[ >::RhsNumberType RhsNumberType;
171 typedef Traits< ]b4_parser_class_name[ >::StateType StateType;
172 typedef Traits< ]b4_parser_class_name[ >::SemanticType SemanticType;
173 typedef Traits< ]b4_parser_class_name[ >::LocationType LocationType;
174
175 typedef Stack< StateType > StateStack;
176 typedef Stack< SemanticType > SemanticStack;
177 typedef Stack< LocationType > LocationStack;
178
179 #if YYLSP_NEEDED
180 ]b4_parser_class_name[ (bool debug,
181 LocationType initlocation][]b4_param[) :
182 ]b4_constructor[][debug_ (debug),
183 cdebug_ (std::cerr),
184 initlocation_ (initlocation)
185 #else
186 ]b4_parser_class_name[ (bool debug][]b4_param[) :
187 ]b4_constructor[][debug_ (debug),
188 cdebug_ (std::cerr)
189 #endif
190 {
191 }
192
193 virtual ~]b4_parser_class_name[ ()
194 {
195 }
196
197 virtual int parse ();
198
199 private:
200
201 virtual void lex_ ();
202 virtual void error_ ();
203 virtual void print_ ();
204
205 /* Stacks. */
206 StateStack state_stack_;
207 SemanticStack semantic_stack_;
208 LocationStack location_stack_;
209
210 /* Tables. */
211 static const ]b4_int_type_for([b4_pact])[ pact_[];
212 static const ]b4_int_type_for([b4_pact])[ pact_ninf_;
213 static const ]b4_int_type_for([b4_defact])[ defact_[];
214 static const ]b4_int_type_for([b4_pgoto])[ pgoto_[];
215 static const ]b4_int_type_for([b4_defgoto])[ defgoto_[];
216 static const ]b4_int_type_for([b4_table])[ table_[];
217 static const ]b4_int_type_for([b4_table])[ table_ninf_;
218 static const ]b4_int_type_for([b4_check])[ check_[];
219 static const ]b4_int_type_for([b4_r1])[ r1_[];
220 static const ]b4_int_type_for([b4_r2])[ r2_[];
221
222 #if YYDEBUG || YYERROR_VERBOSE
223 static const char* const name_[];
224 #endif
225
226 /* More tables, for debugging. */
227 #if YYDEBUG
228 static const RhsNumberType rhs_[];
229 static const ]b4_int_type_for([b4_prhs])[ prhs_[];
230 static const ]b4_int_type_for([b4_rline])[ rline_[];
231 static const ]b4_int_type_for([b4_stos])[ stos_[];
232 static const ]b4_int_type_for([b4_toknum])[ token_number_[];
233 #endif
234
235 /* Even more tables. */
236 static inline TokenNumberType translate_ (int token);
237
238 /* Constants. */
239 static const int eof_;
240 /* LAST_ -- Last index in TABLE_. */
241 static const int last_;
242 static const int nnts_;
243 static const int empty_;
244 static const int final_;
245 static const int terror_;
246 static const int errcode_;
247 static const int ntokens_;
248 static const unsigned user_token_number_max_;
249 static const TokenNumberType undef_token_;
250
251 /* State. */
252 int n_;
253 int len_;
254 int state_;
255
256 /* Debugging. */
257 int debug_;
258 std::ostream &cdebug_;
259
260 /* Lookahead and lookahead in internal form. */
261 int looka_;
262 int ilooka_;
263
264 /* Message. */
265 std::string message;
266
267 /* Semantic value and location of lookahead token. */
268 SemanticType value;
269 LocationType location;
270
271 /* @@$ and $$. */
272 SemanticType yyval;
273 LocationType yyloc;
274
275 /* Initial location. */
276 LocationType initlocation_;
277 };
278 }
279
280 #endif /* ! defined PARSER_HEADER_H */]
281 ])dnl
282 @output @output_parser_name@
283 b4_copyright([C++ Skeleton parser for LALR(1) parsing with Bison],
284 [2002, 2003])
285
286 m4_if(b4_defines_flag, 0, [], [#include @output_header_name@])[
287
288 /* Enable debugging if requested. */
289 #if YYDEBUG
290 # define YYCDEBUG if (debug_) cdebug_
291 #else /* !YYDEBUG */
292 # define YYCDEBUG if (0) cdebug_
293 #endif /* !YYDEBUG */
294
295 #define YYACCEPT goto yyacceptlab
296 #define YYABORT goto yyabortlab
297 #define YYERROR goto yyerrlab1
298
299
300 int
301 yy::]b4_parser_class_name[::parse ()
302 {
303 int nerrs = 0;
304 int errstatus = 0;
305
306 /* Initialize the stacks. The initial state will be pushed in
307 yynewstate, since the latter expects the semantical and the
308 location values to have been already stored, initialize these
309 stacks with a primary value. */
310 state_stack_ = StateStack (0);
311 semantic_stack_ = SemanticStack (1);
312 location_stack_ = LocationStack (1);
313
314 /* Start. */
315 state_ = 0;
316 looka_ = empty_;
317 #if YYLSP_NEEDED
318 location = initlocation_;
319 #endif
320 YYCDEBUG << "Starting parse" << std::endl;
321
322 /* New state. */
323 yynewstate:
324 state_stack_.push (state_);
325 YYCDEBUG << "Entering state " << state_ << std::endl;
326 goto yybackup;
327
328 /* Backup. */
329 yybackup:
330
331 /* Try to take a decision without lookahead. */
332 n_ = pact_[state_];
333 if (n_ == pact_ninf_)
334 goto yydefault;
335
336 /* Read a lookahead token. */
337 if (looka_ == empty_)
338 {
339 YYCDEBUG << "Reading a token: ";
340 lex_ ();
341 }
342
343 /* Convert token to internal form. */
344 if (looka_ <= 0)
345 {
346 looka_ = eof_;
347 ilooka_ = 0;
348 YYCDEBUG << "Now at end of input." << std::endl;
349 }
350 else
351 {
352 ilooka_ = translate_ (looka_);
353 #if YYDEBUG
354 if (debug_)
355 {
356 YYCDEBUG << "Next token is " << looka_
357 << " (" << name_[ilooka_];
358 print_ ();
359 YYCDEBUG << ')' << std::endl;
360 }
361 #endif
362 }
363
364 n_ += ilooka_;
365 if (n_ < 0 || last_ < n_ || check_[n_] != ilooka_)
366 goto yydefault;
367
368 /* Reduce or error. */
369 n_ = table_[n_];
370 if (n_ < 0)
371 {
372 if (n_ == table_ninf_)
373 goto yyerrlab;
374 else
375 {
376 n_ = -n_;
377 goto yyreduce;
378 }
379 }
380 else if (n_ == 0)
381 goto yyerrlab;
382
383 /* Accept? */
384 if (n_ == final_)
385 goto yyacceptlab;
386
387 /* Shift the lookahead token. */
388 #if YYDEBUG
389 YYCDEBUG << "Shifting token " << looka_
390 << " (" << name_[ilooka_] << "), ";
391 #endif
392
393 /* Discard the token being shifted unless it is eof. */
394 if (looka_ != eof_)
395 looka_ = empty_;
396
397 semantic_stack_.push (value);
398 location_stack_.push (location);
399
400 /* Count tokens shifted since error; after three, turn off error
401 status. */
402 if (errstatus)
403 --errstatus;
404
405 state_ = n_;
406 goto yynewstate;
407
408 /* Default action. */
409 yydefault:
410 n_ = defact_[state_];
411 if (n_ == 0)
412 goto yyerrlab;
413 goto yyreduce;
414
415 /* Reduce. */
416 yyreduce:
417 len_ = r2_[n_];
418 if (len_)
419 {
420 yyval = semantic_stack_[len_ - 1];
421 yyloc = location_stack_[len_ - 1];
422 }
423 else
424 {
425 yyval = semantic_stack_[0];
426 yyloc = location_stack_[0];
427 }
428
429 #if YYDEBUG
430 if (debug_)
431 {
432 // Short files will use "unsigned char" for line numbers,
433 // in which case they will be output as character litterals
434 // by "<<".
435 unsigned yylineno = rline_[n_];
436 YYCDEBUG << "Reducing via rule " << n_ - 1
437 << " (line " << yylineno << "), ";
438 for (]b4_int_type_for([b4_prhs])[ i = prhs_[n_];
439 0 <= rhs_[i]; ++i)
440 YYCDEBUG << name_[rhs_[i]] << ' ';
441 YYCDEBUG << "-> " << name_[r1_[n_]] << std::endl;
442 }
443 #endif
444
445 if (len_)
446 {
447 Slice< LocationType, LocationStack > slice (location_stack_, len_);
448 YYLLOC_DEFAULT (yyloc, slice, len_);
449 }
450
451 switch (n_)
452 {
453 ]b4_actions[
454 }
455
456 ]/* Line __line__ of lalr1.cc. */
457 b4_syncline([@oline@], [@ofile@])[
458
459 state_stack_.pop (len_);
460 semantic_stack_.pop (len_);
461 location_stack_.pop (len_);
462
463 #if YYDEBUG
464 if (debug_)
465 {
466 YYCDEBUG << "state stack now";
467 for (StateStack::ConstIterator i = state_stack_.begin ();
468 i != state_stack_.end (); ++i)
469 YYCDEBUG << ' ' << *i;
470 YYCDEBUG << std::endl;
471 }
472 #endif
473
474 semantic_stack_.push (yyval);
475 location_stack_.push (yyloc);
476
477 /* Shift the result of the reduction. */
478 n_ = r1_[n_];
479 state_ = pgoto_[n_ - ntokens_] + state_stack_[0];
480 if (0 <= state_ && state_ <= last_ && check_[state_] == state_stack_[0])
481 state_ = table_[state_];
482 else
483 state_ = defgoto_[n_ - ntokens_];
484 goto yynewstate;
485
486 /* Report and recover from errors. This is very incomplete. */
487 yyerrlab:
488 /* If not already recovering from an error, report this error. */
489 if (!errstatus)
490 {
491 ++nerrs;
492
493 #if YYERROR_VERBOSE
494 n_ = pact_[state_];
495 if (pact_ninf_ < n_ && n_ < last_)
496 {
497 message = "syntax error, unexpected ";
498 message += name_[ilooka_];
499 {
500 int count = 0;
501 for (int x = (n_ < 0 ? -n_ : 0); x < ntokens_ + nnts_; ++x)
502 if (check_[x + n_] == x && x != terror_)
503 ++count;
504 if (count < 5)
505 {
506 count = 0;
507 for (int x = (n_ < 0 ? -n_ : 0); x < ntokens_ + nnts_; ++x)
508 if (check_[x + n_] == x && x != terror_)
509 {
510 message += (!count++) ? ", expecting " : " or ";
511 message += name_[x];
512 }
513 }
514 }
515 }
516 else
517 #endif
518 message = "syntax error";
519 error_ ();
520 }
521 goto yyerrlab1;
522
523
524 /*----------------------------------------------------.
525 | yyerrlab1 -- error raised explicitly by an action. |
526 `----------------------------------------------------*/
527 yyerrlab1:
528 if (errstatus == 3)
529 {
530 /* If just tried and failed to reuse lookahead token after an
531 error, discard it. */
532
533 /* Return failure if at end of input. */
534 if (looka_ == eof_)
535 goto yyabortlab;
536 #if YYDEBUG
537 YYCDEBUG << "Discarding token " << looka_
538 << " (" << name_[ilooka_] << ")." << std::endl;
539 #endif
540 looka_ = empty_;
541 }
542
543 /* Else will try to reuse lookahead token after shifting the error
544 token. */
545
546 errstatus = 3;
547
548 for (;;)
549 {
550 n_ = pact_[state_];
551 if (n_ != pact_ninf_)
552 {
553 n_ += terror_;
554 if (0 <= n_ && n_ <= last_ && check_[n_] == terror_)
555 {
556 n_ = table_[n_];
557 if (0 < n_)
558 break;
559 }
560 }
561
562 /* Pop the current state because it cannot handle the error token. */
563 if (state_stack_.height () == 1)
564 goto yyabortlab;
565
566 #if YYDEBUG
567 if (debug_)
568 {
569 if (stos_[state_] < ntokens_)
570 {
571 YYCDEBUG << "Error: popping token "
572 << token_number_[stos_[state_]]
573 << " (" << name_[stos_[state_]];
574 # ifdef YYPRINT
575 YYPRINT (stderr, token_number_[stos_[state_]],
576 semantic_stack_.top ());
577 # endif
578 YYCDEBUG << ')' << std::endl;
579 }
580 else
581 {
582 YYCDEBUG << "Error: popping nonterminal ("
583 << name_[stos_[state_]] << ')' << std::endl;
584 }
585 }
586 #endif
587
588 state_ = (state_stack_.pop (), state_stack_[0]);
589 semantic_stack_.pop ();
590 location_stack_.pop ();;
591
592 #if YYDEBUG
593 if (debug_)
594 {
595 YYCDEBUG << "Error: state stack now";
596 for (StateStack::ConstIterator i = state_stack_.begin ();
597 i != state_stack_.end (); ++i)
598 YYCDEBUG << ' ' << *i;
599 YYCDEBUG << std::endl;
600 }
601 #endif
602 }
603
604 if (n_ == final_)
605 goto yyacceptlab;
606
607 YYCDEBUG << "Shifting error token, ";
608
609 semantic_stack_.push (value);
610 location_stack_.push (location);
611
612 state_ = n_;
613 goto yynewstate;
614
615 /* Accept. */
616 yyacceptlab:
617 return 0;
618
619 /* Abort. */
620 yyabortlab:
621 return 1;
622 }
623
624 void
625 yy::]b4_parser_class_name[::lex_ ()
626 {
627 #if YYLSP_NEEDED
628 looka_ = yylex (&value, &location);
629 #else
630 looka_ = yylex (&value);
631 #endif
632 }
633
634 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
635 STATE-NUM. */
636 const ]b4_int_type_for([b4_pact]) yy::b4_parser_class_name::pact_ninf_ = b4_pact_ninf[;
637 const ]b4_int_type_for([b4_pact])[
638 yy::]b4_parser_class_name[::pact_[] =
639 {
640 ]b4_pact[
641 };
642
643 /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
644 doesn't specify something else to do. Zero means the default is an
645 error. */
646 const ]b4_int_type_for([b4_defact])[
647 yy::]b4_parser_class_name[::defact_[] =
648 {
649 ]b4_defact[
650 };
651
652 /* YYPGOTO[NTERM-NUM]. */
653 const ]b4_int_type_for([b4_pgoto])[
654 yy::]b4_parser_class_name[::pgoto_[] =
655 {
656 ]b4_pgoto[
657 };
658
659 /* YYDEFGOTO[NTERM-NUM]. */
660 const ]b4_int_type_for([b4_defgoto])[
661 yy::]b4_parser_class_name[::defgoto_[] =
662 {
663 ]b4_defgoto[
664 };
665
666 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
667 positive, shift that token. If negative, reduce the rule which
668 number is the opposite. If zero, do what YYDEFACT says. */
669 const ]b4_int_type_for([b4_table]) yy::b4_parser_class_name::table_ninf_ = b4_table_ninf[;
670 const ]b4_int_type_for([b4_table])[
671 yy::]b4_parser_class_name[::table_[] =
672 {
673 ]b4_table[
674 };
675
676 /* YYCHECK. */
677 const ]b4_int_type_for([b4_check])[
678 yy::]b4_parser_class_name[::check_[] =
679 {
680 ]b4_check[
681 };
682
683 #if YYDEBUG
684 /* STOS_[STATE-NUM] -- The (internal number of the) accessing
685 symbol of state STATE-NUM. */
686 const ]b4_int_type_for([b4_stos])[
687 yy::]b4_parser_class_name[::stos_[] =
688 {
689 ]b4_stos[
690 };
691
692 /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal token number corresponding
693 to YYLEX-NUM. */
694 const ]b4_int_type_for([b4_toknum])[
695 yy::]b4_parser_class_name[::token_number_[] =
696 {
697 ]b4_toknum[
698 };
699 #endif
700
701 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
702 const ]b4_int_type_for([b4_r1])[
703 yy::]b4_parser_class_name[::r1_[] =
704 {
705 ]b4_r1[
706 };
707
708 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
709 const ]b4_int_type_for([b4_r2])[
710 yy::]b4_parser_class_name[::r2_[] =
711 {
712 ]b4_r2[
713 };
714
715 #if YYDEBUG || YYERROR_VERBOSE
716 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
717 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
718 const char*
719 const yy::]b4_parser_class_name[::name_[] =
720 {
721 ]b4_tname[
722 };
723 #endif
724
725 #if YYDEBUG
726 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
727 const yy::]b4_parser_class_name[::RhsNumberType
728 yy::]b4_parser_class_name[::rhs_[] =
729 {
730 ]b4_rhs[
731 };
732
733 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
734 YYRHS. */
735 const ]b4_int_type_for([b4_prhs])[
736 yy::]b4_parser_class_name[::prhs_[] =
737 {
738 ]b4_prhs[
739 };
740
741 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
742 const ]b4_int_type_for([b4_rline])[
743 yy::]b4_parser_class_name[::rline_[] =
744 {
745 ]b4_rline[
746 };
747 #endif
748
749 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
750 yy::]b4_parser_class_name[::TokenNumberType
751 yy::]b4_parser_class_name[::translate_ (int token)
752 {
753 static
754 const TokenNumberType
755 translate_[] =
756 {
757 ]b4_translate[
758 };
759 if ((unsigned) token <= user_token_number_max_)
760 return translate_[token];
761 else
762 return undef_token_;
763 }
764
765 const int yy::]b4_parser_class_name[::eof_ = 0;
766 const int yy::]b4_parser_class_name[::last_ = ]b4_last[;
767 const int yy::]b4_parser_class_name[::nnts_ = ]b4_nterms_number[;
768 const int yy::]b4_parser_class_name[::empty_ = -2;
769 const int yy::]b4_parser_class_name[::final_ = ]b4_final_state_number[;
770 const int yy::]b4_parser_class_name[::terror_ = 1;
771 const int yy::]b4_parser_class_name[::errcode_ = 256;
772 const int yy::]b4_parser_class_name[::ntokens_ = ]b4_tokens_number[;
773
774 const unsigned yy::]b4_parser_class_name[::user_token_number_max_ = ]b4_user_token_number_max[;
775 const yy::]b4_parser_class_name[::TokenNumberType yy::]b4_parser_class_name[::undef_token_ = ]b4_undef_token_number[;
776
777 ]b4_epilogue
778 dnl
779 @output stack.hh
780 b4_copyright([Stack handling for Bison C++ parsers], [2002, 2003])[
781
782 #ifndef BISON_STACK_HH
783 # define BISON_STACK_HH
784
785 #include <deque>
786
787 namespace yy
788 {
789 template < class T, class S = std::deque< T > >
790 class Stack
791 {
792 public:
793
794 typedef typename S::iterator Iterator;
795 typedef typename S::const_iterator ConstIterator;
796
797 Stack () : seq_ ()
798 {
799 }
800
801 Stack (unsigned n) : seq_ (n)
802 {
803 }
804
805 inline
806 T&
807 operator [] (unsigned index)
808 {
809 return seq_[index];
810 }
811
812 inline
813 const T&
814 operator [] (unsigned index) const
815 {
816 return seq_[index];
817 }
818
819 inline
820 void
821 push (const T& t)
822 {
823 seq_.push_front (t);
824 }
825
826 inline
827 void
828 pop (unsigned n = 1)
829 {
830 for (; n; --n)
831 seq_.pop_front ();
832 }
833
834 inline
835 unsigned
836 height () const
837 {
838 return seq_.size ();
839 }
840
841 inline ConstIterator begin () const { return seq_.begin (); }
842 inline ConstIterator end () const { return seq_.end (); }
843
844 private:
845
846 S seq_;
847 };
848
849 template < class T, class S = Stack< T > >
850 class Slice
851 {
852 public:
853
854 Slice (const S& stack,
855 unsigned range) : stack_ (stack),
856 range_ (range)
857 {
858 }
859
860 inline
861 const T&
862 operator [] (unsigned index) const
863 {
864 return stack_[range_ - index];
865 }
866
867 private:
868
869 const S& stack_;
870 unsigned range_;
871 };
872 }
873
874 #endif // not BISON_STACK_HH]
875 dnl
876 @output position.hh
877 b4_copyright([Position class for Bison C++ parsers], [2002, 2003])[
878
879 /**
880 ** \file position.hh
881 ** Define the Location class.
882 */
883
884 #ifndef BISON_POSITION_HH
885 # define BISON_POSITION_HH
886
887 # include <iostream>
888 # include <string>
889
890 namespace yy
891 {
892 /** \brief Abstract a Position. */
893 class Position
894 {
895 public:
896 /** \brief Initial column number. */
897 static const unsigned int initial_column = 0;
898 /** \brief Initial line number. */
899 static const unsigned int initial_line = 1;
900
901 /** \name Ctor & dtor.
902 ** \{ */
903 public:
904 /** \brief Construct a Position. */
905 Position () :
906 filename (),
907 line (initial_line),
908 column (initial_column)
909 {
910 }
911 /** \} */
912
913
914 /** \name Line and Column related manipulators
915 ** \{ */
916 public:
917 /** \brief (line related) Advance to the LINES next lines. */
918 inline void lines (int lines = 1)
919 {
920 column = initial_column;
921 line += lines;
922 }
923
924 /** \brief (column related) Advance to the COLUMNS next columns. */
925 inline void columns (int columns = 1)
926 {
927 int leftmost = initial_column;
928 int current = column;
929 if (leftmost <= current + columns)
930 column += columns;
931 else
932 column = initial_column;
933 }
934 /** \} */
935
936 public:
937 /** \brief File name to which this position refers. */
938 std::string filename;
939 /** \brief Current line number. */
940 unsigned int line;
941 /** \brief Current column number. */
942 unsigned int column;
943 };
944
945 /** \brief Add and assign a Position. */
946 inline const Position&
947 operator+= (Position& res, const int width)
948 {
949 res.columns (width);
950 return res;
951 }
952
953 /** \brief Add two Position objects. */
954 inline const Position
955 operator+ (const Position& begin, const int width)
956 {
957 Position res = begin;
958 return res += width;
959 }
960
961 /** \brief Add and assign a Position. */
962 inline const Position&
963 operator-= (Position& res, const int width)
964 {
965 return res += -width;
966 }
967
968 /** \brief Add two Position objects. */
969 inline const Position
970 operator- (const Position& begin, const int width)
971 {
972 return begin + -width;
973 }
974
975 /** \brief Intercept output stream redirection.
976 ** \param ostr the destination output stream
977 ** \param pos a reference to the Position to redirect
978 */
979 inline std::ostream&
980 operator<< (std::ostream& ostr, const Position& pos)
981 {
982 if (pos.filename != "")
983 ostr << pos.filename << ':';
984 return ostr << pos.line << '.' << pos.column;
985 }
986
987 }
988 #endif // not BISON_POSITION_HH]
989 @output location.hh
990 b4_copyright([Location class for Bison C++ parsers], [2002, 2003])[
991
992 /**
993 ** \file location.hh
994 ** Define the Location class.
995 */
996
997 #ifndef BISON_LOCATION_HH
998 # define BISON_LOCATION_HH
999
1000 # include <iostream>
1001 # include <string>
1002 # include "position.hh"
1003
1004 namespace yy
1005 {
1006
1007 /** \brief Abstract a Location. */
1008 class Location
1009 {
1010 /** \name Ctor & dtor.
1011 ** \{ */
1012 public:
1013 /** \brief Construct a Location. */
1014 Location (void) :
1015 begin (),
1016 end ()
1017 {
1018 }
1019 /** \} */
1020
1021
1022 /** \name Line and Column related manipulators
1023 ** \{ */
1024 public:
1025 /** \brief Reset initial location to final location. */
1026 inline void step (void)
1027 {
1028 begin = end;
1029 }
1030
1031 /** \brief Extend the current location to the COLUMNS next columns. */
1032 inline void columns (unsigned columns = 1)
1033 {
1034 end += columns;
1035 }
1036
1037 /** \brief Extend the current location to the LINES next lines. */
1038 inline void lines (unsigned lines = 1)
1039 {
1040 end.lines (lines);
1041 }
1042 /** \} */
1043
1044
1045 public:
1046 /** \brief Beginning of the located region. */
1047 Position begin;
1048 /** \brief End of the located region. */
1049 Position end;
1050 };
1051
1052 /** \brief Join two Location objects to create a Location. */
1053 inline const Location operator+ (const Location& begin, const Location& end)
1054 {
1055 Location res = begin;
1056 res.end = end.end;
1057 return res;
1058 }
1059
1060 /** \brief Add two Location objects */
1061 inline const Location operator+ (const Location& begin, unsigned width)
1062 {
1063 Location res = begin;
1064 res.columns (width);
1065 return res;
1066 }
1067
1068 /** \brief Add and assign a Location */
1069 inline Location &operator+= (Location& res, unsigned width)
1070 {
1071 res.columns (width);
1072 return res;
1073 }
1074
1075 /** \brief Intercept output stream redirection.
1076 ** \param ostr the destination output stream
1077 ** \param loc a reference to the Location to redirect
1078 **
1079 ** Avoid duplicate information.
1080 */
1081 inline std::ostream& operator<< (std::ostream& ostr, const Location& loc)
1082 {
1083 Position last = loc.end - 1;
1084 ostr << loc.begin;
1085 if (loc.begin.filename != last.filename)
1086 ostr << '-' << last;
1087 else if (loc.begin.line != last.line)
1088 ostr << '-' << last.line << '.' << last.column;
1089 else if (loc.begin.column != last.column)
1090 ostr << '-' << last.column;
1091 return ostr;
1092 }
1093
1094 }
1095
1096 #endif // not BISON_LOCATION_HH]