// A Bison parser, made by GNU Bison 3.5.1. // Locations for Bison parsers in C++ // Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc. // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // As a special exception, you may create a larger work that contains // part or all of the Bison parser skeleton and distribute that work // under terms of your choice, so long as that work isn't itself a // parser generator using the skeleton or a modified version thereof // as a parser skeleton. Alternatively, if you modify or redistribute // the parser skeleton itself, you may (at your option) remove this // special exception, which will cause the skeleton and the resulting // Bison output files to be licensed under the GNU General Public // License without this special exception. // This special exception was added by the Free Software Foundation in // version 2.2 of Bison. #ifndef PCC_PARSER_LOCATION_H #define PCC_PARSER_LOCATION_H #include #include #ifndef YY_NULLPTR #if defined __cplusplus #if 201103L <= __cplusplus #define YY_NULLPTR nullptr #else #define YY_NULLPTR 0 #endif #else #define YY_NULLPTR ((void*) 0) #endif #endif namespace pcc { /// A point in a source file. class Position { public: /// Type for line and column numbers. typedef int counter_type; /// Construct a position. explicit Position(std::string* f = YY_NULLPTR, counter_type l = 1, counter_type c = 1) : filename(f) , line(l) , column(c) {} /// Initialization. void initialize(std::string* fn = YY_NULLPTR, counter_type l = 1, counter_type c = 1) { filename = fn; line = l; column = c; } /** \name Line and Column related manipulators ** \{ */ /// (line related) Advance to the COUNT next lines. void lines(counter_type count = 1) { if (count) { column = 1; line = add_(line, count, 1); } } /// (column related) Advance to the COUNT next columns. void columns(counter_type count = 1) { column = add_(column, count, 1); } /** \} */ /// File name to which this position refers. std::string* filename; /// Current line number. counter_type line; /// Current column number. counter_type column; private: /// Compute max (min, lhs+rhs). static counter_type add_(counter_type lhs, counter_type rhs, counter_type min) { return lhs + rhs < min ? min : lhs + rhs; } }; /// Add \a width columns, in place. inline Position& operator+=(Position& res, Position::counter_type width) { res.columns(width); return res; } /// Add \a width columns. inline Position operator+(Position res, Position::counter_type width) { return res += width; } /// Subtract \a width columns, in place. inline Position& operator-=(Position& res, Position::counter_type width) { return res += -width; } /// Subtract \a width columns. inline Position operator-(Position res, Position::counter_type width) { return res -= width; } /// Compare two position objects. inline bool operator==(const Position& pos1, const Position& pos2) { return ( pos1.line == pos2.line && pos1.column == pos2.column && (pos1.filename == pos2.filename || (pos1.filename && pos2.filename && *pos1.filename == *pos2.filename))); } /// Compare two position objects. inline bool operator!=(const Position& pos1, const Position& pos2) { return !(pos1 == pos2); } /** \brief Intercept output stream redirection. ** \param ostr the destination output stream ** \param pos a reference to the position to redirect */ template std::basic_ostream& operator<<(std::basic_ostream& ostr, const Position& pos) { if (pos.filename) ostr << *pos.filename << ':'; return ostr << pos.line << '.' << pos.column; }; /// Two points in a source file. class Location { public: /// Type for line and column numbers. typedef Position::counter_type counter_type; /// Construct a location from \a b to \a e. Location(const Position& b, const Position& e) : begin(b) , end(e) {} /// Construct a 0-width location in \a p. explicit Location(const Position& p = Position()) : begin(p) , end(p) {} /// Construct a 0-width location in \a f, \a l, \a c. explicit Location(std::string* f, counter_type l = 1, counter_type c = 1) : begin(f, l, c) , end(f, l, c) {} /// Initialization. void initialize(std::string* f = YY_NULLPTR, counter_type l = 1, counter_type c = 1) { begin.initialize(f, l, c); end = begin; } /** \name Line and Column related manipulators ** \{ */ public: /// Reset initial location to final location. void step() { begin = end; } /// Extend the current location to the COUNT next columns. void columns(counter_type count = 1) { end += count; } /// Extend the current location to the COUNT next lines. void lines(counter_type count = 1) { end.lines(count); } /** \} */ public: /// Beginning of the located region. Position begin; /// End of the located region. Position end; }; /// Join two locations, in place. inline Location& operator+=(Location& res, const Location& end) { res.end = end.end; return res; } /// Join two locations. inline Location operator+(Location res, const Location& end) { return res += end; } /// Add \a width columns to the end position, in place. inline Location& operator+=(Location& res, Location::counter_type width) { res.columns(width); return res; } /// Add \a width columns to the end position. inline Location operator+(Location res, Location::counter_type width) { return res += width; } /// Subtract \a width columns to the end position, in place. inline Location& operator-=(Location& res, Location::counter_type width) { return res += -width; } /// Subtract \a width columns to the end position. inline Location operator-(Location res, Location::counter_type width) { return res -= width; } /// Compare two location objects. inline bool operator==(const Location& loc1, const Location& loc2) { return loc1.begin == loc2.begin && loc1.end == loc2.end; } /// Compare two location objects. inline bool operator!=(const Location& loc1, const Location& loc2) { return !(loc1 == loc2); } /** \brief Intercept output stream redirection. ** \param ostr the destination output stream ** \param loc a reference to the location to redirect ** ** Avoid duplicate information. */ template std::basic_ostream& operator<<(std::basic_ostream& ostr, const Location& loc) { Location::counter_type end_col = 0 < loc.end.column ? loc.end.column - 1 : 0; ostr << loc.begin; if (loc.end.filename && (!loc.begin.filename || *loc.begin.filename != *loc.end.filename)) ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col; else if (loc.begin.line < loc.end.line) ostr << '-' << loc.end.line << '.' << end_col; else if (loc.begin.column < end_col) ostr << '-' << end_col; return ostr; } } // namespace pcc #endif // !PCC_PARSER_LOCATION_H