2 # C++ skeleton for Bison
3 # Copyright (C) 2002, 2003 Free Software Foundation, Inc.
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.
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.
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
20 ## ---------------- ##
22 ## ---------------- ##
25 m4_define_default([b4_stack_depth_init
], [200])
27 # Default Parser class name.
28 m4_define_default([b4_parser_class_name
], [Parser
])
32 ## ----------------- ##
33 ## Semantic Values. ##
34 ## ----------------- ##
37 # b4_lhs_value([TYPE])
38 # --------------------
39 # Expansion of $<TYPE>$.
40 m4_define([b4_lhs_value
],
41 [yyval
[]m4_ifval([$
1], [.$
1])])
44 # b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
45 # --------------------------------------
46 # Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
48 m4_define([b4_rhs_value
],
49 [semantic_stack_@
{m4_eval([$
1 - $
2])@
}m4_ifval([$
3], [.$
3])])
51 m4_define_default([b4_location_type
], [Location
])
56 m4_define([b4_lhs_location
],
60 # b4_rhs_location(RULE-LENGTH, NUM)
61 # ---------------------------------
62 # Expansion of @NUM, where the current rule has RULE-LENGTH symbols
64 m4_define([b4_rhs_location
],
65 [location_stack_@
{m4_eval([$
1 - $
2])@
}])
68 m4_define([b4_inherit
],
80 m4_define([b4_constructor
],
87 # We do want M4 expansion after # for CPP macros.
90 m4_if(b4_defines_flag
, 0, [],
91 [@output @output_header_name@
92 b4_copyright([C
++ Skeleton parser
for LALR(1) parsing with Bison
],
94 /* FIXME: This is wrong, we want computed header guards.
95 I don't know why the macros are missing now. :( */
96 #ifndef PARSER_HEADER_H
97 # define PARSER_HEADER_H
100 #include "location.hh"
105 /* Using locations. */
106 #define YYLSP_NEEDED ]b4_locations_flag[
108 ]b4_token_defines(b4_tokens
)[
110 /* Copy the first part of user declarations. */
113 ]/* Line __line__ of lalr1.cc. */
114 b4_syncline([@oline@
], [@ofile@
])[
116 /* Enabling traces. */
118 # define YYDEBUG ]b4_debug[
121 /* Enabling verbose error message. */
122 #ifndef YYERROR_VERBOSE
123 # define YYERROR_VERBOSE ]b4_error_verbose[
127 ]m4_ifdef([b4_stype
],
128 [b4_syncline([b4_stype_line
], [b4_filename
])
129 typedef union b4_stype yystype
;
130 /* Line __line__ of lalr1.cc. */
131 b4_syncline([@oline@
], [@ofile@
])],
132 [typedef int yystype
;])[
133 # define YYSTYPE yystype
136 /* Copy the second part of user declarations. */
139 ]/* Line __line__ of lalr1.cc. */
140 b4_syncline([@oline@
], [@ofile@
])[
141 #ifndef YYLLOC_DEFAULT
142 # define YYLLOC_DEFAULT(Current, Rhs, N) \
143 Current.end = Rhs[N].end;
148 class ]b4_parser_class_name
[;
150 template < typename P
>
156 struct Traits
< ]b4_parser_class_name
[ >
158 typedef ]b4_int_type_for([b4_translate
])[ TokenNumberType
;
159 typedef ]b4_int_type_for([b4_rhs
])[ RhsNumberType
;
160 typedef int StateType
;
161 typedef yystype SemanticType
;
162 typedef ]b4_location_type
[ LocationType
;
168 class ]b4_parser_class_name b4_inherit
[
172 typedef Traits
< ]b4_parser_class_name
[ >::TokenNumberType TokenNumberType
;
173 typedef Traits
< ]b4_parser_class_name
[ >::RhsNumberType RhsNumberType
;
174 typedef Traits
< ]b4_parser_class_name
[ >::StateType StateType
;
175 typedef Traits
< ]b4_parser_class_name
[ >::SemanticType SemanticType
;
176 typedef Traits
< ]b4_parser_class_name
[ >::LocationType LocationType
;
178 typedef Stack
< StateType
> StateStack
;
179 typedef Stack
< SemanticType
> SemanticStack
;
180 typedef Stack
< LocationType
> LocationStack
;
183 ]b4_parser_class_name
[ (bool debug
,
184 LocationType initlocation
][]b4_param
[) :
185 ]b4_constructor
[][debug_ (debug
),
187 initlocation_ (initlocation
)
189 ]b4_parser_class_name
[ (bool debug
][]b4_param
[) :
190 ]b4_constructor
[][debug_ (debug
),
196 virtual ~]b4_parser_class_name
[ ()
200 virtual int parse ();
204 virtual void lex_ ();
205 virtual void error_ ();
206 virtual void print_ ();
209 StateStack state_stack_
;
210 SemanticStack semantic_stack_
;
211 LocationStack location_stack_
;
214 static const ]b4_int_type_for([b4_pact
])[ pact_
[];
215 static const ]b4_int_type_for([b4_pact
])[ pact_ninf_
;
216 static const ]b4_int_type_for([b4_defact
])[ defact_
[];
217 static const ]b4_int_type_for([b4_pgoto
])[ pgoto_
[];
218 static const ]b4_int_type_for([b4_defgoto
])[ defgoto_
[];
219 static const ]b4_int_type_for([b4_table
])[ table_
[];
220 static const ]b4_int_type_for([b4_table
])[ table_ninf_
;
221 static const ]b4_int_type_for([b4_check
])[ check_
[];
222 static const ]b4_int_type_for([b4_r1
])[ r1_
[];
223 static const ]b4_int_type_for([b4_r2
])[ r2_
[];
225 #if YYDEBUG || YYERROR_VERBOSE
226 static const char* const name_
[];
229 /* More tables, for debugging. */
231 static const RhsNumberType rhs_
[];
232 static const ]b4_int_type_for([b4_prhs
])[ prhs_
[];
233 static const ]b4_int_type_for([b4_rline
])[ rline_
[];
234 static const ]b4_int_type_for([b4_stos
])[ stos_
[];
235 static const ]b4_int_type_for([b4_toknum
])[ token_number_
[];
238 /* Even more tables. */
239 static inline TokenNumberType
translate_ (int token
);
242 static const int eof_
;
243 /* LAST_ -- Last index in TABLE_. */
244 static const int last_
;
245 static const int nnts_
;
246 static const int empty_
;
247 static const int final_
;
248 static const int terror_
;
249 static const int errcode_
;
250 static const int ntokens_
;
251 static const int initdepth_
;
252 static const unsigned user_token_number_max_
;
253 static const TokenNumberType undef_token_
;
262 std::ostream
&cdebug_
;
264 /* Lookahead and lookahead in internal form. */
271 /* Semantic value and location of lookahead token. */
273 LocationType location
;
279 /* Initial location. */
280 LocationType initlocation_
;
284 #endif /* ! defined PARSER_HEADER_H */]
286 @output @output_parser_name@
287 b4_copyright([C
++ Skeleton parser
for LALR(1) parsing with Bison
],
290 m4_if(b4_defines_flag
, 0, [], [#include @output_header_name@])[
292 /* Enable debugging if requested. */
294 # define YYCDEBUG if (debug_) cdebug_
296 # define YYCDEBUG if (0) cdebug_
297 #endif /* !YYDEBUG */
300 yy::]b4_parser_class_name
[::parse ()
305 /* Initialize the stacks. The initial state will be pushed in
306 yynewstate, since the latter expects the semantical and the
307 location values to have been already stored, initialize these
308 stacks with a primary value. */
309 state_stack_
= StateStack (0);
310 semantic_stack_
= SemanticStack (1);
311 location_stack_
= LocationStack (1);
317 location
= initlocation_
;
319 YYCDEBUG
<< "Starting parse" << std::endl
;
323 state_stack_
.push (state_
);
324 YYCDEBUG
<< "Entering state " << state_
<< std::endl
;
330 /* Try to take a decision without lookahead. */
332 if (n_
== pact_ninf_
)
335 /* Read a lookahead token. */
336 if (looka_
== empty_
)
338 YYCDEBUG
<< "Reading a token: ";
342 /* Convert token to internal form. */
347 YYCDEBUG
<< "Now at end of input." << std::endl
;
351 ilooka_
= translate_ (looka_
);
355 YYCDEBUG
<< "Next token is " << looka_
356 << " (" << name_
[ilooka_
];
358 YYCDEBUG
<< ')' << std::endl
;
364 if (n_
< 0 || last_
< n_
|| check_
[n_
] != ilooka_
)
367 /* Reduce or error. */
371 if (n_
== table_ninf_
)
386 /* Shift the lookahead token. */
388 YYCDEBUG
<< "Shifting token " << looka_
389 << " (" << name_
[ilooka_
] << "), ";
392 /* Discard the token being shifted unless it is eof. */
396 semantic_stack_
.push (value
);
397 location_stack_
.push (location
);
399 /* Count tokens shifted since error; after three, turn off error
407 /* Default action. */
409 n_
= defact_
[state_
];
419 yyval
= semantic_stack_
[len_
- 1];
420 yyloc
= location_stack_
[len_
- 1];
424 yyval
= semantic_stack_
[0];
425 yyloc
= location_stack_
[0];
431 YYCDEBUG
<< "Reducing via rule " << n_
- 1
432 << " (line " << rline_
[n_
] << "), ";
433 for (]b4_int_type_for([b4_prhs
])[ i
= prhs_
[n_
];
435 YYCDEBUG
<< name_
[rhs_
[i
]] << ' ';
436 YYCDEBUG
<< "-> " << name_
[r1_
[n_
]] << std::endl
;
442 Slice
< LocationType
, LocationStack
> slice (location_stack_
, len_
);
443 YYLLOC_DEFAULT (yyloc
, slice
, len_
);
451 ]/* Line __line__ of lalr1.cc. */
452 b4_syncline([@oline@
], [@ofile@
])[
454 state_stack_
.pop (len_
);
455 semantic_stack_
.pop (len_
);
456 location_stack_
.pop (len_
);
461 YYCDEBUG
<< "state stack now";
462 for (StateStack::ConstIterator i
= state_stack_
.begin ();
463 i
!= state_stack_
.end (); ++i
)
464 YYCDEBUG
<< ' ' << *i
;
465 YYCDEBUG
<< std::endl
;
469 semantic_stack_
.push (yyval
);
470 location_stack_
.push (yyloc
);
472 /* Shift the result of the reduction. */
474 state_
= pgoto_
[n_
- ntokens_
] + state_stack_
[0];
475 if (0 <= state_
&& state_
<= last_
&& check_
[state_
] == state_stack_
[0])
476 state_
= table_
[state_
];
478 state_
= defgoto_
[n_
- ntokens_
];
481 /* Report and recover from errors. This is very incomplete. */
483 /* If not already recovering from an error, report this error. */
490 if (pact_ninf_
< n_
&& n_
< last_
)
492 message
= "syntax error, unexpected ";
493 message
+= name_
[ilooka_
];
496 for (int x
= (n_
< 0 ? -n_
: 0); x
< ntokens_
+ nnts_
; ++x
)
497 if (check_
[x
+ n_
] == x
&& x
!= terror_
)
502 for (int x
= (n_
< 0 ? -n_
: 0); x
< ntokens_
+ nnts_
; ++x
)
503 if (check_
[x
+ n_
] == x
&& x
!= terror_
)
505 message
+= (!count
++) ? ", expecting " : " or ";
513 message
= "syntax error";
518 /* Error raised explicitly by an action. */
522 /* If just tried and failed to reuse lookahead token after an
523 error, discard it. */
525 /* Return failure if at end of input. */
529 YYCDEBUG
<< "Discarding token " << looka_
530 << " (" << name_
[ilooka_
] << ")." << std::endl
;
535 /* Else will try to reuse lookahead token after shifting the error
543 if (n_
!= pact_ninf_
)
546 if (0 <= n_
&& n_
<= last_
&& check_
[n_
] == terror_
)
554 /* Pop the current state because it cannot handle the error token. */
555 if (state_stack_
.height () == 1)
561 if (stos_
[state_
] < ntokens_
)
563 YYCDEBUG
<< "Error: popping token "
564 << token_number_
[stos_
[state_
]]
565 << " (" << name_
[stos_
[state_
]];
567 YYPRINT (stderr
, token_number_
[stos_
[state_
]],
568 semantic_stack_
.top ());
570 YYCDEBUG
<< ')' << std::endl
;
574 YYCDEBUG
<< "Error: popping nonterminal ("
575 << name_
[stos_
[state_
]] << ')' << std::endl
;
580 state_
= (state_stack_
.pop (), state_stack_
[0]);
581 semantic_stack_
.pop ();
582 location_stack_
.pop ();;
587 YYCDEBUG
<< "Error: state stack now";
588 for (StateStack::ConstIterator i
= state_stack_
.begin ();
589 i
!= state_stack_
.end (); ++i
)
590 YYCDEBUG
<< ' ' << *i
;
591 YYCDEBUG
<< std::endl
;
599 YYCDEBUG
<< "Shifting error token, ";
601 semantic_stack_
.push (value
);
602 location_stack_
.push (location
);
617 yy::]b4_parser_class_name
[::lex_ ()
620 looka_
= yylex (&value
, &location
);
622 looka_
= yylex (&value
);
626 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
628 const ]b4_int_type_for([b4_pact
]) yy::b4_parser_class_name::pact_ninf_
= b4_pact_ninf
[;
629 const ]b4_int_type_for([b4_pact
])[
630 yy::]b4_parser_class_name
[::pact_
[] =
635 /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
636 doesn't specify something else to do. Zero means the default is an
638 const ]b4_int_type_for([b4_defact
])[
639 yy::]b4_parser_class_name
[::defact_
[] =
644 /* YYPGOTO[NTERM-NUM]. */
645 const ]b4_int_type_for([b4_pgoto
])[
646 yy::]b4_parser_class_name
[::pgoto_
[] =
651 /* YYDEFGOTO[NTERM-NUM]. */
652 const ]b4_int_type_for([b4_defgoto
])[
653 yy::]b4_parser_class_name
[::defgoto_
[] =
658 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
659 positive, shift that token. If negative, reduce the rule which
660 number is the opposite. If zero, do what YYDEFACT says. */
661 const ]b4_int_type_for([b4_table
]) yy::b4_parser_class_name::table_ninf_
= b4_table_ninf
[;
662 const ]b4_int_type_for([b4_table
])[
663 yy::]b4_parser_class_name
[::table_
[] =
669 const ]b4_int_type_for([b4_check
])[
670 yy::]b4_parser_class_name
[::check_
[] =
676 /* STOS_[STATE-NUM] -- The (internal number of the) accessing
677 symbol of state STATE-NUM. */
678 const ]b4_int_type_for([b4_stos
])[
679 yy::]b4_parser_class_name
[::stos_
[] =
684 /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal token number corresponding
686 const ]b4_int_type_for([b4_toknum
])[
687 yy::]b4_parser_class_name
[::token_number_
[] =
693 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
694 const ]b4_int_type_for([b4_r1
])[
695 yy::]b4_parser_class_name
[::r1_
[] =
700 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
701 const ]b4_int_type_for([b4_r2
])[
702 yy::]b4_parser_class_name
[::r2_
[] =
707 #if YYDEBUG || YYERROR_VERBOSE
708 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
709 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
711 const yy::]b4_parser_class_name
[::name_
[] =
718 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
719 const yy::]b4_parser_class_name
[::RhsNumberType
720 yy::]b4_parser_class_name
[::rhs_
[] =
725 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
727 const ]b4_int_type_for([b4_prhs
])[
728 yy::]b4_parser_class_name
[::prhs_
[] =
733 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
734 const ]b4_int_type_for([b4_rline
])[
735 yy::]b4_parser_class_name
[::rline_
[] =
741 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
742 yy::]b4_parser_class_name
[::TokenNumberType
743 yy::]b4_parser_class_name
[::translate_ (int token
)
746 const TokenNumberType
751 if ((unsigned) token
<= user_token_number_max_
)
752 return translate_
[token
];
757 const int yy::]b4_parser_class_name
[::eof_
= 0;
758 const int yy::]b4_parser_class_name
[::last_
= ]b4_last
[;
759 const int yy::]b4_parser_class_name
[::nnts_
= ]b4_nterms_number
[;
760 const int yy::]b4_parser_class_name
[::empty_
= -2;
761 const int yy::]b4_parser_class_name
[::final_
= ]b4_final_state_number
[;
762 const int yy::]b4_parser_class_name
[::terror_
= 1;
763 const int yy::]b4_parser_class_name
[::errcode_
= 256;
764 const int yy::]b4_parser_class_name
[::ntokens_
= ]b4_tokens_number
[;
765 const int yy::]b4_parser_class_name
[::initdepth_
= ]b4_stack_depth_init
[;
767 const unsigned yy::]b4_parser_class_name
[::user_token_number_max_
= ]b4_user_token_number_max
[;
768 const yy::]b4_parser_class_name
[::TokenNumberType
yy::]b4_parser_class_name
[::undef_token_
= ]b4_undef_token_number
[;
773 b4_copyright([Stack handling
for Bison C
++ parsers
], [2002, 2003])[
775 #ifndef BISON_STACK_HH
776 # define BISON_STACK_HH
782 template < class T
, class S
= std::deque
< T
> >
787 typedef typename
S::iterator Iterator
;
788 typedef typename
S::const_iterator ConstIterator
;
794 Stack (unsigned n
) : seq_ (n
)
800 operator [] (unsigned index
)
807 operator [] (unsigned index
) const
834 inline ConstIterator
begin () const { return seq_
.begin (); }
835 inline ConstIterator
end () const { return seq_
.end (); }
842 template < class T
, class S
= Stack
< T
> >
847 Slice (const S
& stack
,
848 unsigned range
) : stack_ (stack
),
855 operator [] (unsigned index
) const
857 return stack_
[range_
- index
];
867 #endif // not BISON_STACK_HH]
870 b4_copyright([Location
class for Bison C
++ parsers
], [2002, 2003])[
872 #ifndef BISON_LOCATION_HH
873 # define BISON_LOCATION_HH
884 : filename (), line (1), column (0)
887 std::string filename
;
893 operator<< (std::ostream
& ostr
, const Position
& pos
)
895 if (pos
.filename
!= "")
896 ostr
<< pos
.filename
<< ':';
897 ostr
<< pos
.line
<< '.' << pos
.column
;
902 operator- (const Position
& pos
, int col
)
917 /* Don't issue twice the line number when the location is on a single
921 operator<< (std::ostream
& ostr
, const Location
& pos
)
924 if (pos
.begin
.filename
!= pos
.end
.filename
)
925 ostr
<< '-' << pos
.end
- 1;
926 else if (pos
.begin
.line
!= pos
.end
.line
)
927 ostr
<< '-' << pos
.end
.line
<< '.' << pos
.end
.column
- 1;
928 else if (pos
.begin
.column
!= pos
.end
.column
- 1)
929 ostr
<< '-' << pos
.end
.column
- 1;
935 #endif // not BISON_LOCATION_HH]