]> git.saurik.com Git - bison.git/blob - data/location.cc
53fddd4868b384a5bb0bbc47176a3c7c93e0dca6
[bison.git] / data / location.cc
1 # C++ skeleton for Bison
2
3 # Copyright (C) 2002-2015 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-2015])
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 \a width columns, in place.
87 inline position&
88 operator+= (position& res, int width)
89 {
90 res.columns (width);
91 return res;
92 }
93
94 /// Add \a width columns.
95 inline position
96 operator+ (position res, int width)
97 {
98 return res += width;
99 }
100
101 /// Subtract \a width columns, in place.
102 inline position&
103 operator-= (position& res, int width)
104 {
105 return res += -width;
106 }
107
108 /// Subtract \a width columns.
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 locations, in place.
220 inline location& operator+= (location& res, const location& end)
221 {
222 res.end = end.end;
223 return res;
224 }
225
226 /// Join two locations.
227 inline location operator+ (location res, const location& end)
228 {
229 return res += end;
230 }
231
232 /// Add \a width columns to the end position, in place.
233 inline location& operator+= (location& res, int width)
234 {
235 res.columns (width);
236 return res;
237 }
238
239 /// Add \a width columns to the end position.
240 inline location operator+ (location res, int width)
241 {
242 return res += width;
243 }
244
245 /// Subtract \a width columns to the end position, in place.
246 inline location& operator-= (location& res, int width)
247 {
248 return res += -width;
249 }
250
251 /// Subtract \a width columns to the end position.
252 inline location operator- (location res, int width)
253 {
254 return res -= width;
255 }
256 ]b4_percent_define_flag_if([[define_location_comparison]], [[
257 /// Compare two location objects.
258 inline bool
259 operator== (const location& loc1, const location& loc2)
260 {
261 return loc1.begin == loc2.begin && loc1.end == loc2.end;
262 }
263
264 /// Compare two location objects.
265 inline bool
266 operator!= (const location& loc1, const location& loc2)
267 {
268 return !(loc1 == loc2);
269 }
270 ]])[
271 /** \brief Intercept output stream redirection.
272 ** \param ostr the destination output stream
273 ** \param loc a reference to the location to redirect
274 **
275 ** Avoid duplicate information.
276 */
277 template <typename YYChar>
278 inline std::basic_ostream<YYChar>&
279 operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
280 {
281 unsigned int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
282 ostr << loc.begin;
283 if (loc.end.filename
284 && (!loc.begin.filename
285 || *loc.begin.filename != *loc.end.filename))
286 ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
287 else if (loc.begin.line < loc.end.line)
288 ostr << '-' << loc.end.line << '.' << end_col;
289 else if (loc.begin.column < end_col)
290 ostr << '-' << end_col;
291 return ostr;
292 }
293 ]])
294
295
296 b4_defines_if([
297 b4_output_begin([b4_dir_prefix[]position.hh])
298 b4_copyright([Positions for Bison parsers in C++])[
299
300 /**
301 ** \file ]b4_dir_prefix[position.hh
302 ** Define the ]b4_namespace_ref[::position class.
303 */
304
305 ]b4_cpp_guard_open([b4_dir_prefix[]position.hh])[
306
307 # include <algorithm> // std::max
308 # include <iostream>
309 # include <string>
310
311 ]b4_null_define[
312
313 ]b4_namespace_open[
314 ]b4_position_define[
315 ]b4_namespace_close[
316 ]b4_cpp_guard_close([b4_dir_prefix[]position.hh])
317 b4_output_end()
318
319
320 b4_output_begin([b4_dir_prefix[]location.hh])
321 b4_copyright([Locations for Bison parsers in C++])[
322
323 /**
324 ** \file ]b4_dir_prefix[location.hh
325 ** Define the ]b4_namespace_ref[::location class.
326 */
327
328 ]b4_cpp_guard_open([b4_dir_prefix[]location.hh])[
329
330 # include "position.hh"
331
332 ]b4_namespace_open[
333 ]b4_location_define[
334 ]b4_namespace_close[
335 ]b4_cpp_guard_close([b4_dir_prefix[]location.hh])
336 b4_output_end()
337 ])
338
339
340 m4_popdef([b4_copyright_years])