expect.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*=============================================================================
  2. Copyright (c) 2001-2014 Joel de Guzman
  3. Copyright (c) 2017 wanghan02
  4. Copyright (c) 2024 Nana Sakisaka
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #if !defined(BOOST_SPIRIT_X3_EXPECT_MARCH_16_2012_1024PM)
  9. #define BOOST_SPIRIT_X3_EXPECT_MARCH_16_2012_1024PM
  10. #include <boost/spirit/home/x3/support/context.hpp>
  11. #include <boost/spirit/home/x3/support/expectation.hpp>
  12. #include <boost/spirit/home/x3/core/parser.hpp>
  13. #include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
  14. namespace boost { namespace spirit { namespace x3
  15. {
  16. template <typename Subject>
  17. struct expect_directive : unary_parser<Subject, expect_directive<Subject>>
  18. {
  19. typedef unary_parser<Subject, expect_directive<Subject> > base_type;
  20. static bool const is_pass_through_unary = true;
  21. constexpr expect_directive(Subject const& subject)
  22. : base_type(subject) {}
  23. template <typename Iterator, typename Context
  24. , typename RContext, typename Attribute>
  25. bool parse(Iterator& first, Iterator const& last
  26. , Context const& context, RContext& rcontext, Attribute& attr) const
  27. {
  28. bool const r = this->subject.parse(first, last, context, rcontext, attr);
  29. if (!r)
  30. {
  31. #if BOOST_SPIRIT_X3_THROW_EXPECTATION_FAILURE
  32. boost::throw_exception(
  33. expectation_failure<Iterator>(
  34. first, what(this->subject)));
  35. #else
  36. if (!has_expectation_failure(context))
  37. {
  38. set_expectation_failure(first, this->subject, context);
  39. }
  40. #endif
  41. }
  42. return r;
  43. }
  44. };
  45. struct expect_gen
  46. {
  47. template <typename Subject>
  48. constexpr expect_directive<typename extension::as_parser<Subject>::value_type>
  49. operator[](Subject const& subject) const
  50. {
  51. return { as_parser(subject) };
  52. }
  53. };
  54. constexpr auto expect = expect_gen{};
  55. }}}
  56. namespace boost { namespace spirit { namespace x3 { namespace detail
  57. {
  58. // Special case handling for expect expressions.
  59. template <typename Subject, typename Context, typename RContext>
  60. struct parse_into_container_impl<expect_directive<Subject>, Context, RContext>
  61. {
  62. template <typename Iterator, typename Attribute>
  63. static bool call(
  64. expect_directive<Subject> const& parser
  65. , Iterator& first, Iterator const& last
  66. , Context const& context, RContext& rcontext, Attribute& attr)
  67. {
  68. bool const r = parse_into_container(
  69. parser.subject, first, last, context, rcontext, attr);
  70. if (!r)
  71. {
  72. #if BOOST_SPIRIT_X3_THROW_EXPECTATION_FAILURE
  73. boost::throw_exception(
  74. expectation_failure<Iterator>(
  75. first, what(parser.subject)));
  76. #else
  77. if (!has_expectation_failure(context))
  78. {
  79. set_expectation_failure(first, parser.subject, context);
  80. }
  81. #endif
  82. }
  83. return r;
  84. }
  85. };
  86. }}}}
  87. #endif