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