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
],
86 # Constructor's extra arguments.
87 m4_define([b4_parse_param_decl],
88 [m4_ifset([b4_parse_param], [, b4_c_ansi_formals(b4_parse_param)])])
92 # constructor's extra initialisations.
93 m4_define([b4_parse_param_cons
],
94 [m4_ifset([b4_parse_param
],
96 b4_cc_constructor_calls(b4_parse_param
)])])
97 m4_define([b4_cc_constructor_calls
],
98 [m4_map_sep([b4_cc_constructor_call
], [,
100 m4_define([b4_cc_constructor_call
],
103 # b4_parse_param_vars
104 # -------------------
105 # Extra instance variables.
106 m4_define([b4_parse_param_vars
],
107 [m4_ifset([b4_parse_param
],
109 /* User arguments. */
110 b4_cc_var_decls(b4_parse_param
)])])
111 m4_define([b4_cc_var_decls
],
112 [m4_map_sep([b4_cc_var_decl
], [
114 m4_define([b4_cc_var_decl
],
117 # We do want M4 expansion after # for CPP macros.
120 m4_if(b4_defines_flag
, 0, [],
121 [@output @output_header_name@
122 b4_copyright([C
++ Skeleton parser
for LALR(1) parsing with Bison
],
124 /* FIXME: This is wrong, we want computed header guards.
125 I don't know why the macros are missing now. :( */
126 #ifndef PARSER_HEADER_H
127 # define PARSER_HEADER_H
130 #include "location.hh"
135 /* Using locations. */
136 #define YYLSP_NEEDED ]b4_locations_flag[
138 ]b4_token_defines(b4_tokens
)[
140 /* Copy the first part of user declarations. */
143 ]/* Line __line__ of lalr1.cc. */
144 b4_syncline([@oline@
], [@ofile@
])[
146 /* Enabling traces. */
148 # define YYDEBUG ]b4_debug[
151 /* Enabling verbose error message. */
152 #ifndef YYERROR_VERBOSE
153 # define YYERROR_VERBOSE ]b4_error_verbose[
157 ]m4_ifdef([b4_stype
],
158 [b4_syncline([b4_stype_line
], [b4_filename
])
159 typedef union b4_stype yystype
;
160 /* Line __line__ of lalr1.cc. */
161 b4_syncline([@oline@
], [@ofile@
])],
162 [typedef int yystype
;])[
163 # define YYSTYPE yystype
166 /* Copy the second part of user declarations. */
169 ]/* Line __line__ of lalr1.cc. */
170 b4_syncline([@oline@
], [@ofile@
])[
171 #ifndef YYLLOC_DEFAULT
172 # define YYLLOC_DEFAULT(Current, Rhs, N) \
173 ((Current).end = Rhs[N].end)
178 class ]b4_parser_class_name
[;
180 template < typename P
>
186 struct Traits
< ]b4_parser_class_name
[ >
188 typedef ]b4_int_type_for([b4_translate
])[ TokenNumberType
;
189 typedef ]b4_int_type_for([b4_rhs
])[ RhsNumberType
;
190 typedef int StateType
;
191 typedef yystype SemanticType
;
192 typedef ]b4_location_type
[ LocationType
;
198 class ]b4_parser_class_name b4_inherit
[
202 typedef Traits
< ]b4_parser_class_name
[ >::TokenNumberType TokenNumberType
;
203 typedef Traits
< ]b4_parser_class_name
[ >::RhsNumberType RhsNumberType
;
204 typedef Traits
< ]b4_parser_class_name
[ >::StateType StateType
;
205 typedef Traits
< ]b4_parser_class_name
[ >::SemanticType SemanticType
;
206 typedef Traits
< ]b4_parser_class_name
[ >::LocationType LocationType
;
208 typedef Stack
< StateType
> StateStack
;
209 typedef Stack
< SemanticType
> SemanticStack
;
210 typedef Stack
< LocationType
> LocationStack
;
213 ]b4_parser_class_name
[ (bool debug
,
214 LocationType initlocation
][]b4_param
[]b4_parse_param_decl
[) :
215 ]b4_constructor
[][debug_ (debug
),
217 initlocation_ (initlocation
)]b4_parse_param_cons
[
219 ]b4_parser_class_name
[ (bool debug
][]b4_param
[]b4_parse_param_decl
[) :
220 ]b4_constructor
[][debug_ (debug
),
221 cdebug_ (std::cerr
)]b4_parse_param_cons
[
226 virtual ~]b4_parser_class_name
[ ()
230 virtual int parse ();
234 virtual void lex_ ();
235 virtual void error_ ();
236 virtual void print_ ();
239 StateStack state_stack_
;
240 SemanticStack semantic_stack_
;
241 LocationStack location_stack_
;
244 static const ]b4_int_type_for([b4_pact
])[ pact_
[];
245 static const ]b4_int_type(b4_pact_ninf
, b4_pact_ninf
)[ pact_ninf_
;
246 static const ]b4_int_type_for([b4_defact
])[ defact_
[];
247 static const ]b4_int_type_for([b4_pgoto
])[ pgoto_
[];
248 static const ]b4_int_type_for([b4_defgoto
])[ defgoto_
[];
249 static const ]b4_int_type_for([b4_table
])[ table_
[];
250 static const ]b4_int_type(b4_table_ninf
, b4_table_ninf
)[ table_ninf_
;
251 static const ]b4_int_type_for([b4_check
])[ check_
[];
252 static const ]b4_int_type_for([b4_r1
])[ r1_
[];
253 static const ]b4_int_type_for([b4_r2
])[ r2_
[];
255 #if YYDEBUG || YYERROR_VERBOSE
256 static const char* const name_
[];
259 /* More tables, for debugging. */
261 static const RhsNumberType rhs_
[];
262 static const ]b4_int_type_for([b4_prhs
])[ prhs_
[];
263 static const ]b4_int_type_for([b4_rline
])[ rline_
[];
264 static const ]b4_int_type_for([b4_stos
])[ stos_
[];
265 static const ]b4_int_type_for([b4_toknum
])[ token_number_
[];
268 /* Even more tables. */
269 static inline TokenNumberType
translate_ (int token
);
272 static const int eof_
;
273 /* LAST_ -- Last index in TABLE_. */
274 static const int last_
;
275 static const int nnts_
;
276 static const int empty_
;
277 static const int final_
;
278 static const int terror_
;
279 static const int errcode_
;
280 static const int ntokens_
;
281 static const unsigned user_token_number_max_
;
282 static const TokenNumberType undef_token_
;
291 std::ostream
&cdebug_
;
293 /* Lookahead and lookahead in internal form. */
300 /* Semantic value and location of lookahead token. */
302 LocationType location
;
308 /* Initial location. */
309 LocationType initlocation_
;
310 ]b4_parse_param_vars
[
314 #endif /* ! defined PARSER_HEADER_H */]
316 @output @output_parser_name@
317 b4_copyright([C
++ Skeleton parser
for LALR(1) parsing with Bison
],
320 m4_if(b4_defines_flag
, 0, [], [#include @output_header_name@])[
322 /* Enable debugging if requested. */
324 # define YYCDEBUG if (debug_) cdebug_
326 # define YYCDEBUG if (0) cdebug_
327 #endif /* !YYDEBUG */
329 #define YYACCEPT goto yyacceptlab
330 #define YYABORT goto yyabortlab
331 #define YYERROR goto yyerrorlab
335 yy::]b4_parser_class_name
[::parse ()
340 /* Initialize the stacks. The initial state will be pushed in
341 yynewstate, since the latter expects the semantical and the
342 location values to have been already stored, initialize these
343 stacks with a primary value. */
344 state_stack_
= StateStack (0);
345 semantic_stack_
= SemanticStack (1);
346 location_stack_
= LocationStack (1);
352 location
= initlocation_
;
354 YYCDEBUG
<< "Starting parse" << std::endl
;
358 state_stack_
.push (state_
);
359 YYCDEBUG
<< "Entering state " << state_
<< std::endl
;
365 /* Try to take a decision without lookahead. */
367 if (n_
== pact_ninf_
)
370 /* Read a lookahead token. */
371 if (looka_
== empty_
)
373 YYCDEBUG
<< "Reading a token: ";
377 /* Convert token to internal form. */
382 YYCDEBUG
<< "Now at end of input." << std::endl
;
386 ilooka_
= translate_ (looka_
);
390 YYCDEBUG
<< "Next token is " << looka_
391 << " (" << name_
[ilooka_
];
393 YYCDEBUG
<< ')' << std::endl
;
398 /* If the proper action on seeing token YYTOKEN is to reduce or to
399 detect an error, take that action. */
401 if (n_
< 0 || last_
< n_
|| check_
[n_
] != ilooka_
)
404 /* Reduce or error. */
408 if (n_
== table_ninf_
)
423 /* Shift the lookahead token. */
425 YYCDEBUG
<< "Shifting token " << looka_
426 << " (" << name_
[ilooka_
] << "), ";
429 /* Discard the token being shifted unless it is eof. */
433 semantic_stack_
.push (value
);
434 location_stack_
.push (location
);
436 /* Count tokens shifted since error; after three, turn off error
444 /*-----------------------------------------------------------.
445 | yydefault -- do the default action for the current state. |
446 `-----------------------------------------------------------*/
448 n_
= defact_
[state_
];
453 /*-----------------------------.
454 | yyreduce -- Do a reduction. |
455 `-----------------------------*/
458 /* If LEN_ is nonzero, implement the default value of the action:
459 `$$ = $1'. Otherwise, use the top of the stack.
461 Otherwise, the following line sets YYVAL to garbage.
462 This behavior is undocumented and Bison
463 users should not rely upon it. */
466 yyval
= semantic_stack_
[len_
- 1];
467 yyloc
= location_stack_
[len_
- 1];
471 yyval
= semantic_stack_
[0];
472 yyloc
= location_stack_
[0];
478 // Short files will use "unsigned char" for line numbers,
479 // in which case they will be output as character litterals
481 unsigned yylno
= rline_
[n_
];
482 YYCDEBUG
<< "Reducing via rule " << n_
- 1
483 << " (line " << yylno
<< "), ";
484 for (]b4_int_type_for([b4_prhs
])[ i
= prhs_
[n_
];
486 YYCDEBUG
<< name_
[rhs_
[i
]] << ' ';
487 YYCDEBUG
<< "-> " << name_
[r1_
[n_
]] << std::endl
;
493 Slice
< LocationType
, LocationStack
> slice (location_stack_
, len_
);
494 YYLLOC_DEFAULT (yyloc
, slice
, len_
);
502 ]/* Line __line__ of lalr1.cc. */
503 b4_syncline([@oline@
], [@ofile@
])[
505 state_stack_
.pop (len_
);
506 semantic_stack_
.pop (len_
);
507 location_stack_
.pop (len_
);
512 YYCDEBUG
<< "state stack now";
513 for (StateStack::ConstIterator i
= state_stack_
.begin ();
514 i
!= state_stack_
.end (); ++i
)
515 YYCDEBUG
<< ' ' << *i
;
516 YYCDEBUG
<< std::endl
;
520 semantic_stack_
.push (yyval
);
521 location_stack_
.push (yyloc
);
523 /* Shift the result of the reduction. */
525 state_
= pgoto_
[n_
- ntokens_
] + state_stack_
[0];
526 if (0 <= state_
&& state_
<= last_
&& check_
[state_
] == state_stack_
[0])
527 state_
= table_
[state_
];
529 state_
= defgoto_
[n_
- ntokens_
];
532 /*------------------------------------.
533 | yyerrlab -- here on detecting error |
534 `------------------------------------*/
536 /* If not already recovering from an error, report this error. */
543 if (pact_ninf_
< n_
&& n_
< last_
)
545 message
= "syntax error, unexpected ";
546 message
+= name_
[ilooka_
];
549 /* Start YYX at -YYN if negative to avoid negative indexes in
551 int xbegin
= n_
< 0 ? -n_
: 0;
552 /* Stay within bounds of both yycheck and yytname. */
553 int checklim
= last_
- n_
;
554 int xend
= checklim
< ntokens_
? checklim
: ntokens_
;
555 for (int x
= xbegin
; x
< xend
; ++x
)
556 if (check_
[x
+ n_
] == x
&& x
!= terror_
)
561 for (int x1
= xbegin
; x1
< xend
; ++x1
)
562 if (check_
[x1
+ n_
] == x1
&& x1
!= terror_
)
564 message
+= (!count
++) ? ", expecting " : " or ";
565 message
+= name_
[x1
];
572 message
= "syntax error";
578 /* If just tried and failed to reuse lookahead token after an
579 error, discard it. */
581 /* Return failure if at end of input. */
584 /* If at end of input, pop the error token,
585 then the rest of the stack, then return failure. */
590 semantic_stack_
.pop ();
591 location_stack_
.pop ();
592 if (state_stack_
.height () == 1)
594 // YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
595 // FIXME: yydestruct (yystos[*yyssp], yyvsp]b4_location_if([, yylsp])[);
601 YYCDEBUG
<< "Discarding token " << looka_
602 << " (" << name_
[ilooka_
] << ")." << std::endl
;
603 // yydestruct (yytoken, &yylval]b4_location_if([, &yylloc])[);
609 /* Else will try to reuse lookahead token after shifting the error
614 /*---------------------------------------------------.
615 | yyerrorlab -- error raised explicitly by YYERROR. |
616 `---------------------------------------------------*/
619 state_stack_
.pop (len_
);
620 semantic_stack_
.pop (len_
);
621 location_stack_
.pop (len_
);
622 state_
= state_stack_
[0];
625 /*-------------------------------------------------------------.
626 | yyerrlab1 -- common code for both syntax error and YYERROR. |
627 `-------------------------------------------------------------*/
629 errstatus
= 3; /* Each real token shifted decrements this. */
634 if (n_
!= pact_ninf_
)
637 if (0 <= n_
&& n_
<= last_
&& check_
[n_
] == terror_
)
645 /* Pop the current state because it cannot handle the error token. */
646 if (state_stack_
.height () == 1)
652 if (stos_
[state_
] < ntokens_
)
654 YYCDEBUG
<< "Error: popping token "
655 << token_number_
[stos_
[state_
]]
656 << " (" << name_
[stos_
[state_
]];
658 YYPRINT (stderr
, token_number_
[stos_
[state_
]],
659 semantic_stack_
.top ());
661 YYCDEBUG
<< ')' << std::endl
;
665 YYCDEBUG
<< "Error: popping nonterminal ("
666 << name_
[stos_
[state_
]] << ')' << std::endl
;
672 semantic_stack_
.pop ();
673 location_stack_
.pop ();
674 state_
= state_stack_
[0];
679 YYCDEBUG
<< "Error: state stack now";
680 for (StateStack::ConstIterator i
= state_stack_
.begin ();
681 i
!= state_stack_
.end (); ++i
)
682 YYCDEBUG
<< ' ' << *i
;
683 YYCDEBUG
<< std::endl
;
691 YYCDEBUG
<< "Shifting error token, ";
693 semantic_stack_
.push (value
);
694 location_stack_
.push (location
);
709 yy::]b4_parser_class_name
[::lex_ ()
712 looka_
= yylex (&value
, &location
);
714 looka_
= yylex (&value
);
718 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
720 const ]b4_int_type(b4_pact_ninf
, b4_pact_ninf
) yy::b4_parser_class_name::pact_ninf_
= b4_pact_ninf
[;
721 const ]b4_int_type_for([b4_pact
])[
722 yy::]b4_parser_class_name
[::pact_
[] =
727 /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
728 doesn't specify something else to do. Zero means the default is an
730 const ]b4_int_type_for([b4_defact
])[
731 yy::]b4_parser_class_name
[::defact_
[] =
736 /* YYPGOTO[NTERM-NUM]. */
737 const ]b4_int_type_for([b4_pgoto
])[
738 yy::]b4_parser_class_name
[::pgoto_
[] =
743 /* YYDEFGOTO[NTERM-NUM]. */
744 const ]b4_int_type_for([b4_defgoto
])[
745 yy::]b4_parser_class_name
[::defgoto_
[] =
750 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
751 positive, shift that token. If negative, reduce the rule which
752 number is the opposite. If zero, do what YYDEFACT says. */
753 const ]b4_int_type(b4_table_ninf
, b4_table_ninf
) yy::b4_parser_class_name::table_ninf_
= b4_table_ninf
[;
754 const ]b4_int_type_for([b4_table
])[
755 yy::]b4_parser_class_name
[::table_
[] =
761 const ]b4_int_type_for([b4_check
])[
762 yy::]b4_parser_class_name
[::check_
[] =
768 /* STOS_[STATE-NUM] -- The (internal number of the) accessing
769 symbol of state STATE-NUM. */
770 const ]b4_int_type_for([b4_stos
])[
771 yy::]b4_parser_class_name
[::stos_
[] =
776 /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal token number corresponding
778 const ]b4_int_type_for([b4_toknum
])[
779 yy::]b4_parser_class_name
[::token_number_
[] =
785 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
786 const ]b4_int_type_for([b4_r1
])[
787 yy::]b4_parser_class_name
[::r1_
[] =
792 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
793 const ]b4_int_type_for([b4_r2
])[
794 yy::]b4_parser_class_name
[::r2_
[] =
799 #if YYDEBUG || YYERROR_VERBOSE
800 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
801 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
803 const yy::]b4_parser_class_name
[::name_
[] =
810 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
811 const yy::]b4_parser_class_name
[::RhsNumberType
812 yy::]b4_parser_class_name
[::rhs_
[] =
817 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
819 const ]b4_int_type_for([b4_prhs
])[
820 yy::]b4_parser_class_name
[::prhs_
[] =
825 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
826 const ]b4_int_type_for([b4_rline
])[
827 yy::]b4_parser_class_name
[::rline_
[] =
833 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
834 yy::]b4_parser_class_name
[::TokenNumberType
835 yy::]b4_parser_class_name
[::translate_ (int token
)
838 const TokenNumberType
843 if ((unsigned) token
<= user_token_number_max_
)
844 return translate_table
[token
];
849 const int yy::]b4_parser_class_name
[::eof_
= 0;
850 const int yy::]b4_parser_class_name
[::last_
= ]b4_last
[;
851 const int yy::]b4_parser_class_name
[::nnts_
= ]b4_nterms_number
[;
852 const int yy::]b4_parser_class_name
[::empty_
= -2;
853 const int yy::]b4_parser_class_name
[::final_
= ]b4_final_state_number
[;
854 const int yy::]b4_parser_class_name
[::terror_
= 1;
855 const int yy::]b4_parser_class_name
[::errcode_
= 256;
856 const int yy::]b4_parser_class_name
[::ntokens_
= ]b4_tokens_number
[;
858 const unsigned yy::]b4_parser_class_name
[::user_token_number_max_
= ]b4_user_token_number_max
[;
859 const yy::]b4_parser_class_name
[::TokenNumberType
yy::]b4_parser_class_name
[::undef_token_
= ]b4_undef_token_number
[;
864 b4_copyright([Stack handling
for Bison C
++ parsers
], [2002, 2003])[
866 #ifndef BISON_STACK_HH
867 # define BISON_STACK_HH
873 template < class T
, class S
= std::deque
< T
> >
878 typedef typename
S::iterator Iterator
;
879 typedef typename
S::const_iterator ConstIterator
;
885 Stack (unsigned n
) : seq_ (n
)
891 operator [] (unsigned i
)
898 operator [] (unsigned i
) const
925 inline ConstIterator
begin () const { return seq_
.begin (); }
926 inline ConstIterator
end () const { return seq_
.end (); }
933 template < class T
, class S
= Stack
< T
> >
938 Slice (const S
& stack
,
939 unsigned range
) : stack_ (stack
),
946 operator [] (unsigned i
) const
948 return stack_
[range_
- i
];
958 #endif // not BISON_STACK_HH]
961 b4_copyright([Position
class for Bison C
++ parsers
], [2002, 2003])[
965 ** Define the Location class.
968 #ifndef BISON_POSITION_HH
969 # define BISON_POSITION_HH
976 /** \brief Abstract a Position. */
980 /** \brief Initial column number. */
981 static const unsigned int initial_column
= 0;
982 /** \brief Initial line number. */
983 static const unsigned int initial_line
= 1;
985 /** \name Ctor & dtor.
988 /** \brief Construct a Position. */
992 column (initial_column
)
998 /** \name Line and Column related manipulators
1001 /** \brief (line related) Advance to the COUNT next lines. */
1002 inline void lines (int count
= 1)
1004 column
= initial_column
;
1008 /** \brief (column related) Advance to the COUNT next columns. */
1009 inline void columns (int count
= 1)
1011 int leftmost
= initial_column
;
1012 int current
= column
;
1013 if (leftmost
<= current
+ count
)
1016 column
= initial_column
;
1021 /** \brief File name to which this position refers. */
1022 std::string filename
;
1023 /** \brief Current line number. */
1025 /** \brief Current column number. */
1026 unsigned int column
;
1029 /** \brief Add and assign a Position. */
1030 inline const Position
&
1031 operator+= (Position
& res
, const int width
)
1033 res
.columns (width
);
1037 /** \brief Add two Position objects. */
1038 inline const Position
1039 operator+ (const Position
& begin
, const int width
)
1041 Position res
= begin
;
1042 return res
+= width
;
1045 /** \brief Add and assign a Position. */
1046 inline const Position
&
1047 operator-= (Position
& res
, const int width
)
1049 return res
+= -width
;
1052 /** \brief Add two Position objects. */
1053 inline const Position
1054 operator- (const Position
& begin
, const int width
)
1056 return begin
+ -width
;
1059 /** \brief Intercept output stream redirection.
1060 ** \param ostr the destination output stream
1061 ** \param pos a reference to the Position to redirect
1063 inline std::ostream
&
1064 operator<< (std::ostream
& ostr
, const Position
& pos
)
1066 if (!pos
.filename
.empty ())
1067 ostr
<< pos
.filename
<< ':';
1068 return ostr
<< pos
.line
<< '.' << pos
.column
;
1072 #endif // not BISON_POSITION_HH]
1074 b4_copyright([Location
class for Bison C
++ parsers
], [2002, 2003])[
1077 ** \file location.hh
1078 ** Define the Location class.
1081 #ifndef BISON_LOCATION_HH
1082 # define BISON_LOCATION_HH
1084 # include <iostream>
1086 # include "position.hh"
1091 /** \brief Abstract a Location. */
1094 /** \name Ctor & dtor.
1097 /** \brief Construct a Location. */
1106 /** \name Line and Column related manipulators
1109 /** \brief Reset initial location to final location. */
1110 inline void step (void)
1115 /** \brief Extend the current location to the COUNT next columns. */
1116 inline void columns (unsigned int count
= 1)
1121 /** \brief Extend the current location to the COUNT next lines. */
1122 inline void lines (unsigned int count
= 1)
1130 /** \brief Beginning of the located region. */
1132 /** \brief End of the located region. */
1136 /** \brief Join two Location objects to create a Location. */
1137 inline const Location
operator+ (const Location
& begin
, const Location
& end
)
1139 Location res
= begin
;
1144 /** \brief Add two Location objects */
1145 inline const Location
operator+ (const Location
& begin
, unsigned width
)
1147 Location res
= begin
;
1148 res
.columns (width
);
1152 /** \brief Add and assign a Location */
1153 inline Location
&operator+= (Location
& res
, unsigned width
)
1155 res
.columns (width
);
1159 /** \brief Intercept output stream redirection.
1160 ** \param ostr the destination output stream
1161 ** \param loc a reference to the Location to redirect
1163 ** Avoid duplicate information.
1165 inline std::ostream
& operator<< (std::ostream
& ostr
, const Location
& loc
)
1167 Position last
= loc
.end
- 1;
1169 if (loc
.begin
.filename
!= last
.filename
)
1170 ostr
<< '-' << last
;
1171 else if (loc
.begin
.line
!= last
.line
)
1172 ostr
<< '-' << last
.line
<< '.' << last
.column
;
1173 else if (loc
.begin
.column
!= last
.column
)
1174 ostr
<< '-' << last
.column
;
1180 #endif // not BISON_LOCATION_HH]