]> git.saurik.com Git - bison.git/blob - data/location.cc
version 3.0.1
[bison.git] / data / location.cc
1 # C++ skeleton for Bison
2
3 # Copyright (C) 2002-2013 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 3 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, see <http://www.gnu.org/licenses/>.
17
18 m4_pushdef([b4_copyright_years],
19 [2002-2013])
20
21 # b4_position_define
22 # ------------------
23 # Define class position.
24 m4_define([b4_position_define],
25 [[ /// Abstract a position.
26 class position
27 {
28 public:]m4_ifdef([b4_location_constructors], [[
29 /// Construct a position.
30 explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
31 unsigned int l = ]b4_location_initial_line[u,
32 unsigned int c = ]b4_location_initial_column[u)
33 : filename (f)
34 , line (l)
35 , column (c)
36 {
37 }
38
39 ]])[
40 /// Initialization.
41 void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULLPTR,
42 unsigned int l = ]b4_location_initial_line[u,
43 unsigned int c = ]b4_location_initial_column[u)
44 {
45 filename = fn;
46 line = l;
47 column = c;
48 }
49
50 /** \name Line and Column related manipulators
51 ** \{ */
52 /// (line related) Advance to the COUNT next lines.
53 void lines (int count = 1)
54 {
55 if (count)
56 {
57 column = ]b4_location_initial_column[u;
58 line = add_ (line, count, ]b4_location_initial_line[);
59 }
60 }
61
62 /// (column related) Advance to the COUNT next columns.
63 void columns (int count = 1)
64 {
65 column = add_ (column, count, ]b4_location_initial_column[);
66 }
67 /** \} */
68
69 /// File name to which this position refers.
70 ]b4_percent_define_get([[filename_type]])[* filename;
71 /// Current line number.
72 unsigned int line;
73 /// Current column number.
74 unsigned int column;
75
76 private:
77 /// Compute max(min, lhs+rhs) (provided min <= lhs).
78 static unsigned int add_ (unsigned int lhs, int rhs, unsigned int min)
79 {
80 return (0 < rhs || -static_cast<unsigned int>(rhs) < lhs
81 ? rhs + lhs
82 : min);
83 }
84 };
85
86 /// Add and assign a position.
87 inline position&
88 operator+= (position& res, int width)
89 {
90 res.columns (width);
91 return res;
92 }
93
94 /// Add two position objects.
95 inline position
96 operator+ (position res, int width)
97 {
98 return res += width;
99 }
100
101 /// Add and assign a position.
102 inline position&
103 operator-= (position& res, int width)
104 {
105 return res += -width;
106 }
107
108 /// Add two position objects.
109 inline position
110 operator- (position res, int width)
111 {
112 return res -= width;
113 }
114 ]b4_percent_define_flag_if([[define_location_comparison]], [[
115 /// Compare two position objects.
116 inline bool
117 operator== (const position& pos1, const position& pos2)
118 {
119 return (pos1.line == pos2.line
120 && pos1.column == pos2.column
121 && (pos1.filename == pos2.filename
122 || (pos1.filename && pos2.filename
123 && *pos1.filename == *pos2.filename)));
124 }
125
126 /// Compare two position objects.
127 inline bool
128 operator!= (const position& pos1, const position& pos2)
129 {
130 return !(pos1 == pos2);
131 }
132 ]])[
133 /** \brief Intercept output stream redirection.
134 ** \param ostr the destination output stream
135 ** \param pos a reference to the position to redirect
136 */
137 template <typename YYChar>
138 inline std::basic_ostream<YYChar>&
139 operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
140 {
141 if (pos.filename)
142 ostr << *pos.filename << ':';
143 return ostr << pos.line << '.' << pos.column;
144 }
145 ]])
146
147
148 # b4_location_define
149 # ------------------
150 m4_define([b4_location_define],
151 [[ /// Abstract a location.
152 class location
153 {
154 public:
155 ]m4_ifdef([b4_location_constructors], [
156 /// Construct a location from \a b to \a e.
157 location (const position& b, const position& e)
158 : begin (b)
159 , end (e)
160 {
161 }
162
163 /// Construct a 0-width location in \a p.
164 explicit location (const position& p = position ())
165 : begin (p)
166 , end (p)
167 {
168 }
169
170 /// Construct a 0-width location in \a f, \a l, \a c.
171 explicit location (]b4_percent_define_get([[filename_type]])[* f,
172 unsigned int l = ]b4_location_initial_line[u,
173 unsigned int c = ]b4_location_initial_column[u)
174 : begin (f, l, c)
175 , end (f, l, c)
176 {
177 }
178
179 ])[
180 /// Initialization.
181 void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
182 unsigned int l = ]b4_location_initial_line[u,
183 unsigned int c = ]b4_location_initial_column[u)
184 {
185 begin.initialize (f, l, c);
186 end = begin;
187 }
188
189 /** \name Line and Column related manipulators
190 ** \{ */
191 public:
192 /// Reset initial location to final location.
193 void step ()
194 {
195 begin = end;
196 }
197
198 /// Extend the current location to the COUNT next columns.
199 void columns (int count = 1)
200 {
201 end += count;
202 }
203
204 /// Extend the current location to the COUNT next lines.
205 void lines (int count = 1)
206 {
207 end.lines (count);
208 }
209 /** \} */
210
211
212 public:
213 /// Beginning of the located region.
214 position begin;
215 /// End of the located region.
216 position end;
217 };
218
219 /// Join two location objects to create a location.
220 inline location operator+ (location res, const location& end)
221 {
222 res.end = end.end;
223 return res;
224 }
225
226 /// Change end position in place.
227 inline location& operator+= (location& res, int width)
228 {
229 res.columns (width);
230 return res;
231 }
232
233 /// Change end position.
234 inline location operator+ (location res, int width)
235 {
236 return res += width;
237 }
238
239 /// Change end position in place.
240 inline location& operator-= (location& res, int width)
241 {
242 return res += -width;
243 }
244
245 /// Change end position.
246 inline location operator- (const location& begin, int width)
247 {
248 return begin + -width;
249 }
250 ]b4_percent_define_flag_if([[define_location_comparison]], [[
251 /// Compare two location objects.
252 inline bool
253 operator== (const location& loc1, const location& loc2)
254 {
255 return loc1.begin == loc2.begin && loc1.end == loc2.end;
256 }
257
258 /// Compare two location objects.
259 inline bool
260 operator!= (const location& loc1, const location& loc2)
261 {
262 return !(loc1 == loc2);
263 }
264 ]])[
265 /** \brief Intercept output stream redirection.
266 ** \param ostr the destination output stream
267 ** \param loc a reference to the location to redirect
268 **
269 ** Avoid duplicate information.
270 */
271 template <typename YYChar>
272 inline std::basic_ostream<YYChar>&
273 operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
274 {
275 unsigned int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
276 ostr << loc.begin// << "(" << loc.end << ") "
277 ;
278 if (loc.end.filename
279 && (!loc.begin.filename
280 || *loc.begin.filename != *loc.end.filename))
281 ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
282 else if (loc.begin.line < loc.end.line)
283 ostr << '-' << loc.end.line << '.' << end_col;
284 else if (loc.begin.column < end_col)
285 ostr << '-' << end_col;
286 return ostr;
287 }
288 ]])
289
290
291 b4_defines_if([
292 b4_output_begin([b4_dir_prefix[]position.hh])
293 b4_copyright([Positions for Bison parsers in C++])[
294
295 /**
296 ** \file ]b4_dir_prefix[position.hh
297 ** Define the ]b4_namespace_ref[::position class.
298 */
299
300 ]b4_cpp_guard_open([b4_dir_prefix[]position.hh])[
301
302 # include <algorithm> // std::max
303 # include <iostream>
304 # include <string>
305
306 ]b4_null_define[
307
308 ]b4_namespace_open[
309 ]b4_position_define[
310 ]b4_namespace_close[
311 ]b4_cpp_guard_close([b4_dir_prefix[]position.hh])
312 b4_output_end()
313
314
315 b4_output_begin([b4_dir_prefix[]location.hh])
316 b4_copyright([Locations for Bison parsers in C++])[
317
318 /**
319 ** \file ]b4_dir_prefix[location.hh
320 ** Define the ]b4_namespace_ref[::location class.
321 */
322
323 ]b4_cpp_guard_open([b4_dir_prefix[]location.hh])[
324
325 # include "position.hh"
326
327 ]b4_namespace_open[
328 ]b4_location_define[
329 ]b4_namespace_close[
330 ]b4_cpp_guard_close([b4_dir_prefix[]location.hh])
331 b4_output_end()
332 ])
333
334
335 m4_popdef([b4_copyright_years])