location.cc 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. # C++ skeleton for Bison
  2. # Copyright (C) 2002-2013 Free Software Foundation, Inc.
  3. # This program is free software: you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation, either version 3 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. m4_pushdef([b4_copyright_years],
  16. [2002-2013])
  17. # b4_position_define
  18. # ------------------
  19. # Define class position.
  20. m4_define([b4_position_define],
  21. [[ /// Abstract a position.
  22. class position
  23. {
  24. public:]m4_ifdef([b4_location_constructors], [[
  25. /// Construct a position.
  26. explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
  27. unsigned int l = ]b4_location_initial_line[u,
  28. unsigned int c = ]b4_location_initial_column[u)
  29. : filename (f)
  30. , line (l)
  31. , column (c)
  32. {
  33. }
  34. ]])[
  35. /// Initialization.
  36. void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULL,
  37. unsigned int l = ]b4_location_initial_line[u,
  38. unsigned int c = ]b4_location_initial_column[u)
  39. {
  40. filename = fn;
  41. line = l;
  42. column = c;
  43. }
  44. /** \name Line and Column related manipulators
  45. ** \{ */
  46. /// (line related) Advance to the COUNT next lines.
  47. void lines (int count = 1)
  48. {
  49. if (count)
  50. {
  51. column = ]b4_location_initial_column[u;
  52. line = add_ (line, count, ]b4_location_initial_line[);
  53. }
  54. }
  55. /// (column related) Advance to the COUNT next columns.
  56. void columns (int count = 1)
  57. {
  58. column = add_ (column, count, ]b4_location_initial_column[);
  59. }
  60. /** \} */
  61. /// File name to which this position refers.
  62. ]b4_percent_define_get([[filename_type]])[* filename;
  63. /// Current line number.
  64. unsigned int line;
  65. /// Current column number.
  66. unsigned int column;
  67. private:
  68. /// Compute max(min, lhs+rhs) (provided min <= lhs).
  69. static unsigned int add_ (unsigned int lhs, int rhs, unsigned int min)
  70. {
  71. return (0 < rhs || -static_cast<unsigned int>(rhs) < lhs
  72. ? rhs + lhs
  73. : min);
  74. }
  75. };
  76. /// Add and assign a position.
  77. inline position&
  78. operator+= (position& res, int width)
  79. {
  80. res.columns (width);
  81. return res;
  82. }
  83. /// Add two position objects.
  84. inline position
  85. operator+ (position res, int width)
  86. {
  87. return res += width;
  88. }
  89. /// Add and assign a position.
  90. inline position&
  91. operator-= (position& res, int width)
  92. {
  93. return res += -width;
  94. }
  95. /// Add two position objects.
  96. inline position
  97. operator- (position res, int width)
  98. {
  99. return res -= width;
  100. }
  101. ]b4_percent_define_flag_if([[define_location_comparison]], [[
  102. /// Compare two position objects.
  103. inline bool
  104. operator== (const position& pos1, const position& pos2)
  105. {
  106. return (pos1.line == pos2.line
  107. && pos1.column == pos2.column
  108. && (pos1.filename == pos2.filename
  109. || (pos1.filename && pos2.filename
  110. && *pos1.filename == *pos2.filename)));
  111. }
  112. /// Compare two position objects.
  113. inline bool
  114. operator!= (const position& pos1, const position& pos2)
  115. {
  116. return !(pos1 == pos2);
  117. }
  118. ]])[
  119. /** \brief Intercept output stream redirection.
  120. ** \param ostr the destination output stream
  121. ** \param pos a reference to the position to redirect
  122. */
  123. template <typename YYChar>
  124. inline std::basic_ostream<YYChar>&
  125. operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
  126. {
  127. if (pos.filename)
  128. ostr << *pos.filename << ':';
  129. return ostr << pos.line << '.' << pos.column;
  130. }
  131. ]])
  132. # b4_location_define
  133. # ------------------
  134. m4_define([b4_location_define],
  135. [[ /// Abstract a location.
  136. class location
  137. {
  138. public:
  139. ]m4_ifdef([b4_location_constructors], [
  140. /// Construct a location from \a b to \a e.
  141. location (const position& b, const position& e)
  142. : begin (b)
  143. , end (e)
  144. {
  145. }
  146. /// Construct a 0-width location in \a p.
  147. explicit location (const position& p = position ())
  148. : begin (p)
  149. , end (p)
  150. {
  151. }
  152. /// Construct a 0-width location in \a f, \a l, \a c.
  153. explicit location (]b4_percent_define_get([[filename_type]])[* f,
  154. unsigned int l = ]b4_location_initial_line[u,
  155. unsigned int c = ]b4_location_initial_column[u)
  156. : begin (f, l, c)
  157. , end (f, l, c)
  158. {
  159. }
  160. ])[
  161. /// Initialization.
  162. void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
  163. unsigned int l = ]b4_location_initial_line[u,
  164. unsigned int c = ]b4_location_initial_column[u)
  165. {
  166. begin.initialize (f, l, c);
  167. end = begin;
  168. }
  169. /** \name Line and Column related manipulators
  170. ** \{ */
  171. public:
  172. /// Reset initial location to final location.
  173. void step ()
  174. {
  175. begin = end;
  176. }
  177. /// Extend the current location to the COUNT next columns.
  178. void columns (int count = 1)
  179. {
  180. end += count;
  181. }
  182. /// Extend the current location to the COUNT next lines.
  183. void lines (int count = 1)
  184. {
  185. end.lines (count);
  186. }
  187. /** \} */
  188. public:
  189. /// Beginning of the located region.
  190. position begin;
  191. /// End of the located region.
  192. position end;
  193. };
  194. /// Join two location objects to create a location.
  195. inline location operator+ (location res, const location& end)
  196. {
  197. res.end = end.end;
  198. return res;
  199. }
  200. /// Change end position in place.
  201. inline location& operator+= (location& res, int width)
  202. {
  203. res.columns (width);
  204. return res;
  205. }
  206. /// Change end position.
  207. inline location operator+ (location res, int width)
  208. {
  209. return res += width;
  210. }
  211. /// Change end position in place.
  212. inline location& operator-= (location& res, int width)
  213. {
  214. return res += -width;
  215. }
  216. /// Change end position.
  217. inline location operator- (const location& begin, int width)
  218. {
  219. return begin + -width;
  220. }
  221. ]b4_percent_define_flag_if([[define_location_comparison]], [[
  222. /// Compare two location objects.
  223. inline bool
  224. operator== (const location& loc1, const location& loc2)
  225. {
  226. return loc1.begin == loc2.begin && loc1.end == loc2.end;
  227. }
  228. /// Compare two location objects.
  229. inline bool
  230. operator!= (const location& loc1, const location& loc2)
  231. {
  232. return !(loc1 == loc2);
  233. }
  234. ]])[
  235. /** \brief Intercept output stream redirection.
  236. ** \param ostr the destination output stream
  237. ** \param loc a reference to the location to redirect
  238. **
  239. ** Avoid duplicate information.
  240. */
  241. template <typename YYChar>
  242. inline std::basic_ostream<YYChar>&
  243. operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
  244. {
  245. unsigned int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
  246. ostr << loc.begin// << "(" << loc.end << ") "
  247. ;
  248. if (loc.end.filename
  249. && (!loc.begin.filename
  250. || *loc.begin.filename != *loc.end.filename))
  251. ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
  252. else if (loc.begin.line < loc.end.line)
  253. ostr << '-' << loc.end.line << '.' << end_col;
  254. else if (loc.begin.column < end_col)
  255. ostr << '-' << end_col;
  256. return ostr;
  257. }
  258. ]])
  259. b4_defines_if([
  260. b4_output_begin([b4_dir_prefix[]position.hh])
  261. b4_copyright([Positions for Bison parsers in C++])[
  262. /**
  263. ** \file ]b4_dir_prefix[position.hh
  264. ** Define the ]b4_namespace_ref[::position class.
  265. */
  266. ]b4_cpp_guard_open([b4_dir_prefix[]position.hh])[
  267. # include <algorithm> // std::max
  268. # include <iostream>
  269. # include <string>
  270. ]b4_null_define[
  271. ]b4_namespace_open[
  272. ]b4_position_define[
  273. ]b4_namespace_close[
  274. ]b4_cpp_guard_close([b4_dir_prefix[]position.hh])
  275. b4_output_end()
  276. b4_output_begin([b4_dir_prefix[]location.hh])
  277. b4_copyright([Locations for Bison parsers in C++])[
  278. /**
  279. ** \file ]b4_dir_prefix[location.hh
  280. ** Define the ]b4_namespace_ref[::location class.
  281. */
  282. ]b4_cpp_guard_open([b4_dir_prefix[]location.hh])[
  283. # include "position.hh"
  284. ]b4_namespace_open[
  285. ]b4_location_define[
  286. ]b4_namespace_close[
  287. ]b4_cpp_guard_close([b4_dir_prefix[]location.hh])
  288. b4_output_end()
  289. ])
  290. m4_popdef([b4_copyright_years])