guard.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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_GUARD_FERBRUARY_02_2013_0649PM)
  7. #define BOOST_SPIRIT_X3_GUARD_FERBRUARY_02_2013_0649PM
  8. #include <boost/spirit/home/x3/support/context.hpp>
  9. #include <boost/spirit/home/x3/directive/expect.hpp>
  10. namespace boost { namespace spirit { namespace x3
  11. {
  12. enum class error_handler_result
  13. {
  14. fail
  15. , retry
  16. , accept
  17. , rethrow
  18. };
  19. template <typename Subject, typename Handler>
  20. struct guard : unary_parser<Subject, guard<Subject, Handler>>
  21. {
  22. typedef unary_parser<Subject, guard<Subject, Handler>> base_type;
  23. static bool const is_pass_through_unary = true;
  24. guard(Subject const& subject, Handler handler)
  25. : base_type(subject), handler(handler) {}
  26. template <typename Iterator, typename Context
  27. , typename RuleContext, typename Attribute>
  28. bool parse(Iterator& first, Iterator const& last
  29. , Context const& context, RuleContext& rcontext, Attribute& attr) const
  30. {
  31. for (;;)
  32. {
  33. try
  34. {
  35. Iterator i = first;
  36. bool r = this->subject.parse(i, last, context, rcontext, attr);
  37. if (r)
  38. first = i;
  39. return r;
  40. }
  41. catch (expectation_failure<Iterator> const& x)
  42. {
  43. switch (handler(first, last, x, context))
  44. {
  45. case error_handler_result::fail:
  46. return false;
  47. case error_handler_result::retry:
  48. continue;
  49. case error_handler_result::accept:
  50. return true;
  51. case error_handler_result::rethrow:
  52. throw;
  53. }
  54. }
  55. }
  56. return false;
  57. }
  58. Handler handler;
  59. };
  60. }}}
  61. #endif