parser_fwd.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. // Copyright (C) 2020 T. Zachary Laine
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_PARSER_PARSER_FWD_HPP
  7. #define BOOST_PARSER_PARSER_FWD_HPP
  8. #include <boost/parser/config.hpp>
  9. #include <boost/parser/error_handling_fwd.hpp>
  10. #include <any>
  11. #include <cstdint>
  12. #include <functional>
  13. #include <map>
  14. #include <memory>
  15. #include <optional>
  16. #include <variant>
  17. namespace boost::parser::detail { namespace text {
  18. struct null_sentinel_t;
  19. }}
  20. namespace boost { namespace parser {
  21. /** A sentinel type that compares equal to a pointer to a character value
  22. type, iff the pointer is null. */
  23. using null_sentinel_t = boost::parser::detail::text::null_sentinel_t;
  24. /** A variable template that indicates that type `T` is an optional-like
  25. type. */
  26. template<typename T>
  27. constexpr bool enable_optional = false;
  28. /** A variable template that indicates that type `T` is an variant-like
  29. type. */
  30. template<typename T>
  31. constexpr bool enable_variant = false;
  32. #ifndef BOOST_PARSER_DOXYGEN
  33. template<typename T>
  34. constexpr bool enable_optional<std::optional<T>> = true;
  35. template<typename... Ts>
  36. constexpr bool enable_variant<std::variant<Ts...>> = true;
  37. #endif
  38. /** A type trait that evaluates to the attribute type for parser `Parser`
  39. used to parse range `R`, as if by calling `parse(r, parser)`, using
  40. some `R r` and `Parser parser`. Note that this implies that pointers
  41. to null-terminated strings are supported types for `R`. The result is
  42. not wrapped in a `std::optional` like the result of a call to
  43. `parse()` would be. If `Parser` produces no attribute, the result is
  44. the no-attribute sentinel type `none`. */
  45. template<typename R, typename Parser>
  46. struct attribute;
  47. /** An alias for `typename attribute<R, Parser>::type`. */
  48. template<typename R, typename Parser>
  49. using attribute_t = typename attribute<R, Parser>::type;
  50. /** Produces a `subrange` comprising the given pointer and
  51. `null_sentinel`. This should be used to make Null-Terminated Byte
  52. Strings ("NTBSs") compatible with ranges. */
  53. template<typename CharT>
  54. constexpr auto null_term(CharT * ptr)
  55. {
  56. return BOOST_PARSER_SUBRANGE(ptr, detail::text::null_sentinel);
  57. }
  58. namespace detail {
  59. template<typename T>
  60. constexpr bool is_optional_v = enable_optional<T>;
  61. struct nope;
  62. enum class flags : unsigned int {
  63. gen_attrs = 1 << 0,
  64. use_skip = 1 << 1,
  65. trace = 1 << 2,
  66. in_apply_parser = 1 << 3
  67. };
  68. struct symbol_table_trie_element
  69. {
  70. std::any trie_;
  71. bool has_case_folded_;
  72. };
  73. using symbol_table_tries_t =
  74. std::map<void *, symbol_table_trie_element, std::less<void *>>;
  75. using pending_symtab_ops_visitor = std::function<void()>;
  76. struct pending_symtab_ops_entry
  77. {
  78. pending_symtab_ops_visitor visit_;
  79. // Contains std::vector<detail::symbol_table_operation<T>> (T is
  80. // known to visit_).
  81. std::any ops_;
  82. };
  83. using pending_symbol_table_operations_t = std::map<
  84. void const *,
  85. pending_symtab_ops_entry,
  86. std::less<void const *>>;
  87. template<
  88. bool DoTrace,
  89. bool UseCallbacks,
  90. typename Iter,
  91. typename Sentinel,
  92. typename ErrorHandler>
  93. inline auto make_context(
  94. Iter first,
  95. Sentinel last,
  96. bool & success,
  97. int & indent,
  98. ErrorHandler const & error_handler,
  99. nope const &,
  100. symbol_table_tries_t & symbol_table_tries,
  101. pending_symbol_table_operations_t &
  102. pending_symbol_table_operations) noexcept;
  103. struct skip_skipper;
  104. struct char_subrange
  105. {
  106. char32_t lo_;
  107. char32_t hi_;
  108. };
  109. template<typename Tag>
  110. struct char_subranges
  111. {};
  112. struct hex_digit_subranges
  113. {};
  114. struct control_subranges
  115. {};
  116. template<typename Tag>
  117. struct char_set
  118. {};
  119. struct punct_chars
  120. {};
  121. struct symb_chars
  122. {};
  123. struct lower_case_chars
  124. {};
  125. struct upper_case_chars
  126. {};
  127. }
  128. /** Repeats the application of another parser `p` of type `Parser`,
  129. optionally applying another parser `d` of type `DelimiterParser` in
  130. between each pair of applications of `p`. The parse succeeds if `p`
  131. succeeds at least the minumum number of times, and `d` succeeds each
  132. time it is applied. The attribute produced is a sequence of the type
  133. of attribute produced by `Parser`. */
  134. template<
  135. typename Parser,
  136. typename DelimiterParser = detail::nope,
  137. typename MinType = int64_t,
  138. typename MaxType = int64_t>
  139. struct repeat_parser;
  140. /** Repeats the application of another parser `p` of type `Parser`, `[0,
  141. Inf)` times. The parse always succeeds. The attribute produced is a
  142. sequence of the type of attribute produced by `Parser`. */
  143. template<typename Parser>
  144. struct zero_plus_parser;
  145. /** Repeats the application of another parser `p` of type `Parser`, `[1,
  146. Inf)` times. The parse succeeds iff `p` succeeds at least once. The
  147. attribute produced is a sequence of the type of attribute produced by
  148. `Parser`. */
  149. template<typename Parser>
  150. struct one_plus_parser;
  151. /** Repeats the application of another parser `p` of type `Parser`, `[1,
  152. Inf)` times, applying a parser `d` of type `DelimiterParser` in
  153. between each pair of applications of `p`. The parse succeeds iff `p`
  154. succeeds at least once, and `d` succeeds each time it is applied. The
  155. attribute produced is a sequence of the type of attribute produced by
  156. `Parser`. */
  157. template<typename Parser, typename DelimiterParser>
  158. struct delimited_seq_parser;
  159. /** Repeats the application of another parser of type `Parser`, `[0, 1]`
  160. times. The parse always succeeds. The attribute produced is a
  161. `std::optional<T>`, where `T` is the type of attribute produced by
  162. `Parser`. */
  163. template<typename Parser>
  164. struct opt_parser;
  165. /** Applies each parser in `ParserTuple`, in order, stopping after the
  166. application of the first one that succeeds. The parse succeeds iff
  167. one of the sub-parsers succeeds. The attribute produced is a
  168. `std::variant` over the types of attribute produced by the parsers in
  169. `ParserTuple`. */
  170. template<typename ParserTuple>
  171. struct or_parser;
  172. /** Applies each parsers in `ParserTuple`, an any order, stopping after
  173. all of them have matched the input. The parse succeeds iff all the
  174. parsers match, regardless of the order in which they do. The
  175. attribute produced is a `parser::tuple` containing the attributes of
  176. the subparsers, in their order of the parsers' appearance in
  177. `ParserTuple`, not the order of the parsers' matches. It is an error
  178. to specialize `perm_parser` with a `ParserTuple` template parameter
  179. that includes an `eps_parser`. */
  180. template<typename ParserTuple, typename DelimiterParser>
  181. struct perm_parser;
  182. /** Applies each parser in `ParserTuple`, in order. The parse succeeds
  183. iff all of the sub-parsers succeed. The attribute produced is a
  184. `std::tuple` over the types of attribute produced by the parsers in
  185. `ParserTuple`. The BacktrackingTuple template parameter is a
  186. `parser::tuple` of `std::bool_constant` values. The `i`th such value
  187. indicates whether backtracking is allowed if the `i`th parser
  188. fails. */
  189. template<
  190. typename ParserTuple,
  191. typename BacktrackingTuple,
  192. typename CombiningGroups>
  193. struct seq_parser;
  194. /** Applies the given parser `p` of type `Parser` and an invocable `a` of
  195. type `Action`. `Action` shall model `semantic_action`, and `a` will
  196. only be invoked if `p` succeeds. The parse succeeds iff `p` succeeds.
  197. Produces no attribute. */
  198. template<typename Parser, typename Action>
  199. struct action_parser;
  200. /** Applies the given parser `p` of type `Parser`. The attribute produced
  201. by `p` is passed to the fiven invocable `f` of type `F`. `f` will
  202. only be invoked if `p` succeeds and sttributes are currently being
  203. generated. The parse succeeds iff `p` succeeds. The attribute
  204. produced is the the result of the call to `f`. */
  205. template<typename Parser, typename F>
  206. struct transform_parser;
  207. /** Applies the given parser `p` of type `Parser`. This parser produces
  208. no attribute, and suppresses the production of any attributes that
  209. would otherwise be produced by `p`. The parse succeeds iff `p`
  210. succeeds. */
  211. template<typename Parser>
  212. struct omit_parser;
  213. /** Applies the given parser `p` of type `Parser`; regardless of the
  214. attribute produced by `Parser`, this parser's attribute is equivalent
  215. to `_where(ctx)` within a semantic action on `p`. The parse succeeds
  216. iff `p` succeeds. */
  217. template<typename Parser>
  218. struct raw_parser;
  219. #if defined(BOOST_PARSER_DOXYGEN) || BOOST_PARSER_USE_CONCEPTS
  220. /** Applies the given parser `p` of type `Parser`. Regardless of the
  221. attribute produced by `Parser`, this parser's attribute is equivalent
  222. to `std::basic_string_view<char_type>` within a semantic action on
  223. `p`, where `char_type` is the type of character in the sequence being
  224. parsed. If the parsed range is transcoded, `char_type` will be the
  225. type being transcoded from. If the underlying range of `char_type` is
  226. non-contiguous, code using `string_view_parser` is ill-formed. The
  227. parse succeeds iff `p` succeeds. This parser is only available in
  228. C++20 and later. */
  229. template<typename Parser>
  230. struct string_view_parser;
  231. #endif
  232. /** Applies the given parser `p` of type `Parser`, disabling the current
  233. skipper in use, if any. The parse succeeds iff `p` succeeds. The
  234. attribute produced is the type of attribute produced by `Parser`. */
  235. template<typename Parser>
  236. struct lexeme_parser;
  237. /** Applies the given parser `p` of type `Parser`, enabling
  238. case-insensitive matching, based on Unicode case folding. The parse
  239. succeeds iff `p` succeeds. The attribute produced is the type of
  240. attribute produced by `Parser`. */
  241. template<typename Parser>
  242. struct no_case_parser;
  243. /** Applies the given parser `p` of type `Parser`, using a parser of type
  244. `SkipParser` as the skipper. The parse succeeds iff `p` succeeds.
  245. The attribute produced is the type of attribute produced by
  246. `Parser`. */
  247. template<typename Parser, typename SkipParser = detail::nope>
  248. struct skip_parser;
  249. /** Applies the given parser `p` of type `Parser`, producing no attributes
  250. and consuming no input. The parse succeeds iff `p`'s success is
  251. unequal to `FailOnMatch`. */
  252. template<typename Parser, bool FailOnMatch>
  253. struct expect_parser;
  254. /** Matches one of a set S of possible inputs, each of which is associated
  255. with an attribute value of type `T`, forming a symbol table. New
  256. elements and their associated attributes may be added to or removed
  257. from S dynamically, during parsing; any such changes are reverted at
  258. the end of parsing. The parse succeeds iff an element of S is
  259. matched. \see `symbols` */
  260. template<typename T>
  261. struct symbol_parser;
  262. /** Applies another parser `p`, associated with this parser via `TagType`.
  263. The attribute produced is `Attribute`. Both a default-constructed
  264. object of type `LocalState`, and a default-constructed object of type
  265. `ParamsTuple`, are added to the parse context before the associated
  266. parser is applied. The parse succeeds iff `p` succeeds. If
  267. `CanUseCallbacks` is `true`, and if this parser is used within a call
  268. to `callback_parse()`, the attribute is produced via callback;
  269. otherwise, the attribute is produced as normal (as a return value, or
  270. as an out-param). The rule may be constructed with user-friendly
  271. diagnostic text that will appear if the top-level parse is executed
  272. with `trace_mode == boost::parser::trace::on`. */
  273. template<
  274. bool CanUseCallbacks,
  275. typename TagType,
  276. typename Attribute,
  277. typename LocalState,
  278. typename ParamsTuple>
  279. struct rule_parser;
  280. /** Matches anything, and consumes no input. If `Predicate` is anything
  281. other than `detail::nope` (which it is by default), and `pred_(ctx)`
  282. evaluates to false, where `ctx` is the parser context, the parse
  283. fails. */
  284. template<typename Predicate>
  285. struct eps_parser;
  286. /** Matches only the end of input. Produces no attribute. */
  287. struct eoi_parser;
  288. /** Matches anything, consumes no input, and produces an attribute of type
  289. `RESOLVE(Attribute)`. */
  290. template<typename Attribute>
  291. struct attr_parser;
  292. /** A tag type that can be passed as the first parameter to `char_()` when
  293. the second parameter is a sorted, random access sequence that can be
  294. matched using a binary search.*/
  295. struct sorted_t
  296. {};
  297. inline constexpr sorted_t sorted;
  298. /** Matches a single code point. If `AttributeType` is not `void`,
  299. `AttributeType` is the attribute type produced; otherwise, the
  300. attribute type is the decayed type of the matched code point. The
  301. parse fails only if the parser is constructed with a specific set of
  302. expected code point values that does not include the matched code
  303. point. */
  304. template<typename Expected, typename AttributeType = void>
  305. struct char_parser;
  306. /** Matches a single code point that is equal to one of the code points
  307. associated with tag type `Tag`. This is used to create sets of
  308. characters for matching Unicode character classes like punctuation or
  309. lower case. Attribute type is the attribute type of the character
  310. being matched. */
  311. template<typename Tag>
  312. struct char_set_parser;
  313. /** Matches a single code point that falls into one of the subranges of
  314. code points associated with tag type `Tag`. This is used to create
  315. sets of characters for matching Unicode character classes like hex
  316. digits or control characters. Attribute type is the attribute type of
  317. the character being matched. */
  318. template<typename Tag>
  319. struct char_subrange_parser;
  320. /** Matches a single decimal digit code point, using the Unicode character
  321. class Hex_Digit. Attribute type is the attribute type of the
  322. character being matched. */
  323. struct digit_parser;
  324. /** Matches a particular string, delimited by an iterator sentinel pair;
  325. produces no attribute. */
  326. template<typename StrIter, typename StrSentinel>
  327. struct string_parser;
  328. /** Matches a string delimited by quotation marks; produces a
  329. `std::string` attribute. */
  330. template<
  331. typename Quotes = detail::nope,
  332. typename Escapes = detail::nope,
  333. typename CharParser = char_parser<detail::nope>>
  334. struct quoted_string_parser;
  335. /** Matches an end-of-line (`NewlinesOnly == true`), whitespace
  336. (`NewlinesOnly == false`), or (`NoNewlines == true`) blank (whitespace
  337. but not newline) code point, based on the Unicode definitions of each
  338. (also matches the two code points `"\r\n"`). Produces no
  339. attribute. */
  340. template<bool NewlinesOnly, bool NoNewlines>
  341. struct ws_parser;
  342. /** Matches the strings "true" and "false", producing an attribute of
  343. `true` or `false`, respectively, and fails on any other input. */
  344. struct bool_parser;
  345. /** Matches an unsigned number of radix `Radix`, of at least `MinDigits`
  346. and at most `MaxDigits`, producing an attribute of type `T`. Fails on
  347. any other input. The parse will also fail if `Expected` is anything
  348. but `detail::nope` (which it is by default), and the produced
  349. attribute is not equal to `expected_`. `Radix` must be one of `2`,
  350. `8`, `10`, or `16`. */
  351. template<
  352. typename T,
  353. int Radix = 10,
  354. int MinDigits = 1,
  355. int MaxDigits = -1,
  356. typename Expected = detail::nope>
  357. struct uint_parser;
  358. /** Matches a signed number of radix `Radix`, of at least `MinDigits` and
  359. at most `MaxDigits`, producing an attribute of type `T`. Fails on any
  360. other input. The parse will also fail if `Expected` is anything but
  361. `detail::nope` (which it is by default), and the produced
  362. attribute is not equal to `expected_`. `Radix` must be one of `2`,
  363. `8`, `10`, or `16`. */
  364. template<
  365. typename T,
  366. int Radix = 10,
  367. int MinDigits = 1,
  368. int MaxDigits = -1,
  369. typename Expected = detail::nope>
  370. struct int_parser;
  371. /** Matches a floating point number, producing an attribute of type
  372. `T`. */
  373. template<typename T>
  374. struct float_parser;
  375. /** Applies at most one of the parsers in `OrParser`. If `switch_value_`
  376. matches one or more of the values in the parsers in `OrParser`, the
  377. first such parser is applied, and the success or failure and attribute
  378. of the parse are those of the applied parser. Otherwise, the parse
  379. fails. */
  380. template<typename SwitchValue, typename OrParser = detail::nope>
  381. struct switch_parser;
  382. /** A wrapper for parsers that provides the operations that must be
  383. supported by all parsers (e.g. `operator>>()`). `GlobalState` is an
  384. optional state object that can be accessed within semantic actions via
  385. a call to `_globals()`. This global state object is ignored for all
  386. but the topmost parser; the topmost global state object is available
  387. in the semantic actions of all nested parsers. `ErrorHandler` is the
  388. type of the error handler to be used on parse failure. This handler
  389. is ignored on all but the topmost parser; the topmost parser's error
  390. handler is used for all errors encountered during parsing. */
  391. template<
  392. typename Parser,
  393. typename GlobalState = detail::nope,
  394. typename ErrorHandler = default_error_handler>
  395. struct parser_interface;
  396. using no_attribute = detail::nope;
  397. using no_local_state = detail::nope;
  398. using no_params = detail::nope;
  399. /** A type used to declare named parsing rules. The `TagType` template
  400. parameter is used to associate a particular `rule` with the
  401. `rule_parser` used during parsing. */
  402. template<
  403. typename TagType,
  404. typename Attribute = no_attribute,
  405. typename LocalState = no_local_state,
  406. typename ParamsTuple = no_params>
  407. struct rule;
  408. /** A type used to declare named parsing rules that support reporting of
  409. attributes via callback. The `TagType` template parameter is used to
  410. associate a particular `rule` with the `rule_parser` used during
  411. parsing. */
  412. template<
  413. typename TagType,
  414. typename Attribute = no_attribute,
  415. typename LocalState = no_local_state,
  416. typename ParamsTuple = no_params>
  417. struct callback_rule;
  418. #ifdef BOOST_PARSER_DOXYGEN
  419. /** Returns a reference to the attribute(s) (i.e. return value) of the
  420. bottommost parser; multiple attributes will be stored within a
  421. `parser::tuple`. You may write to this value in a semantic action to
  422. control what attribute value(s) the associated parser produces.
  423. Returns `none` if the bottommost parser does produce an attribute. */
  424. decltype(auto) _val(Context const & context);
  425. #endif
  426. /** Returns a reference to the attribute or attributes already produced by
  427. the bottommost parser; multiple attributes will be stored within a
  428. `parser::tuple`. Returns `none` if the bottommost parser does produce
  429. an attribute. */
  430. template<typename Context>
  431. decltype(auto) _attr(Context const & context);
  432. /** Returns a `subrange` that describes the matched range of the
  433. bottommost parser. */
  434. template<typename Context>
  435. decltype(auto) _where(Context const & context);
  436. /** Returns an iterator to the beginning of the entire sequence being
  437. parsed. The effect of calling this within a semantic action
  438. associated with a skip-parser is undefined */
  439. template<typename Context>
  440. decltype(auto) _begin(Context const & context);
  441. /** Returns an iterator to the end of the entire sequence being parsed. */
  442. template<typename Context>
  443. decltype(auto) _end(Context const & context);
  444. /** Returns a reference to a `bool` that represents the success or failure
  445. of the bottommost parser. You can assign `false` to this within a
  446. semantic action to force a parser to fail its parse. */
  447. template<typename Context>
  448. decltype(auto) _pass(Context const & context);
  449. /** Returns a reference to one or more local values that the bottommost
  450. rule is declared to have; multiple values will be stored within a
  451. `parser::tuple`. Returns `none` if there is no bottommost rule, or if
  452. that rule has no locals. */
  453. template<typename Context>
  454. decltype(auto) _locals(Context const & context);
  455. /** Returns a reference to one or more parameters passed to the bottommost
  456. rule `r`, by using `r` as `r.with(param0, param1, ... paramN)`;
  457. multiple values will be stored within a `parser::tuple`. Returns
  458. `none` if there is no bottommost rule, or if that rule was not given
  459. any parameters. */
  460. template<typename Context>
  461. decltype(auto) _params(Context const & context);
  462. /** Returns a reference to the globals object associated with the
  463. top-level parser. Returns `none` if there is no associated globals
  464. object. */
  465. template<typename Context>
  466. decltype(auto) _globals(Context const & context);
  467. /** Returns a reference to the error handler object associated with the
  468. top-level parser. Returns `none` if there is no associated error
  469. handler. */
  470. template<typename Context>
  471. decltype(auto) _error_handler(Context const & context);
  472. /** Report that the error described in `message` occurred at `location`,
  473. using the context's error handler. */
  474. #if BOOST_PARSER_USE_CONCEPTS
  475. template<std::forward_iterator I, typename Context>
  476. #else
  477. template<typename I, typename Context>
  478. #endif
  479. void _report_error(
  480. Context const & context, std::string_view message, I location);
  481. /** Report that the error described in `message` occurred at
  482. `_where(context).begin()`, using the context's error handler. */
  483. template<typename Context>
  484. void _report_error(Context const & context, std::string_view message);
  485. /** Report that the warning described in `message` occurred at `location`,
  486. using the context's error handler. */
  487. #if BOOST_PARSER_USE_CONCEPTS
  488. template<std::forward_iterator I, typename Context>
  489. #else
  490. template<typename I, typename Context>
  491. #endif
  492. void _report_warning(
  493. Context const & context, std::string_view message, I location);
  494. /** Report that the warning described in `message` occurred at
  495. `_where(context).begin()`, using the context's error handler. */
  496. template<typename Context>
  497. void _report_warning(Context const & context, std::string_view message);
  498. }}
  499. #endif