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 ## ---------------- ##
24 # Default Parser class name.
25 m4_define_default([b4_parser_class_name
], [Parser
])
29 ## ----------------- ##
30 ## Semantic Values. ##
31 ## ----------------- ##
34 # b4_lhs_value([TYPE])
35 # --------------------
36 # Expansion of $<TYPE>$.
37 m4_define([b4_lhs_value
],
38 [yyval
[]m4_ifval([$
1], [.$
1])])
41 # b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
42 # --------------------------------------
43 # Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
45 m4_define([b4_rhs_value
],
46 [semantic_stack_@
{m4_eval([$
1 - $
2])@
}m4_ifval([$
3], [.$
3])])
48 m4_define_default([b4_location_type
], [Location
])
53 m4_define([b4_lhs_location
],
57 # b4_rhs_location(RULE-LENGTH, NUM)
58 # ---------------------------------
59 # Expansion of @NUM, where the current rule has RULE-LENGTH symbols
61 m4_define([b4_rhs_location
],
62 [location_stack_@
{m4_eval([$
1 - $
2])@
}])
65 m4_define([b4_inherit
],
77 m4_define([b4_constructor
],
84 # We do want M4 expansion after # for CPP macros.
87 m4_if(b4_defines_flag
, 0, [],
88 [@output @output_header_name@
89 b4_copyright([C
++ Skeleton parser
for LALR(1) parsing with Bison
],
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
97 #include "location.hh"
102 /* Using locations. */
103 #define YYLSP_NEEDED ]b4_locations_flag[
105 ]b4_token_defines(b4_tokens
)[
107 /* Copy the first part of user declarations. */
110 ]/* Line __line__ of lalr1.cc. */
111 b4_syncline([@oline@
], [@ofile@
])[
113 /* Enabling traces. */
115 # define YYDEBUG ]b4_debug[
118 /* Enabling verbose error message. */
119 #ifndef YYERROR_VERBOSE
120 # define YYERROR_VERBOSE ]b4_error_verbose[
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
133 /* Copy the second part of user declarations. */
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;
145 class ]b4_parser_class_name
[;
147 template < typename P
>
153 struct Traits
< ]b4_parser_class_name
[ >
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
;
165 class ]b4_parser_class_name b4_inherit
[
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
;
175 typedef Stack
< StateType
> StateStack
;
176 typedef Stack
< SemanticType
> SemanticStack
;
177 typedef Stack
< LocationType
> LocationStack
;
180 ]b4_parser_class_name
[ (bool debug
,
181 LocationType initlocation
][]b4_param
[) :
182 ]b4_constructor
[][debug_ (debug
),
184 initlocation_ (initlocation
)
186 ]b4_parser_class_name
[ (bool debug
][]b4_param
[) :
187 ]b4_constructor
[][debug_ (debug
),
193 virtual ~]b4_parser_class_name
[ ()
197 virtual int parse ();
201 virtual void lex_ ();
202 virtual void error_ ();
203 virtual void print_ ();
206 StateStack state_stack_
;
207 SemanticStack semantic_stack_
;
208 LocationStack location_stack_
;
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_
[];
222 #if YYDEBUG || YYERROR_VERBOSE
223 static const char* const name_
[];
226 /* More tables, for debugging. */
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_
[];
235 /* Even more tables. */
236 static inline TokenNumberType
translate_ (int token
);
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_
;
258 std::ostream
&cdebug_
;
260 /* Lookahead and lookahead in internal form. */
267 /* Semantic value and location of lookahead token. */
269 LocationType location
;
275 /* Initial location. */
276 LocationType initlocation_
;
280 #endif /* ! defined PARSER_HEADER_H */]
282 @output @output_parser_name@
283 b4_copyright([C
++ Skeleton parser
for LALR(1) parsing with Bison
],
286 m4_if(b4_defines_flag
, 0, [], [#include @output_header_name@])[
288 /* Enable debugging if requested. */
290 # define YYCDEBUG if (debug_) cdebug_
292 # define YYCDEBUG if (0) cdebug_
293 #endif /* !YYDEBUG */
295 #define YYACCEPT goto yyacceptlab
296 #define YYABORT goto yyabortlab
297 #define YYERROR goto yyerrlab1
301 yy::]b4_parser_class_name
[::parse ()
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);
318 location
= initlocation_
;
320 YYCDEBUG
<< "Starting parse" << std::endl
;
324 state_stack_
.push (state_
);
325 YYCDEBUG
<< "Entering state " << state_
<< std::endl
;
331 /* Try to take a decision without lookahead. */
333 if (n_
== pact_ninf_
)
336 /* Read a lookahead token. */
337 if (looka_
== empty_
)
339 YYCDEBUG
<< "Reading a token: ";
343 /* Convert token to internal form. */
348 YYCDEBUG
<< "Now at end of input." << std::endl
;
352 ilooka_
= translate_ (looka_
);
356 YYCDEBUG
<< "Next token is " << looka_
357 << " (" << name_
[ilooka_
];
359 YYCDEBUG
<< ')' << std::endl
;
365 if (n_
< 0 || last_
< n_
|| check_
[n_
] != ilooka_
)
368 /* Reduce or error. */
372 if (n_
== table_ninf_
)
387 /* Shift the lookahead token. */
389 YYCDEBUG
<< "Shifting token " << looka_
390 << " (" << name_
[ilooka_
] << "), ";
393 /* Discard the token being shifted unless it is eof. */
397 semantic_stack_
.push (value
);
398 location_stack_
.push (location
);
400 /* Count tokens shifted since error; after three, turn off error
408 /* Default action. */
410 n_
= defact_
[state_
];
420 yyval
= semantic_stack_
[len_
- 1];
421 yyloc
= location_stack_
[len_
- 1];
425 yyval
= semantic_stack_
[0];
426 yyloc
= location_stack_
[0];
432 // Short files will use "unsigned char" for line numbers,
433 // in which case they will be output as character litterals
435 unsigned yylno
= rline_
[n_
];
436 YYCDEBUG
<< "Reducing via rule " << n_
- 1
437 << " (line " << yylno
<< "), ";
438 for (]b4_int_type_for([b4_prhs
])[ i
= prhs_
[n_
];
440 YYCDEBUG
<< name_
[rhs_
[i
]] << ' ';
441 YYCDEBUG
<< "-> " << name_
[r1_
[n_
]] << std::endl
;
447 Slice
< LocationType
, LocationStack
> slice (location_stack_
, len_
);
448 YYLLOC_DEFAULT (yyloc
, slice
, len_
);
456 ]/* Line __line__ of lalr1.cc. */
457 b4_syncline([@oline@
], [@ofile@
])[
459 state_stack_
.pop (len_
);
460 semantic_stack_
.pop (len_
);
461 location_stack_
.pop (len_
);
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
;
474 semantic_stack_
.push (yyval
);
475 location_stack_
.push (yyloc
);
477 /* Shift the result of the reduction. */
479 state_
= pgoto_
[n_
- ntokens_
] + state_stack_
[0];
480 if (0 <= state_
&& state_
<= last_
&& check_
[state_
] == state_stack_
[0])
481 state_
= table_
[state_
];
483 state_
= defgoto_
[n_
- ntokens_
];
486 /* Report and recover from errors. This is very incomplete. */
488 /* If not already recovering from an error, report this error. */
495 if (pact_ninf_
< n_
&& n_
< last_
)
497 message
= "syntax error, unexpected ";
498 message
+= name_
[ilooka_
];
501 /* Start YYX at -YYN if negative to avoid negative indexes in
503 int xbegin
= n_
< 0 ? -n_
: 0;
504 /* Stay within bounds of both yycheck and yytname. */
505 int checklim
= last_
- n_
;
506 int xend
= checklim
< ntokens_
? checklim
: ntokens_
;
507 for (int x
= xbegin
; x
< xend
; ++x
)
508 if (check_
[x
+ n_
] == x
&& x
!= terror_
)
513 for (int x
= xbegin
; x
< xend
; ++x
)
514 if (check_
[x
+ n_
] == x
&& x
!= terror_
)
516 message
+= (!count
++) ? ", expecting " : " or ";
524 message
= "syntax error";
530 /*----------------------------------------------------.
531 | yyerrlab1 -- error raised explicitly by an action. |
532 `----------------------------------------------------*/
536 /* If just tried and failed to reuse lookahead token after an
537 error, discard it. */
539 /* Return failure if at end of input. */
543 YYCDEBUG
<< "Discarding token " << looka_
544 << " (" << name_
[ilooka_
] << ")." << std::endl
;
549 /* Else will try to reuse lookahead token after shifting the error
557 if (n_
!= pact_ninf_
)
560 if (0 <= n_
&& n_
<= last_
&& check_
[n_
] == terror_
)
568 /* Pop the current state because it cannot handle the error token. */
569 if (state_stack_
.height () == 1)
575 if (stos_
[state_
] < ntokens_
)
577 YYCDEBUG
<< "Error: popping token "
578 << token_number_
[stos_
[state_
]]
579 << " (" << name_
[stos_
[state_
]];
581 YYPRINT (stderr
, token_number_
[stos_
[state_
]],
582 semantic_stack_
.top ());
584 YYCDEBUG
<< ')' << std::endl
;
588 YYCDEBUG
<< "Error: popping nonterminal ("
589 << name_
[stos_
[state_
]] << ')' << std::endl
;
594 state_
= (state_stack_
.pop (), state_stack_
[0]);
595 semantic_stack_
.pop ();
596 location_stack_
.pop ();;
601 YYCDEBUG
<< "Error: state stack now";
602 for (StateStack::ConstIterator i
= state_stack_
.begin ();
603 i
!= state_stack_
.end (); ++i
)
604 YYCDEBUG
<< ' ' << *i
;
605 YYCDEBUG
<< std::endl
;
613 YYCDEBUG
<< "Shifting error token, ";
615 semantic_stack_
.push (value
);
616 location_stack_
.push (location
);
631 yy::]b4_parser_class_name
[::lex_ ()
634 looka_
= yylex (&value
, &location
);
636 looka_
= yylex (&value
);
640 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
642 const ]b4_int_type_for([b4_pact
]) yy::b4_parser_class_name::pact_ninf_
= b4_pact_ninf
[;
643 const ]b4_int_type_for([b4_pact
])[
644 yy::]b4_parser_class_name
[::pact_
[] =
649 /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
650 doesn't specify something else to do. Zero means the default is an
652 const ]b4_int_type_for([b4_defact
])[
653 yy::]b4_parser_class_name
[::defact_
[] =
658 /* YYPGOTO[NTERM-NUM]. */
659 const ]b4_int_type_for([b4_pgoto
])[
660 yy::]b4_parser_class_name
[::pgoto_
[] =
665 /* YYDEFGOTO[NTERM-NUM]. */
666 const ]b4_int_type_for([b4_defgoto
])[
667 yy::]b4_parser_class_name
[::defgoto_
[] =
672 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
673 positive, shift that token. If negative, reduce the rule which
674 number is the opposite. If zero, do what YYDEFACT says. */
675 const ]b4_int_type_for([b4_table
]) yy::b4_parser_class_name::table_ninf_
= b4_table_ninf
[;
676 const ]b4_int_type_for([b4_table
])[
677 yy::]b4_parser_class_name
[::table_
[] =
683 const ]b4_int_type_for([b4_check
])[
684 yy::]b4_parser_class_name
[::check_
[] =
690 /* STOS_[STATE-NUM] -- The (internal number of the) accessing
691 symbol of state STATE-NUM. */
692 const ]b4_int_type_for([b4_stos
])[
693 yy::]b4_parser_class_name
[::stos_
[] =
698 /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal token number corresponding
700 const ]b4_int_type_for([b4_toknum
])[
701 yy::]b4_parser_class_name
[::token_number_
[] =
707 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
708 const ]b4_int_type_for([b4_r1
])[
709 yy::]b4_parser_class_name
[::r1_
[] =
714 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
715 const ]b4_int_type_for([b4_r2
])[
716 yy::]b4_parser_class_name
[::r2_
[] =
721 #if YYDEBUG || YYERROR_VERBOSE
722 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
723 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
725 const yy::]b4_parser_class_name
[::name_
[] =
732 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
733 const yy::]b4_parser_class_name
[::RhsNumberType
734 yy::]b4_parser_class_name
[::rhs_
[] =
739 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
741 const ]b4_int_type_for([b4_prhs
])[
742 yy::]b4_parser_class_name
[::prhs_
[] =
747 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
748 const ]b4_int_type_for([b4_rline
])[
749 yy::]b4_parser_class_name
[::rline_
[] =
755 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
756 yy::]b4_parser_class_name
[::TokenNumberType
757 yy::]b4_parser_class_name
[::translate_ (int token
)
760 const TokenNumberType
765 if ((unsigned) token
<= user_token_number_max_
)
766 return translate_
[token
];
771 const int yy::]b4_parser_class_name
[::eof_
= 0;
772 const int yy::]b4_parser_class_name
[::last_
= ]b4_last
[;
773 const int yy::]b4_parser_class_name
[::nnts_
= ]b4_nterms_number
[;
774 const int yy::]b4_parser_class_name
[::empty_
= -2;
775 const int yy::]b4_parser_class_name
[::final_
= ]b4_final_state_number
[;
776 const int yy::]b4_parser_class_name
[::terror_
= 1;
777 const int yy::]b4_parser_class_name
[::errcode_
= 256;
778 const int yy::]b4_parser_class_name
[::ntokens_
= ]b4_tokens_number
[;
780 const unsigned yy::]b4_parser_class_name
[::user_token_number_max_
= ]b4_user_token_number_max
[;
781 const yy::]b4_parser_class_name
[::TokenNumberType
yy::]b4_parser_class_name
[::undef_token_
= ]b4_undef_token_number
[;
786 b4_copyright([Stack handling
for Bison C
++ parsers
], [2002, 2003])[
788 #ifndef BISON_STACK_HH
789 # define BISON_STACK_HH
795 template < class T
, class S
= std::deque
< T
> >
800 typedef typename
S::iterator Iterator
;
801 typedef typename
S::const_iterator ConstIterator
;
807 Stack (unsigned n
) : seq_ (n
)
813 operator [] (unsigned index
)
820 operator [] (unsigned index
) const
847 inline ConstIterator
begin () const { return seq_
.begin (); }
848 inline ConstIterator
end () const { return seq_
.end (); }
855 template < class T
, class S
= Stack
< T
> >
860 Slice (const S
& stack
,
861 unsigned range
) : stack_ (stack
),
868 operator [] (unsigned index
) const
870 return stack_
[range_
- index
];
880 #endif // not BISON_STACK_HH]
883 b4_copyright([Position
class for Bison C
++ parsers
], [2002, 2003])[
887 ** Define the Location class.
890 #ifndef BISON_POSITION_HH
891 # define BISON_POSITION_HH
898 /** \brief Abstract a Position. */
902 /** \brief Initial column number. */
903 static const unsigned int initial_column
= 0;
904 /** \brief Initial line number. */
905 static const unsigned int initial_line
= 1;
907 /** \name Ctor & dtor.
910 /** \brief Construct a Position. */
914 column (initial_column
)
920 /** \name Line and Column related manipulators
923 /** \brief (line related) Advance to the LINES next lines. */
924 inline void lines (int lines
= 1)
926 column
= initial_column
;
930 /** \brief (column related) Advance to the COLUMNS next columns. */
931 inline void columns (int columns
= 1)
933 int leftmost
= initial_column
;
934 int current
= column
;
935 if (leftmost
<= current
+ columns
)
938 column
= initial_column
;
943 /** \brief File name to which this position refers. */
944 std::string filename
;
945 /** \brief Current line number. */
947 /** \brief Current column number. */
951 /** \brief Add and assign a Position. */
952 inline const Position
&
953 operator+= (Position
& res
, const int width
)
959 /** \brief Add two Position objects. */
960 inline const Position
961 operator+ (const Position
& begin
, const int width
)
963 Position res
= begin
;
967 /** \brief Add and assign a Position. */
968 inline const Position
&
969 operator-= (Position
& res
, const int width
)
971 return res
+= -width
;
974 /** \brief Add two Position objects. */
975 inline const Position
976 operator- (const Position
& begin
, const int width
)
978 return begin
+ -width
;
981 /** \brief Intercept output stream redirection.
982 ** \param ostr the destination output stream
983 ** \param pos a reference to the Position to redirect
986 operator<< (std::ostream
& ostr
, const Position
& pos
)
988 if (pos
.filename
!= "")
989 ostr
<< pos
.filename
<< ':';
990 return ostr
<< pos
.line
<< '.' << pos
.column
;
994 #endif // not BISON_POSITION_HH]
996 b4_copyright([Location
class for Bison C
++ parsers
], [2002, 2003])[
1000 ** Define the Location class.
1003 #ifndef BISON_LOCATION_HH
1004 # define BISON_LOCATION_HH
1006 # include <iostream>
1008 # include "position.hh"
1013 /** \brief Abstract a Location. */
1016 /** \name Ctor & dtor.
1019 /** \brief Construct a Location. */
1028 /** \name Line and Column related manipulators
1031 /** \brief Reset initial location to final location. */
1032 inline void step (void)
1037 /** \brief Extend the current location to the COLUMNS next columns. */
1038 inline void columns (unsigned columns
= 1)
1043 /** \brief Extend the current location to the LINES next lines. */
1044 inline void lines (unsigned lines
= 1)
1052 /** \brief Beginning of the located region. */
1054 /** \brief End of the located region. */
1058 /** \brief Join two Location objects to create a Location. */
1059 inline const Location
operator+ (const Location
& begin
, const Location
& end
)
1061 Location res
= begin
;
1066 /** \brief Add two Location objects */
1067 inline const Location
operator+ (const Location
& begin
, unsigned width
)
1069 Location res
= begin
;
1070 res
.columns (width
);
1074 /** \brief Add and assign a Location */
1075 inline Location
&operator+= (Location
& res
, unsigned width
)
1077 res
.columns (width
);
1081 /** \brief Intercept output stream redirection.
1082 ** \param ostr the destination output stream
1083 ** \param loc a reference to the Location to redirect
1085 ** Avoid duplicate information.
1087 inline std::ostream
& operator<< (std::ostream
& ostr
, const Location
& loc
)
1089 Position last
= loc
.end
- 1;
1091 if (loc
.begin
.filename
!= last
.filename
)
1092 ostr
<< '-' << last
;
1093 else if (loc
.begin
.line
!= last
.line
)
1094 ostr
<< '-' << last
.line
<< '.' << last
.column
;
1095 else if (loc
.begin
.column
!= last
.column
)
1096 ostr
<< '-' << last
.column
;
1102 #endif // not BISON_LOCATION_HH]