location.cc 10 KB

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