1 #C++ skeleton for Bison 2 3 #Copyright(C) 2002 - 2015, 2018 - 2021 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 < https: // www.gnu.org/licenses/>. 17 18 m4_pushdef([b4_copyright_years], 19 [2002-2015, 2018-2021]) 20 21 #b4_location_file 22 #-- -- -- -- -- -- -- -- 23 #Name of the file containing the position / location class, 24 #if we want this file. 25 b4_percent_define_check_file([b4_location_file], 26 [[api.location.file]], 27 b4_header_if([[location.hh]])) 28 29 # b4_location_include 30 # -- -- -- -- -- -- -- -- -- - 31 # If location.hh is to be generated, the name under which should it be 32 # included. 33 # 34 # b4_location_path 35 # -- -- -- -- -- -- -- -- 36 # The path to use for the CPP guard. 37 m4_ifdef([b4_location_file], 38 [m4_define([b4_location_include], 39 [b4_percent_define_get([[api.location.include]], 40 ["b4_location_file"])]) 41 m4_define([b4_location_path], 42 b4_percent_define_get([[api.location.include]], 43 ["b4_mapped_dir_prefix[]b4_location_file"])) 44 m4_define([b4_location_path], 45 m4_substr(m4_defn([b4_location_path]), 1, m4_eval(m4_len(m4_defn([b4_location_path])) - 2))) 46 ]) 47 48 # b4_position_file 49 # -- -- -- -- -- -- -- -- 50 # Name of the file containing the position class, if we want this file. 51 b4_header_if( 52 [b4_required_version_if( 53 [30200], [], 54 [m4_ifdef([b4_location_file], 55 [m4_define([b4_position_file], [position.hh])])])]) 56 57 # b4_location_define 58 # -- -- -- -- -- -- -- -- -- 59 # Define the position and location classes. 60 m4_define([b4_location_define], 61 [[ /// A point in a source file. 62 class position 63 { 64 public: 65 /// Type for file name. 66 typedef ]b4_percent_define_get([[api.filename.type]])[ filename_type; 67 /// Type for line and column numbers. 68 typedef int counter_type; 69 ]m4_ifdef([b4_location_constructors], [[ 70 /// Construct a position. 71 explicit position (filename_type* f = YY_NULLPTR, 72 counter_type l = ]b4_location_initial_line[, 73 counter_type c = ]b4_location_initial_column[) 74 : filename (f) 75 , line (l) 76 , column (c) 77 {} 78 79 ]])[ 80 /// Initialization. 81 void initialize (filename_type* fn = YY_NULLPTR, 82 counter_type l = ]b4_location_initial_line[, 83 counter_type c = ]b4_location_initial_column[) 84 { 85 filename = fn; 86 line = l; 87 column = c; 88 } 89 90 /** \name Line and Column related manipulators 91 ** \{ */ 92 /// (line related) Advance to the COUNT next lines. 93 void lines (counter_type count = 1) 94 { 95 if (count) 96 { 97 column = ]b4_location_initial_column[; 98 line = add_ (line, count, ]b4_location_initial_line[); 99 } 100 } 101 102 /// (column related) Advance to the COUNT next columns. 103 void columns (counter_type count = 1) 104 { 105 column = add_ (column, count, ]b4_location_initial_column[); 106 } 107 /** \} */ 108 109 /// File name to which this position refers. 110 filename_type* filename; 111 /// Current line number. 112 counter_type line; 113 /// Current column number. 114 counter_type column; 115 116 private: 117 /// Compute max (min, lhs+rhs). 118 static counter_type add_ (counter_type lhs, counter_type rhs, counter_type min) 119 { 120 return lhs + rhs < min ? min : lhs + rhs; 121 } 122 }; 123 124 /// Add \a width columns, in place. 125 inline position& 126 operator+= (position& res, position::counter_type width) 127 { 128 res.columns(width); 129 return res; 130 } 131 132 /// Add \a width columns. 133 inline position 134 operator+ (position res, position::counter_type width) 135 { 136 return res += width; 137 } 138 139 /// Subtract \a width columns, in place. 140 inline position& 141 operator-= (position& res, position::counter_type width) 142 { 143 return res += -width; 144 } 145 146 /// Subtract \a width columns. 147 inline position 148 operator- (position res, position::counter_type width) 149 { 150 return res -= width; 151 } 152 ]b4_percent_define_flag_if([[define_location_comparison]], [[ 153 /// Compare two position objects. 154 inline bool 155 operator== (const position& pos1, const position& pos2) 156 { 157 return (pos1.line == pos2.line && pos1.column == pos2.column && 158 (pos1.filename == pos2.filename || 159 (pos1.filename && pos2.filename && *pos1.filename == *pos2.filename))); 160 } 161 162 /// Compare two position objects. 163 inline bool 164 operator!= (const position& pos1, const position& pos2) 165 { 166 return !(pos1 == pos2); 167 } 168 ]])[ 169 /** \brief Intercept output stream redirection. 170 ** \param ostr the destination output stream 171 ** \param pos a reference to the position to redirect 172 */ 173 template <typename YYChar> 174 std::basic_ostream<YYChar>& 175 operator<< (std::basic_ostream<YYChar>& ostr, const position& pos) 176 { 177 if (pos.filename) 178 ostr << *pos.filename << ':'; 179 return ostr << pos.line << '.' << pos.column; 180 } 181 182 /// Two points in a source file. 183 class location 184 { 185 public: 186 /// Type for file name. 187 typedef position::filename_type filename_type; 188 /// Type for line and column numbers. 189 typedef position::counter_type counter_type; 190 ]m4_ifdef([b4_location_constructors], [ 191 /// Construct a location from \a b to \a e. 192 location (const position& b, const position& e) 193 : begin (b) 194 , end (e) 195 {} 196 197 /// Construct a 0-width location in \a p. 198 explicit location (const position& p = position ()) 199 : begin (p) 200 , end (p) 201 {} 202 203 /// Construct a 0-width location in \a f, \a l, \a c. 204 explicit location (filename_type* f, 205 counter_type l = ]b4_location_initial_line[, 206 counter_type c = ]b4_location_initial_column[) 207 : begin (f, l, c) 208 , end (f, l, c) 209 {} 210 211 ])[ 212 /// Initialization. 213 void initialize (filename_type* f = YY_NULLPTR, 214 counter_type l = ]b4_location_initial_line[, 215 counter_type c = ]b4_location_initial_column[) 216 { 217 begin.initialize(f, l, c); 218 end = begin; 219 } 220 221 /** \name Line and Column related manipulators 222 ** \{ */ 223 public: 224 /// Reset initial location to final location. 225 void step () 226 { 227 begin = end; 228 } 229 230 /// Extend the current location to the COUNT next columns. 231 void columns (counter_type count = 1) 232 { 233 end += count; 234 } 235 236 /// Extend the current location to the COUNT next lines. 237 void lines (counter_type count = 1) 238 { 239 end.lines(count); 240 } 241 /** \} */ 242 243 244 public: 245 /// Beginning of the located region. 246 position begin; 247 /// End of the located region. 248 position end; 249 }; 250 251 /// Join two locations, in place. 252 inline location& 253 operator+= (location& res, const location& end) 254 { 255 res.end = end.end; 256 return res; 257 } 258 259 /// Join two locations. 260 inline location 261 operator+ (location res, const location& end) 262 { 263 return res += end; 264 } 265 266 /// Add \a width columns to the end position, in place. 267 inline location& 268 operator+= (location& res, location::counter_type width) 269 { 270 res.columns(width); 271 return res; 272 } 273 274 /// Add \a width columns to the end position. 275 inline location 276 operator+ (location res, location::counter_type width) 277 { 278 return res += width; 279 } 280 281 /// Subtract \a width columns to the end position, in place. 282 inline location& 283 operator-= (location& res, location::counter_type width) 284 { 285 return res += -width; 286 } 287 288 /// Subtract \a width columns to the end position. 289 inline location 290 operator- (location res, location::counter_type width) 291 { 292 return res -= width; 293 } 294 ]b4_percent_define_flag_if([[define_location_comparison]], [[ 295 /// Compare two location objects. 296 inline bool 297 operator== (const location& loc1, const location& loc2) 298 { 299 return loc1.begin == loc2.begin && loc1.end == loc2.end; 300 } 301 302 /// Compare two location objects. 303 inline bool 304 operator!= (const location& loc1, const location& loc2) 305 { 306 return !(loc1 == loc2); 307 } 308 ]])[ 309 /** \brief Intercept output stream redirection. 310 ** \param ostr the destination output stream 311 ** \param loc a reference to the location to redirect 312 ** 313 ** Avoid duplicate information. 314 */ 315 template <typename YYChar> 316 std::basic_ostream<YYChar>& 317 operator<< (std::basic_ostream<YYChar>& ostr, const location& loc) 318 { 319 location::counter_type end_col = 0 < loc.end.column ? loc.end.column - 1 : 0; 320 ostr << loc.begin; 321 if (loc.end.filename && (!loc.begin.filename || *loc.begin.filename != *loc.end.filename)) 322 ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col; 323 else if (loc.begin.line < loc.end.line) 324 ostr << '-' << loc.end.line << '.' << end_col; 325 else if (loc.begin.column < end_col) 326 ostr << '-' << end_col; 327 return ostr; 328 } 329 ]]) 330 331 332 m4_ifdef([b4_position_file], [[ 333 ]b4_output_begin([b4_dir_prefix], [b4_position_file])[ 334 ]b4_generated_by[ 335 // Starting with Bison 3.2, this file is useless: the structure it 336 // used to define is now defined in "]b4_location_file[". 337 // 338 // To get rid of this file: 339 // 1. add '%require "3.2"' (or newer) to your grammar file 340 // 2. remove references to this file from your build system 341 // 3. if you used to include it, include "]b4_location_file[" instead. 342 343 # include] b4_location_include[ 344 ]b4_output_end[ 345 ]]) 346 347 348 m4_ifdef([b4_location_file], [[ 349 ]b4_output_begin([b4_dir_prefix], [b4_location_file])[ 350 ]b4_copyright([Locations for Bison parsers in C++])[ 351 /** 352 ** \file ]b4_location_path[ 353 ** Define the ]b4_namespace_ref[::location class. 354 */ 355 356 ]b4_cpp_guard_open([b4_location_path])[ 357 358 # include <iostream> 359 # include <string> 360 361 ]b4_null_define[ 362 363 ]b4_namespace_open[ 364 ]b4_location_define[ 365 ]b4_namespace_close[ 366 ]b4_cpp_guard_close([b4_location_path])[ 367 ]b4_output_end[ 368 ]]) 369 370 371 m4_popdef([b4_copyright_years]) 372