expect.hpp 3.3 KB

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