0031970: Data Exchange, STEP reader - parser syntax error messages are inaccessible
[occt.git] / src / StepFile / location.hh
1 // A Bison parser, made by GNU Bison 3.7.1.
2
3 // Locations for Bison parsers in C++
4
5 // Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
6
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
11
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License
18 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 // As a special exception, you may create a larger work that contains
21 // part or all of the Bison parser skeleton and distribute that work
22 // under terms of your choice, so long as that work isn't itself a
23 // parser generator using the skeleton or a modified version thereof
24 // as a parser skeleton.  Alternatively, if you modify or redistribute
25 // the parser skeleton itself, you may (at your option) remove this
26 // special exception, which will cause the skeleton and the resulting
27 // Bison output files to be licensed under the GNU General Public
28 // License without this special exception.
29
30 // This special exception was added by the Free Software Foundation in
31 // version 2.2 of Bison.
32
33 /**
34  ** \file StepFile/location.hh
35  ** Define the step::location class.
36  */
37
38 #ifndef YY_STEP_STEPFILE_LOCATION_HH_INCLUDED
39 # define YY_STEP_STEPFILE_LOCATION_HH_INCLUDED
40
41 # include <iostream>
42 # include <string>
43
44 # ifndef YY_NULLPTR
45 #  if defined __cplusplus
46 #   if 201103L <= __cplusplus
47 #    define YY_NULLPTR nullptr
48 #   else
49 #    define YY_NULLPTR 0
50 #   endif
51 #  else
52 #   define YY_NULLPTR ((void*)0)
53 #  endif
54 # endif
55
56 namespace step {
57
58   /// A point in a source file.
59   class position
60   {
61   public:
62     /// Type for file name.
63     typedef const std::string filename_type;
64     /// Type for line and column numbers.
65     typedef int counter_type;
66
67     /// Construct a position.
68     explicit position (filename_type* f = YY_NULLPTR,
69                        counter_type l = 1,
70                        counter_type c = 1)
71       : filename (f)
72       , line (l)
73       , column (c)
74     {}
75
76
77     /// Initialization.
78     void initialize (filename_type* fn = YY_NULLPTR,
79                      counter_type l = 1,
80                      counter_type c = 1)
81     {
82       filename = fn;
83       line = l;
84       column = c;
85     }
86
87     /** \name Line and Column related manipulators
88      ** \{ */
89     /// (line related) Advance to the COUNT next lines.
90     void lines (counter_type count = 1)
91     {
92       if (count)
93         {
94           column = 1;
95           line = add_ (line, count, 1);
96         }
97     }
98
99     /// (column related) Advance to the COUNT next columns.
100     void columns (counter_type count = 1)
101     {
102       column = add_ (column, count, 1);
103     }
104     /** \} */
105
106     /// File name to which this position refers.
107     filename_type* filename;
108     /// Current line number.
109     counter_type line;
110     /// Current column number.
111     counter_type column;
112
113   private:
114     /// Compute max (min, lhs+rhs).
115     static counter_type add_ (counter_type lhs, counter_type rhs, counter_type min)
116     {
117       return lhs + rhs < min ? min : lhs + rhs;
118     }
119   };
120
121   /// Add \a width columns, in place.
122   inline position&
123   operator+= (position& res, position::counter_type width)
124   {
125     res.columns (width);
126     return res;
127   }
128
129   /// Add \a width columns.
130   inline position
131   operator+ (position res, position::counter_type width)
132   {
133     return res += width;
134   }
135
136   /// Subtract \a width columns, in place.
137   inline position&
138   operator-= (position& res, position::counter_type width)
139   {
140     return res += -width;
141   }
142
143   /// Subtract \a width columns.
144   inline position
145   operator- (position res, position::counter_type width)
146   {
147     return res -= width;
148   }
149
150   /** \brief Intercept output stream redirection.
151    ** \param ostr the destination output stream
152    ** \param pos a reference to the position to redirect
153    */
154   template <typename YYChar>
155   std::basic_ostream<YYChar>&
156   operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
157   {
158     if (pos.filename)
159       ostr << *pos.filename << ':';
160     return ostr << pos.line << '.' << pos.column;
161   }
162
163   /// Two points in a source file.
164   class location
165   {
166   public:
167     /// Type for file name.
168     typedef position::filename_type filename_type;
169     /// Type for line and column numbers.
170     typedef position::counter_type counter_type;
171
172     /// Construct a location from \a b to \a e.
173     location (const position& b, const position& e)
174       : begin (b)
175       , end (e)
176     {}
177
178     /// Construct a 0-width location in \a p.
179     explicit location (const position& p = position ())
180       : begin (p)
181       , end (p)
182     {}
183
184     /// Construct a 0-width location in \a f, \a l, \a c.
185     explicit location (filename_type* f,
186                        counter_type l = 1,
187                        counter_type c = 1)
188       : begin (f, l, c)
189       , end (f, l, c)
190     {}
191
192
193     /// Initialization.
194     void initialize (filename_type* f = YY_NULLPTR,
195                      counter_type l = 1,
196                      counter_type c = 1)
197     {
198       begin.initialize (f, l, c);
199       end = begin;
200     }
201
202     /** \name Line and Column related manipulators
203      ** \{ */
204   public:
205     /// Reset initial location to final location.
206     void step ()
207     {
208       begin = end;
209     }
210
211     /// Extend the current location to the COUNT next columns.
212     void columns (counter_type count = 1)
213     {
214       end += count;
215     }
216
217     /// Extend the current location to the COUNT next lines.
218     void lines (counter_type count = 1)
219     {
220       end.lines (count);
221     }
222     /** \} */
223
224
225   public:
226     /// Beginning of the located region.
227     position begin;
228     /// End of the located region.
229     position end;
230   };
231
232   /// Join two locations, in place.
233   inline location&
234   operator+= (location& res, const location& end)
235   {
236     res.end = end.end;
237     return res;
238   }
239
240   /// Join two locations.
241   inline location
242   operator+ (location res, const location& end)
243   {
244     return res += end;
245   }
246
247   /// Add \a width columns to the end position, in place.
248   inline location&
249   operator+= (location& res, location::counter_type width)
250   {
251     res.columns (width);
252     return res;
253   }
254
255   /// Add \a width columns to the end position.
256   inline location
257   operator+ (location res, location::counter_type width)
258   {
259     return res += width;
260   }
261
262   /// Subtract \a width columns to the end position, in place.
263   inline location&
264   operator-= (location& res, location::counter_type width)
265   {
266     return res += -width;
267   }
268
269   /// Subtract \a width columns to the end position.
270   inline location
271   operator- (location res, location::counter_type width)
272   {
273     return res -= width;
274   }
275
276   /** \brief Intercept output stream redirection.
277    ** \param ostr the destination output stream
278    ** \param loc a reference to the location to redirect
279    **
280    ** Avoid duplicate information.
281    */
282   template <typename YYChar>
283   std::basic_ostream<YYChar>&
284   operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
285   {
286     location::counter_type end_col
287       = 0 < loc.end.column ? loc.end.column - 1 : 0;
288     ostr << loc.begin;
289     if (loc.end.filename
290         && (!loc.begin.filename
291             || *loc.begin.filename != *loc.end.filename))
292       ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
293     else if (loc.begin.line < loc.end.line)
294       ostr << '-' << loc.end.line << '.' << end_col;
295     else if (loc.begin.column < end_col)
296       ostr << '-' << end_col;
297     return ostr;
298   }
299
300 } // step
301
302 #endif // !YY_STEP_STEPFILE_LOCATION_HH_INCLUDED