printing_impl.hpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971
  1. #ifndef BOOST_PARSER_DETAIL_PRINTING_IMPL_HPP
  2. #define BOOST_PARSER_DETAIL_PRINTING_IMPL_HPP
  3. #include <boost/parser/detail/printing.hpp>
  4. #if __has_include(<boost/type_index.hpp>)
  5. #if defined(__GNUC__) || defined(__clang__)
  6. #pragma GCC diagnostic push
  7. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  8. #endif
  9. #include <boost/type_index.hpp>
  10. #define BOOST_PARSER_HAVE_BOOST_TYPEINDEX 1
  11. #define BOOST_PARSER_TYPE_NAME_NS boost_type_index
  12. #if defined(__GNUC__) || defined(__clang__)
  13. #pragma GCC diagnostic pop
  14. #endif
  15. #else
  16. #include <typeinfo>
  17. #define BOOST_PARSER_HAVE_BOOST_TYPEINDEX 0
  18. #define BOOST_PARSER_TYPE_NAME_NS std_typeinfo
  19. #endif
  20. namespace boost { namespace parser { namespace detail {
  21. inline namespace BOOST_PARSER_TYPE_NAME_NS {
  22. template<typename T>
  23. auto type_name()
  24. {
  25. #if BOOST_PARSER_HAVE_BOOST_TYPEINDEX
  26. return typeindex::type_id<T>().pretty_name();
  27. #else
  28. return typeid(T).name();
  29. #endif
  30. }
  31. }
  32. template<typename Parser>
  33. struct n_aray_parser : std::false_type
  34. {};
  35. template<
  36. typename Parser,
  37. typename DelimiterParser,
  38. typename MinType,
  39. typename MaxType>
  40. struct n_aray_parser<
  41. repeat_parser<Parser, DelimiterParser, MinType, MaxType>>
  42. : std::true_type
  43. {};
  44. template<typename Parser, typename MinType, typename MaxType>
  45. struct n_aray_parser<repeat_parser<Parser, detail::nope, MinType, MaxType>>
  46. : std::false_type
  47. {};
  48. template<typename Parser, typename DelimiterParser>
  49. struct n_aray_parser<delimited_seq_parser<Parser, DelimiterParser>>
  50. : std::true_type
  51. {};
  52. template<typename ParserTuple>
  53. struct n_aray_parser<or_parser<ParserTuple>> : std::true_type
  54. {};
  55. template<typename ParserTuple, typename DelimiterParser>
  56. struct n_aray_parser<perm_parser<ParserTuple, DelimiterParser>>
  57. : std::true_type
  58. {};
  59. template<
  60. typename ParserTuple,
  61. typename BacktrackingTuple,
  62. typename CombiningGroups>
  63. struct n_aray_parser<
  64. seq_parser<ParserTuple, BacktrackingTuple, CombiningGroups>>
  65. : std::true_type
  66. {};
  67. // true iff Parser is an n-ary parser (contains N>2 subparsers).
  68. template<typename Parser>
  69. constexpr bool n_aray_parser_v = n_aray_parser<Parser>::value;
  70. template<typename Context, typename Expected>
  71. void print_expected(
  72. Context const & context,
  73. std::ostream & os,
  74. Expected expected,
  75. bool no_parens = false)
  76. {
  77. if (is_nope_v<Expected>)
  78. return;
  79. if (!no_parens)
  80. os << "(";
  81. detail::print(os, detail::resolve(context, expected));
  82. if (!no_parens)
  83. os << ")";
  84. }
  85. template<
  86. typename Context,
  87. typename Parser,
  88. typename DelimiterParser,
  89. typename MinType,
  90. typename MaxType>
  91. void print_parser(
  92. Context const & context,
  93. repeat_parser<Parser, DelimiterParser, MinType, MaxType> const & parser,
  94. std::ostream & os,
  95. int components)
  96. {
  97. if constexpr (is_nope_v<DelimiterParser>) {
  98. auto const min_ = detail::resolve(context, parser.min_);
  99. auto const max_ = detail::resolve(context, parser.max_);
  100. constexpr bool n_ary_child = n_aray_parser_v<Parser>;
  101. if (min_ == 0 && max_ == Inf) {
  102. os << "*";
  103. if (n_ary_child)
  104. os << "(";
  105. detail::print_parser(
  106. context, parser.parser_, os, components + 1);
  107. if (n_ary_child)
  108. os << ")";
  109. } else if (min_ == 1 && max_ == Inf) {
  110. os << "+";
  111. if (n_ary_child)
  112. os << "(";
  113. detail::print_parser(
  114. context, parser.parser_, os, components + 1);
  115. if (n_ary_child)
  116. os << ")";
  117. } else {
  118. os << "repeat(";
  119. detail::print(os, min_);
  120. if (min_ == max_) {
  121. os << ")[";
  122. } else {
  123. os << ", ";
  124. if (max_ == unbounded)
  125. os << "Inf";
  126. else
  127. detail::print(os, max_);
  128. os << ")[";
  129. }
  130. detail::print_parser(
  131. context, parser.parser_, os, components + 1);
  132. os << "]";
  133. }
  134. } else {
  135. detail::print_parser(context, parser.parser_, os, components + 1);
  136. os << " % ";
  137. detail::print_parser(
  138. context, parser.delimiter_parser_, os, components + 2);
  139. }
  140. }
  141. template<typename Context, typename Parser>
  142. void print_parser(
  143. Context const & context,
  144. opt_parser<Parser> const & parser,
  145. std::ostream & os,
  146. int components)
  147. {
  148. os << "-";
  149. constexpr bool n_ary_child = n_aray_parser_v<Parser>;
  150. if (n_ary_child)
  151. os << "(";
  152. detail::print_parser(context, parser.parser_, os, components + 1);
  153. if (n_ary_child)
  154. os << ")";
  155. }
  156. template<typename Context, typename Parser>
  157. void print_or_like_parser(
  158. Context const & context,
  159. Parser const & parser,
  160. std::ostream & os,
  161. int components,
  162. std::string_view or_ellipsis,
  163. std::string_view ws_or)
  164. {
  165. int i = 0;
  166. bool printed_ellipsis = false;
  167. hl::for_each(parser.parsers_, [&](auto const & parser) {
  168. if (components == parser_component_limit) {
  169. if (!printed_ellipsis)
  170. os << or_ellipsis;
  171. printed_ellipsis = true;
  172. return;
  173. }
  174. if (i)
  175. os << ws_or;
  176. detail::print_parser(context, parser, os, components);
  177. ++components;
  178. ++i;
  179. });
  180. }
  181. template<typename Context, typename ParserTuple>
  182. void print_parser(
  183. Context const & context,
  184. or_parser<ParserTuple> const & parser,
  185. std::ostream & os,
  186. int components)
  187. {
  188. detail::print_or_like_parser(
  189. context, parser, os, components, " | ...", " | ");
  190. }
  191. template<typename Context, typename ParserTuple, typename DelimiterParser>
  192. void print_parser(
  193. Context const & context,
  194. perm_parser<ParserTuple, DelimiterParser> const & parser,
  195. std::ostream & os,
  196. int components)
  197. {
  198. if constexpr (!is_nope_v<DelimiterParser>) {
  199. os << "delimiter(";
  200. detail::print_parser(
  201. context, parser.delimiter_parser_, os, components);
  202. os << ")[";
  203. }
  204. detail::print_or_like_parser(
  205. context, parser, os, components, " || ...", " || ");
  206. if constexpr (!is_nope_v<DelimiterParser>)
  207. os << "]";
  208. }
  209. template<
  210. typename Context,
  211. typename ParserTuple,
  212. typename BacktrackingTuple,
  213. typename CombiningGroups>
  214. void print_parser(
  215. Context const & context,
  216. seq_parser<ParserTuple, BacktrackingTuple, CombiningGroups> const &
  217. parser,
  218. std::ostream & os,
  219. int components)
  220. {
  221. int prev_group = 0;
  222. int i = 0;
  223. bool printed_ellipsis = false;
  224. using combining_groups =
  225. detail::combining_t<ParserTuple, CombiningGroups>;
  226. hl::for_each(
  227. hl::zip(parser.parsers_, BacktrackingTuple{}, combining_groups{}),
  228. [&](auto const & parser_and_backtrack) {
  229. using namespace literals;
  230. auto const & parser = parser::get(parser_and_backtrack, 0_c);
  231. auto const backtrack = parser::get(parser_and_backtrack, 1_c);
  232. auto const group = parser::get(parser_and_backtrack, 2_c);
  233. if (components == parser_component_limit) {
  234. if (!printed_ellipsis) {
  235. os << (backtrack ? " >> ..." : " > ...");
  236. }
  237. printed_ellipsis = true;
  238. return;
  239. }
  240. if (group != prev_group && prev_group)
  241. os << ']';
  242. if (i)
  243. os << (backtrack ? " >> " : " > ");
  244. if (group != prev_group && group)
  245. os << (group == -1 ? "separate[" : "merge[");
  246. detail::print_parser(context, parser, os, components);
  247. ++components;
  248. ++i;
  249. prev_group = (int)group;
  250. });
  251. if (prev_group && !printed_ellipsis)
  252. os << ']';
  253. }
  254. template<typename Context, typename Parser, typename Action>
  255. void print_parser(
  256. Context const & context,
  257. action_parser<Parser, Action> const & parser,
  258. std::ostream & os,
  259. int components)
  260. {
  261. detail::print_parser(context, parser.parser_, os, components);
  262. os << "[<<action>>]";
  263. }
  264. template<typename Context, typename Parser>
  265. void print_directive(
  266. Context const & context,
  267. std::string_view name,
  268. Parser const & parser,
  269. std::ostream & os,
  270. int components)
  271. {
  272. os << name << "[";
  273. if (++components == parser_component_limit)
  274. os << "...";
  275. else
  276. detail::print_parser(context, parser, os, components + 1);
  277. os << "]";
  278. }
  279. template<typename Context, typename Parser, typename F>
  280. void print_parser(
  281. Context const & context,
  282. transform_parser<Parser, F> const & parser,
  283. std::ostream & os,
  284. int components)
  285. {
  286. detail::print_directive(
  287. context, "transform(<<f>>)", parser.parser_, os, components);
  288. }
  289. template<typename Context, typename Parser>
  290. void print_parser(
  291. Context const & context,
  292. omit_parser<Parser> const & parser,
  293. std::ostream & os,
  294. int components)
  295. {
  296. detail::print_directive(
  297. context, "omit", parser.parser_, os, components);
  298. }
  299. template<typename Context, typename Parser>
  300. void print_parser(
  301. Context const & context,
  302. raw_parser<Parser> const & parser,
  303. std::ostream & os,
  304. int components)
  305. {
  306. detail::print_directive(context, "raw", parser.parser_, os, components);
  307. }
  308. #if defined(BOOST_PARSER_DOXYGEN) || BOOST_PARSER_USE_CONCEPTS
  309. template<typename Context, typename Parser>
  310. void print_parser(
  311. Context const & context,
  312. string_view_parser<Parser> const & parser,
  313. std::ostream & os,
  314. int components)
  315. {
  316. detail::print_directive(
  317. context, "string_view", parser.parser_, os, components);
  318. }
  319. #endif
  320. template<typename Context, typename Parser>
  321. void print_parser(
  322. Context const & context,
  323. lexeme_parser<Parser> const & parser,
  324. std::ostream & os,
  325. int components)
  326. {
  327. detail::print_directive(
  328. context, "lexeme", parser.parser_, os, components);
  329. }
  330. template<typename Context, typename Parser>
  331. void print_parser(
  332. Context const & context,
  333. no_case_parser<Parser> const & parser,
  334. std::ostream & os,
  335. int components)
  336. {
  337. detail::print_directive(
  338. context, "no_case", parser.parser_, os, components);
  339. }
  340. template<typename Context, typename Parser, typename SkipParser>
  341. void print_parser(
  342. Context const & context,
  343. skip_parser<Parser, SkipParser> const & parser,
  344. std::ostream & os,
  345. int components)
  346. {
  347. if constexpr (is_nope_v<SkipParser>) {
  348. detail::print_directive(
  349. context, "skip", parser.parser_, os, components);
  350. } else {
  351. os << "skip(";
  352. detail::print_parser(
  353. context, parser.skip_parser_.parser_, os, components);
  354. os << ")";
  355. detail::print_directive(
  356. context, "", parser.parser_, os, components + 1);
  357. }
  358. }
  359. template<typename Context, typename Parser, bool FailOnMatch>
  360. void print_parser(
  361. Context const & context,
  362. expect_parser<Parser, FailOnMatch> const & parser,
  363. std::ostream & os,
  364. int components)
  365. {
  366. if (FailOnMatch)
  367. os << "!";
  368. else
  369. os << "&";
  370. constexpr bool n_ary_child = n_aray_parser_v<Parser>;
  371. if (n_ary_child)
  372. os << "(";
  373. detail::print_parser(context, parser.parser_, os, components + 1);
  374. if (n_ary_child)
  375. os << ")";
  376. }
  377. template<
  378. typename Context,
  379. bool UseCallbacks,
  380. typename Parser,
  381. typename Attribute,
  382. typename LocalState,
  383. typename ParamsTuple>
  384. void print_parser(
  385. Context const & context,
  386. rule_parser<
  387. UseCallbacks,
  388. Parser,
  389. Attribute,
  390. LocalState,
  391. ParamsTuple> const & parser,
  392. std::ostream & os,
  393. int components)
  394. {
  395. os << parser.diagnostic_text_;
  396. if constexpr (!is_nope_v<ParamsTuple>) {
  397. os << ".with(";
  398. int i = 0;
  399. hl::for_each(parser.params_, [&](auto const & param) {
  400. if (i++)
  401. os << ", ";
  402. detail::print_expected(context, os, param, true);
  403. });
  404. os << ")";
  405. }
  406. }
  407. template<typename Context, typename T>
  408. void print_parser(
  409. Context const & context,
  410. symbol_parser<T> const & parser,
  411. std::ostream & os,
  412. int components)
  413. {
  414. if (parser.diagnostic_text_.empty())
  415. os << "symbols<" << detail::type_name<T>() << ">";
  416. else
  417. os << parser.diagnostic_text_;
  418. }
  419. template<typename Context, typename Predicate>
  420. void print_parser(
  421. Context const & context,
  422. eps_parser<Predicate> const & parser,
  423. std::ostream & os,
  424. int components)
  425. {
  426. os << "eps(<<pred>>)";
  427. }
  428. template<typename Context>
  429. void print_parser(
  430. Context const & context,
  431. eps_parser<nope> const & parser,
  432. std::ostream & os,
  433. int components)
  434. {
  435. os << "eps";
  436. }
  437. template<typename Context>
  438. void print_parser(
  439. Context const & context,
  440. eoi_parser const & parser,
  441. std::ostream & os,
  442. int components)
  443. {
  444. os << "eoi";
  445. }
  446. template<typename Context, typename Atribute>
  447. void print_parser(
  448. Context const & context,
  449. attr_parser<Atribute> const & parser,
  450. std::ostream & os,
  451. int components)
  452. {
  453. os << "attr";
  454. detail::print_expected(context, os, parser.attr_);
  455. }
  456. template<
  457. typename Context,
  458. typename ResolvedExpected,
  459. bool Integral = std::is_integral<ResolvedExpected>{}>
  460. struct print_expected_char_impl
  461. {
  462. static void call(
  463. Context const & context,
  464. std::ostream & os,
  465. ResolvedExpected expected)
  466. {
  467. detail::print(os, expected);
  468. }
  469. };
  470. template<typename Context>
  471. struct print_expected_char_impl<Context, char32_t, true>
  472. {
  473. static void
  474. call(Context const & context, std::ostream & os, char32_t expected)
  475. {
  476. if (expected == '\'') {
  477. os << "'\\''";
  478. return;
  479. }
  480. std::array<char32_t, 1> cps = {{expected}};
  481. auto const r = cps | text::as_utf8;
  482. os << "'";
  483. for (auto c : r) {
  484. detail::print_char(os, c);
  485. }
  486. os << "'";
  487. }
  488. };
  489. template<typename Context, typename Expected>
  490. void print_expected_char(
  491. Context const & context, std::ostream & os, Expected expected)
  492. {
  493. auto resolved_expected = detail::resolve(context, expected);
  494. detail::print_expected_char_impl<Context, decltype(resolved_expected)>::
  495. call(context, os, resolved_expected);
  496. }
  497. template<typename Context, typename T>
  498. struct char_print_parser_impl
  499. {
  500. static void call(Context const & context, std::ostream & os, T expected)
  501. {
  502. detail::print_expected_char(context, os, expected);
  503. }
  504. };
  505. template<typename Context, typename T, typename U>
  506. struct char_print_parser_impl<Context, char_pair<T, U>>
  507. {
  508. static void call(
  509. Context const & context,
  510. std::ostream & os,
  511. char_pair<T, U> expected)
  512. {
  513. detail::print_expected_char(context, os, expected.lo_);
  514. os << ", ";
  515. detail::print_expected_char(context, os, expected.hi_);
  516. }
  517. };
  518. template<typename Context, typename Iter, typename Sentinel, bool B>
  519. struct char_print_parser_impl<Context, char_range<Iter, Sentinel, B>>
  520. {
  521. static void call(
  522. Context const & context,
  523. std::ostream & os,
  524. char_range<Iter, Sentinel, B> expected)
  525. {
  526. os << "\"";
  527. auto const r = expected.chars_ | text::as_utf8;
  528. for (auto c : r) {
  529. detail::print_char(os, c);
  530. }
  531. os << "\"";
  532. }
  533. };
  534. template<typename Context, typename Expected, typename AttributeType>
  535. void print_parser(
  536. Context const & context,
  537. char_parser<Expected, AttributeType> const & parser,
  538. std::ostream & os,
  539. int components)
  540. {
  541. if (std::is_same_v<AttributeType, uint32_t>)
  542. os << "cp";
  543. else if (std::is_same_v<AttributeType, char>)
  544. os << "cu";
  545. else
  546. os << "char_";
  547. if constexpr (!is_nope_v<Expected>) {
  548. os << "(";
  549. char_print_parser_impl<Context, Expected>::call(
  550. context, os, parser.expected_);
  551. os << ")";
  552. }
  553. }
  554. template<typename Context>
  555. void print_parser(
  556. Context const & context,
  557. digit_parser const & parser,
  558. std::ostream & os,
  559. int components)
  560. {
  561. os << "digit";
  562. }
  563. template<typename Context>
  564. void print_parser(
  565. Context const & context,
  566. char_subrange_parser<hex_digit_subranges> const & parser,
  567. std::ostream & os,
  568. int components)
  569. {
  570. os << "hex_digit";
  571. }
  572. template<typename Context>
  573. void print_parser(
  574. Context const & context,
  575. char_subrange_parser<control_subranges> const & parser,
  576. std::ostream & os,
  577. int components)
  578. {
  579. os << "control";
  580. }
  581. template<typename Context>
  582. void print_parser(
  583. Context const & context,
  584. char_set_parser<punct_chars> const & parser,
  585. std::ostream & os,
  586. int components)
  587. {
  588. os << "punct";
  589. }
  590. template<typename Context>
  591. void print_parser(
  592. Context const & context,
  593. char_set_parser<symb_chars> const & parser,
  594. std::ostream & os,
  595. int components)
  596. {
  597. os << "symb";
  598. }
  599. template<typename Context>
  600. void print_parser(
  601. Context const & context,
  602. char_set_parser<lower_case_chars> const & parser,
  603. std::ostream & os,
  604. int components)
  605. {
  606. os << "lower";
  607. }
  608. template<typename Context>
  609. void print_parser(
  610. Context const & context,
  611. char_set_parser<upper_case_chars> const & parser,
  612. std::ostream & os,
  613. int components)
  614. {
  615. os << "upper";
  616. }
  617. template<typename Context, typename Expected, typename AttributeType>
  618. void print_parser(
  619. Context const & context,
  620. omit_parser<char_parser<Expected, AttributeType>> const & parser,
  621. std::ostream & os,
  622. int components)
  623. {
  624. if constexpr (is_nope_v<Expected>) {
  625. os << "omit[char_]";
  626. } else {
  627. char_print_parser_impl<Context, Expected>::call(
  628. context, os, parser.parser_.expected_);
  629. }
  630. }
  631. template<typename Context, typename StrIter, typename StrSentinel>
  632. void print_parser(
  633. Context const & context,
  634. string_parser<StrIter, StrSentinel> const & parser,
  635. std::ostream & os,
  636. int components)
  637. {
  638. os << "string(\"";
  639. for (auto c : BOOST_PARSER_DETAIL_TEXT_SUBRANGE(
  640. parser.expected_first_, parser.expected_last_) |
  641. text::as_utf8) {
  642. detail::print_char(os, c);
  643. }
  644. os << "\")";
  645. }
  646. template<typename Context, typename StrIter, typename StrSentinel>
  647. void print_parser(
  648. Context const & context,
  649. omit_parser<string_parser<StrIter, StrSentinel>> const & parser,
  650. std::ostream & os,
  651. int components)
  652. {
  653. os << "\"";
  654. for (auto c : BOOST_PARSER_DETAIL_TEXT_SUBRANGE(
  655. parser.parser_.expected_first_,
  656. parser.parser_.expected_last_) |
  657. text::as_utf8) {
  658. detail::print_char(os, c);
  659. }
  660. os << "\"";
  661. }
  662. template<
  663. typename Context,
  664. typename Quotes,
  665. typename Escapes,
  666. typename CharParser>
  667. void print_parser(
  668. Context const & context,
  669. quoted_string_parser<Quotes, Escapes, CharParser> const & parser,
  670. std::ostream & os,
  671. int components)
  672. {
  673. os << "quoted_string(";
  674. if constexpr (is_nope_v<Quotes>) {
  675. detail::print_expected_char_impl<Context, char32_t>::call(
  676. context, os, parser.ch_);
  677. } else {
  678. os << '"';
  679. for (auto c : parser.chs_ | text::as_utf8) {
  680. detail::print_char(os, c);
  681. }
  682. os << '"';
  683. }
  684. os << ')';
  685. }
  686. template<typename Context, bool NewlinesOnly, bool NoNewlines>
  687. void print_parser(
  688. Context const & context,
  689. ws_parser<NewlinesOnly, NoNewlines> const & parser,
  690. std::ostream & os,
  691. int components)
  692. {
  693. if constexpr (NoNewlines)
  694. os << "blank";
  695. else if constexpr (NewlinesOnly)
  696. os << "eol";
  697. else
  698. os << "ws";
  699. }
  700. template<typename Context>
  701. void print_parser(
  702. Context const & context,
  703. bool_parser const & parser,
  704. std::ostream & os,
  705. int components)
  706. {
  707. os << "bool_";
  708. }
  709. template<
  710. typename Context,
  711. typename T,
  712. int Radix,
  713. int MinDigits,
  714. int MaxDigits,
  715. typename Expected>
  716. void print_parser(
  717. Context const & context,
  718. uint_parser<T, Radix, MinDigits, MaxDigits, Expected> const & parser,
  719. std::ostream & os,
  720. int components)
  721. {
  722. if (MinDigits == 1 && MaxDigits == -1) {
  723. if (std::is_same_v<T, unsigned short>) {
  724. os << "ushort_";
  725. detail::print_expected(context, os, parser.expected_);
  726. return;
  727. } else if (std::is_same_v<T, unsigned int>) {
  728. if (Radix == 2)
  729. os << "bin";
  730. else if (Radix == 8)
  731. os << "oct";
  732. else if (Radix == 16)
  733. os << "hex";
  734. else if (Radix == 10)
  735. os << "uint_";
  736. detail::print_expected(context, os, parser.expected_);
  737. return;
  738. } else if (Radix == 10 && std::is_same_v<T, unsigned long>) {
  739. os << "ulong_";
  740. detail::print_expected(context, os, parser.expected_);
  741. return;
  742. } else if (Radix == 10 && std::is_same_v<T, unsigned long long>) {
  743. os << "ulong_long";
  744. detail::print_expected(context, os, parser.expected_);
  745. return;
  746. }
  747. }
  748. os << "uint<" << detail::type_name<T>() << ", " << Radix << ", "
  749. << MinDigits << ", " << MaxDigits << ">";
  750. detail::print_expected(context, os, parser.expected_);
  751. }
  752. template<
  753. typename Context,
  754. typename T,
  755. int Radix,
  756. int MinDigits,
  757. int MaxDigits,
  758. typename Expected>
  759. void print_parser(
  760. Context const & context,
  761. int_parser<T, Radix, MinDigits, MaxDigits, Expected> const & parser,
  762. std::ostream & os,
  763. int components)
  764. {
  765. if (Radix == 10 && MinDigits == 1 && MaxDigits == -1) {
  766. if (std::is_same_v<T, short>) {
  767. os << "short_";
  768. detail::print_expected(context, os, parser.expected_);
  769. return;
  770. } else if (std::is_same_v<T, int>) {
  771. os << "int_";
  772. detail::print_expected(context, os, parser.expected_);
  773. return;
  774. } else if (std::is_same_v<T, long>) {
  775. os << "long_";
  776. detail::print_expected(context, os, parser.expected_);
  777. return;
  778. } else if (std::is_same_v<T, long long>) {
  779. os << "long_long";
  780. detail::print_expected(context, os, parser.expected_);
  781. return;
  782. }
  783. }
  784. os << "int<" << detail::type_name<T>() << ", " << Radix << ", "
  785. << MinDigits << ", " << MaxDigits << ">";
  786. detail::print_expected(context, os, parser.expected_);
  787. }
  788. template<typename Context>
  789. void print_parser(
  790. Context const & context,
  791. int_parser<short> const & parser,
  792. std::ostream & os,
  793. int components)
  794. {
  795. os << "short_";
  796. }
  797. template<typename Context>
  798. void print_parser(
  799. Context const & context,
  800. int_parser<long> const & parser,
  801. std::ostream & os,
  802. int components)
  803. {
  804. os << "long_";
  805. }
  806. template<typename Context>
  807. void print_parser(
  808. Context const & context,
  809. int_parser<long long> const & parser,
  810. std::ostream & os,
  811. int components)
  812. {
  813. os << "long_long";
  814. }
  815. template<typename Context, typename T>
  816. void print_parser(
  817. Context const & context,
  818. float_parser<T> const & parser,
  819. std::ostream & os,
  820. int components)
  821. {
  822. os << "float<" << detail::type_name<T>() << ">";
  823. }
  824. template<typename Context>
  825. void print_parser(
  826. Context const & context,
  827. float_parser<float> const & parser,
  828. std::ostream & os,
  829. int components)
  830. {
  831. os << "float_";
  832. }
  833. template<typename Context>
  834. void print_parser(
  835. Context const & context,
  836. float_parser<double> const & parser,
  837. std::ostream & os,
  838. int components)
  839. {
  840. os << "double_";
  841. }
  842. template<
  843. typename Context,
  844. typename ParserTuple,
  845. typename BacktrackingTuple,
  846. typename CombiningGroups>
  847. void print_switch_matchers(
  848. Context const & context,
  849. seq_parser<ParserTuple, BacktrackingTuple, CombiningGroups> const &
  850. parser,
  851. std::ostream & os,
  852. int components)
  853. {
  854. using namespace literals;
  855. os << "(";
  856. detail::print(
  857. os,
  858. detail::resolve(
  859. context, parser::get(parser.parsers_, 0_c).pred_.value_));
  860. os << ", ";
  861. detail::print_parser(
  862. context, parser::get(parser.parsers_, 1_c), os, components);
  863. os << ")";
  864. }
  865. template<typename Context, typename ParserTuple>
  866. void print_switch_matchers(
  867. Context const & context,
  868. or_parser<ParserTuple> const & parser,
  869. std::ostream & os,
  870. int components)
  871. {
  872. using namespace literals;
  873. bool printed_ellipsis = false;
  874. hl::for_each(parser.parsers_, [&](auto const & parser) {
  875. if (components == parser_component_limit) {
  876. if (!printed_ellipsis)
  877. os << "...";
  878. printed_ellipsis = true;
  879. return;
  880. }
  881. detail::print_switch_matchers(context, parser, os, components);
  882. ++components;
  883. });
  884. }
  885. template<typename Context, typename SwitchValue, typename OrParser>
  886. void print_parser(
  887. Context const & context,
  888. switch_parser<SwitchValue, OrParser> const & parser,
  889. std::ostream & os,
  890. int components)
  891. {
  892. os << "switch_(";
  893. detail::print(os, detail::resolve(context, parser.switch_value_));
  894. os << ")";
  895. detail::print_switch_matchers(
  896. context, parser.or_parser_, os, components);
  897. }
  898. }}}
  899. #endif