]> git.saurik.com Git - bison.git/blob - data/lalr1.cc
* data/lalr1.cc (position.hh): New subfile, including the extended
[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 YYCDEBUG << "Reducing via rule " << n_ - 1
436 << " (line " << static_cast <unsigned> (rline_[n_]) << "), ";
437 for (]b4_int_type_for([b4_prhs])[ i = prhs_[n_];
438 0 <= rhs_[i]; ++i)
439 YYCDEBUG << name_[rhs_[i]] << ' ';
440 YYCDEBUG << "-> " << name_[r1_[n_]] << std::endl;
441 }
442 #endif
443
444 if (len_)
445 {
446 Slice< LocationType, LocationStack > slice (location_stack_, len_);
447 YYLLOC_DEFAULT (yyloc, slice, len_);
448 }
449
450 switch (n_)
451 {
452 ]b4_actions[
453 }
454
455 ]/* Line __line__ of lalr1.cc. */
456 b4_syncline([@oline@], [@ofile@])[
457
458 state_stack_.pop (len_);
459 semantic_stack_.pop (len_);
460 location_stack_.pop (len_);
461
462 #if YYDEBUG
463 if (debug_)
464 {
465 YYCDEBUG << "state stack now";
466 for (StateStack::ConstIterator i = state_stack_.begin ();
467 i != state_stack_.end (); ++i)
468 YYCDEBUG << ' ' << *i;
469 YYCDEBUG << std::endl;
470 }
471 #endif
472
473 semantic_stack_.push (yyval);
474 location_stack_.push (yyloc);
475
476 /* Shift the result of the reduction. */
477 n_ = r1_[n_];
478 state_ = pgoto_[n_ - ntokens_] + state_stack_[0];
479 if (0 <= state_ && state_ <= last_ && check_[state_] == state_stack_[0])
480 state_ = table_[state_];
481 else
482 state_ = defgoto_[n_ - ntokens_];
483 goto yynewstate;
484
485 /* Report and recover from errors. This is very incomplete. */
486 yyerrlab:
487 /* If not already recovering from an error, report this error. */
488 if (!errstatus)
489 {
490 ++nerrs;
491
492 #if YYERROR_VERBOSE
493 n_ = pact_[state_];
494 if (pact_ninf_ < n_ && n_ < last_)
495 {
496 message = "syntax error, unexpected ";
497 message += name_[ilooka_];
498 {
499 int count = 0;
500 for (int x = (n_ < 0 ? -n_ : 0); x < ntokens_ + nnts_; ++x)
501 if (check_[x + n_] == x && x != terror_)
502 ++count;
503 if (count < 5)
504 {
505 count = 0;
506 for (int x = (n_ < 0 ? -n_ : 0); x < ntokens_ + nnts_; ++x)
507 if (check_[x + n_] == x && x != terror_)
508 {
509 message += (!count++) ? ", expecting " : " or ";
510 message += name_[x];
511 }
512 }
513 }
514 }
515 else
516 #endif
517 message = "syntax error";
518 error_ ();
519 }
520 goto yyerrlab1;
521
522
523 /*----------------------------------------------------.
524 | yyerrlab1 -- error raised explicitly by an action. |
525 `----------------------------------------------------*/
526 yyerrlab1:
527 if (errstatus == 3)
528 {
529 /* If just tried and failed to reuse lookahead token after an
530 error, discard it. */
531
532 /* Return failure if at end of input. */
533 if (looka_ == eof_)
534 goto yyabortlab;
535 #if YYDEBUG
536 YYCDEBUG << "Discarding token " << looka_
537 << " (" << name_[ilooka_] << ")." << std::endl;
538 #endif
539 looka_ = empty_;
540 }
541
542 /* Else will try to reuse lookahead token after shifting the error
543 token. */
544
545 errstatus = 3;
546
547 for (;;)
548 {
549 n_ = pact_[state_];
550 if (n_ != pact_ninf_)
551 {
552 n_ += terror_;
553 if (0 <= n_ && n_ <= last_ && check_[n_] == terror_)
554 {
555 n_ = table_[n_];
556 if (0 < n_)
557 break;
558 }
559 }
560
561 /* Pop the current state because it cannot handle the error token. */
562 if (state_stack_.height () == 1)
563 goto yyabortlab;
564
565 #if YYDEBUG
566 if (debug_)
567 {
568 if (stos_[state_] < ntokens_)
569 {
570 YYCDEBUG << "Error: popping token "
571 << token_number_[stos_[state_]]
572 << " (" << name_[stos_[state_]];
573 # ifdef YYPRINT
574 YYPRINT (stderr, token_number_[stos_[state_]],
575 semantic_stack_.top ());
576 # endif
577 YYCDEBUG << ')' << std::endl;
578 }
579 else
580 {
581 YYCDEBUG << "Error: popping nonterminal ("
582 << name_[stos_[state_]] << ')' << std::endl;
583 }
584 }
585 #endif
586
587 state_ = (state_stack_.pop (), state_stack_[0]);
588 semantic_stack_.pop ();
589 location_stack_.pop ();;
590
591 #if YYDEBUG
592 if (debug_)
593 {
594 YYCDEBUG << "Error: state stack now";
595 for (StateStack::ConstIterator i = state_stack_.begin ();
596 i != state_stack_.end (); ++i)
597 YYCDEBUG << ' ' << *i;
598 YYCDEBUG << std::endl;
599 }
600 #endif
601 }
602
603 if (n_ == final_)
604 goto yyacceptlab;
605
606 YYCDEBUG << "Shifting error token, ";
607
608 semantic_stack_.push (value);
609 location_stack_.push (location);
610
611 state_ = n_;
612 goto yynewstate;
613
614 /* Accept. */
615 yyacceptlab:
616 return 0;
617
618 /* Abort. */
619 yyabortlab:
620 return 1;
621 }
622
623 void
624 yy::]b4_parser_class_name[::lex_ ()
625 {
626 #if YYLSP_NEEDED
627 looka_ = yylex (&value, &location);
628 #else
629 looka_ = yylex (&value);
630 #endif
631 }
632
633 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
634 STATE-NUM. */
635 const ]b4_int_type_for([b4_pact]) yy::b4_parser_class_name::pact_ninf_ = b4_pact_ninf[;
636 const ]b4_int_type_for([b4_pact])[
637 yy::]b4_parser_class_name[::pact_[] =
638 {
639 ]b4_pact[
640 };
641
642 /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
643 doesn't specify something else to do. Zero means the default is an
644 error. */
645 const ]b4_int_type_for([b4_defact])[
646 yy::]b4_parser_class_name[::defact_[] =
647 {
648 ]b4_defact[
649 };
650
651 /* YYPGOTO[NTERM-NUM]. */
652 const ]b4_int_type_for([b4_pgoto])[
653 yy::]b4_parser_class_name[::pgoto_[] =
654 {
655 ]b4_pgoto[
656 };
657
658 /* YYDEFGOTO[NTERM-NUM]. */
659 const ]b4_int_type_for([b4_defgoto])[
660 yy::]b4_parser_class_name[::defgoto_[] =
661 {
662 ]b4_defgoto[
663 };
664
665 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
666 positive, shift that token. If negative, reduce the rule which
667 number is the opposite. If zero, do what YYDEFACT says. */
668 const ]b4_int_type_for([b4_table]) yy::b4_parser_class_name::table_ninf_ = b4_table_ninf[;
669 const ]b4_int_type_for([b4_table])[
670 yy::]b4_parser_class_name[::table_[] =
671 {
672 ]b4_table[
673 };
674
675 /* YYCHECK. */
676 const ]b4_int_type_for([b4_check])[
677 yy::]b4_parser_class_name[::check_[] =
678 {
679 ]b4_check[
680 };
681
682 #if YYDEBUG
683 /* STOS_[STATE-NUM] -- The (internal number of the) accessing
684 symbol of state STATE-NUM. */
685 const ]b4_int_type_for([b4_stos])[
686 yy::]b4_parser_class_name[::stos_[] =
687 {
688 ]b4_stos[
689 };
690
691 /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal token number corresponding
692 to YYLEX-NUM. */
693 const ]b4_int_type_for([b4_toknum])[
694 yy::]b4_parser_class_name[::token_number_[] =
695 {
696 ]b4_toknum[
697 };
698 #endif
699
700 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
701 const ]b4_int_type_for([b4_r1])[
702 yy::]b4_parser_class_name[::r1_[] =
703 {
704 ]b4_r1[
705 };
706
707 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
708 const ]b4_int_type_for([b4_r2])[
709 yy::]b4_parser_class_name[::r2_[] =
710 {
711 ]b4_r2[
712 };
713
714 #if YYDEBUG || YYERROR_VERBOSE
715 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
716 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
717 const char*
718 const yy::]b4_parser_class_name[::name_[] =
719 {
720 ]b4_tname[
721 };
722 #endif
723
724 #if YYDEBUG
725 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
726 const yy::]b4_parser_class_name[::RhsNumberType
727 yy::]b4_parser_class_name[::rhs_[] =
728 {
729 ]b4_rhs[
730 };
731
732 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
733 YYRHS. */
734 const ]b4_int_type_for([b4_prhs])[
735 yy::]b4_parser_class_name[::prhs_[] =
736 {
737 ]b4_prhs[
738 };
739
740 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
741 const ]b4_int_type_for([b4_rline])[
742 yy::]b4_parser_class_name[::rline_[] =
743 {
744 ]b4_rline[
745 };
746 #endif
747
748 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
749 yy::]b4_parser_class_name[::TokenNumberType
750 yy::]b4_parser_class_name[::translate_ (int token)
751 {
752 static
753 const TokenNumberType
754 translate_[] =
755 {
756 ]b4_translate[
757 };
758 if ((unsigned) token <= user_token_number_max_)
759 return translate_[token];
760 else
761 return undef_token_;
762 }
763
764 const int yy::]b4_parser_class_name[::eof_ = 0;
765 const int yy::]b4_parser_class_name[::last_ = ]b4_last[;
766 const int yy::]b4_parser_class_name[::nnts_ = ]b4_nterms_number[;
767 const int yy::]b4_parser_class_name[::empty_ = -2;
768 const int yy::]b4_parser_class_name[::final_ = ]b4_final_state_number[;
769 const int yy::]b4_parser_class_name[::terror_ = 1;
770 const int yy::]b4_parser_class_name[::errcode_ = 256;
771 const int yy::]b4_parser_class_name[::ntokens_ = ]b4_tokens_number[;
772
773 const unsigned yy::]b4_parser_class_name[::user_token_number_max_ = ]b4_user_token_number_max[;
774 const yy::]b4_parser_class_name[::TokenNumberType yy::]b4_parser_class_name[::undef_token_ = ]b4_undef_token_number[;
775
776 ]b4_epilogue
777 dnl
778 @output stack.hh
779 b4_copyright([Stack handling for Bison C++ parsers], [2002, 2003])[
780
781 #ifndef BISON_STACK_HH
782 # define BISON_STACK_HH
783
784 #include <deque>
785
786 namespace yy
787 {
788 template < class T, class S = std::deque< T > >
789 class Stack
790 {
791 public:
792
793 typedef typename S::iterator Iterator;
794 typedef typename S::const_iterator ConstIterator;
795
796 Stack () : seq_ ()
797 {
798 }
799
800 Stack (unsigned n) : seq_ (n)
801 {
802 }
803
804 inline
805 T&
806 operator [] (unsigned index)
807 {
808 return seq_[index];
809 }
810
811 inline
812 const T&
813 operator [] (unsigned index) const
814 {
815 return seq_[index];
816 }
817
818 inline
819 void
820 push (const T& t)
821 {
822 seq_.push_front (t);
823 }
824
825 inline
826 void
827 pop (unsigned n = 1)
828 {
829 for (; n; --n)
830 seq_.pop_front ();
831 }
832
833 inline
834 unsigned
835 height () const
836 {
837 return seq_.size ();
838 }
839
840 inline ConstIterator begin () const { return seq_.begin (); }
841 inline ConstIterator end () const { return seq_.end (); }
842
843 private:
844
845 S seq_;
846 };
847
848 template < class T, class S = Stack< T > >
849 class Slice
850 {
851 public:
852
853 Slice (const S& stack,
854 unsigned range) : stack_ (stack),
855 range_ (range)
856 {
857 }
858
859 inline
860 const T&
861 operator [] (unsigned index) const
862 {
863 return stack_[range_ - index];
864 }
865
866 private:
867
868 const S& stack_;
869 unsigned range_;
870 };
871 }
872
873 #endif // not BISON_STACK_HH]
874 dnl
875 @output position.hh
876 b4_copyright([Position class for Bison C++ parsers], [2002, 2003])[
877
878 /**
879 ** \file position.hh
880 ** Define the Location class.
881 */
882
883 #ifndef BISON_POSITION_HH
884 # define BISON_POSITION_HH
885
886 # include <iostream>
887 # include <string>
888
889 namespace yy
890 {
891 /** \brief Abstract a Position. */
892 class Position
893 {
894 public:
895 /** \brief Initial column number. */
896 static const unsigned int initial_column = 0;
897 /** \brief Initial line number. */
898 static const unsigned int initial_line = 1;
899
900 /** \name Ctor & dtor.
901 ** \{ */
902 public:
903 /** \brief Construct a Position. */
904 Position () :
905 filename (),
906 line (initial_line),
907 column (initial_column)
908 {
909 }
910 /** \} */
911
912
913 /** \name Line and Column related manipulators
914 ** \{ */
915 public:
916 /** \brief (line related) Advance to the LINES next lines. */
917 inline void lines (int lines = 1)
918 {
919 column = initial_column;
920 line += lines;
921 }
922
923 /** \brief (column related) Advance to the COLUMNS next columns. */
924 inline void columns (int columns = 1)
925 {
926 column += columns;
927 }
928 /** \} */
929
930 public:
931 /** \brief File name to which this position refers. */
932 std::string filename;
933 /** \brief Current line number. */
934 unsigned int line;
935 /** \brief Current column number. */
936 unsigned int column;
937 };
938
939 /** \brief Add and assign a Position. */
940 inline const Position&
941 operator+= (Position& res, const int width)
942 {
943 res.columns (width);
944 return res;
945 }
946
947 /** \brief Add two Position objects. */
948 inline const Position
949 operator+ (const Position& begin, const int width)
950 {
951 Position res = begin;
952 return res += width;
953 }
954
955 /** \brief Add and assign a Position. */
956 inline const Position&
957 operator-= (Position& res, const int width)
958 {
959 return res += -width;
960 }
961
962 /** \brief Add two Position objects. */
963 inline const Position
964 operator- (const Position& begin, const int width)
965 {
966 return begin + -width;
967 }
968
969 /** \brief Intercept output stream redirection.
970 ** \param ostr the destination output stream
971 ** \param pos a reference to the Position to redirect
972 */
973 inline std::ostream&
974 operator<< (std::ostream& ostr, const Position& pos)
975 {
976 if (pos.filename != "")
977 ostr << pos.filename << ':';
978 return ostr << pos.line << '.' << pos.column;
979 }
980
981 }
982 #endif // not BISON_POSITION_HH]
983 @output location.hh
984 b4_copyright([Location class for Bison C++ parsers], [2002, 2003])[
985
986 /**
987 ** \file location.hh
988 ** Define the Location class.
989 */
990
991 #ifndef BISON_LOCATION_HH
992 # define BISON_LOCATION_HH
993
994 # include <iostream>
995 # include <string>
996 # include "position.hh"
997
998 namespace yy
999 {
1000
1001 /** \brief Abstract a Location. */
1002 class Location
1003 {
1004 /** \name Ctor & dtor.
1005 ** \{ */
1006 public:
1007 /** \brief Construct a Location. */
1008 Location (void) :
1009 begin (),
1010 end ()
1011 {
1012 }
1013 /** \} */
1014
1015
1016 /** \name Line and Column related manipulators
1017 ** \{ */
1018 public:
1019 /** \brief Reset initial location to final location. */
1020 inline void step (void)
1021 {
1022 begin = end;
1023 }
1024
1025 /** \brief Extend the current location to the COLUMNS next columns. */
1026 inline void columns (unsigned columns = 1)
1027 {
1028 end += columns;
1029 }
1030
1031 /** \brief Extend the current location to the LINES next lines. */
1032 inline void lines (unsigned lines = 1)
1033 {
1034 end.lines (lines);
1035 }
1036 /** \} */
1037
1038
1039 public:
1040 /** \brief Beginning of the located region. */
1041 Position begin;
1042 /** \brief End of the located region. */
1043 Position end;
1044 };
1045
1046 /** \brief Join two Location objects to create a Location. */
1047 inline const Location operator+ (const Location& begin, const Location& end)
1048 {
1049 Location res = begin;
1050 res.end = end.end;
1051 return res;
1052 }
1053
1054 /** \brief Add two Location objects */
1055 inline const Location operator+ (const Location& begin, unsigned width)
1056 {
1057 Location res = begin;
1058 res.columns (width);
1059 return res;
1060 }
1061
1062 /** \brief Add and assign a Location */
1063 inline Location &operator+= (Location& res, unsigned width)
1064 {
1065 res.columns (width);
1066 return res;
1067 }
1068
1069 /** \brief Intercept output stream redirection.
1070 ** \param ostr the destination output stream
1071 ** \param pos a reference to the Position to redirect
1072 **
1073 ** Don't issue twice the line number when the location is on a single line.
1074 */
1075 inline std::ostream& operator<< (std::ostream& ostr, const Location& pos)
1076 {
1077 ostr << pos.begin;
1078 if (pos.begin.filename != pos.end.filename)
1079 ostr << '-' << pos.end - 1;
1080 else if (pos.begin.line != pos.end.line)
1081 ostr << '-' << pos.end.line << '.' << pos.end.column - 1;
1082 else if (pos.begin.column != pos.end.column - 1)
1083 ostr << '-' << pos.end.column - 1;
1084 return ostr;
1085 }
1086
1087 }
1088
1089 #endif // not BISON_LOCATION_HH]