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