1 /*============================================================================= 2 Copyright (c) 2001-2014 Joel de Guzman 3 4 Distributed under the Boost Software License, Version 1.0. (See accompanying 5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 =============================================================================*/ 7 #if !defined(BOOST_SPIRIT_X3_GUARD_FERBRUARY_02_2013_0649PM) 8 #define BOOST_SPIRIT_X3_GUARD_FERBRUARY_02_2013_0649PM 9 10 #include <boost/spirit/home/x3/support/context.hpp> 11 #include <boost/spirit/home/x3/directive/expect.hpp> 12 13 namespace boost { namespace spirit { namespace x3 14 { 15 enum class error_handler_result 16 { 17 fail 18 , retry 19 , accept 20 , rethrow 21 }; 22 23 template <typename Subject, typename Handler> 24 struct guard : unary_parser<Subject, guard<Subject, Handler>> 25 { 26 typedef unary_parser<Subject, guard<Subject, Handler>> base_type; 27 static bool const is_pass_through_unary = true; 28 guardboost::spirit::x3::guard29 constexpr guard(Subject const& subject, Handler handler) 30 : base_type(subject), handler(handler) {} 31 32 template <typename Iterator, typename Context 33 , typename RuleContext, typename Attribute> parseboost::spirit::x3::guard34 bool parse(Iterator& first, Iterator const& last 35 , Context const& context, RuleContext& rcontext, Attribute& attr) const 36 { 37 for (;;) 38 { 39 try 40 { 41 Iterator i = first; 42 bool r = this->subject.parse(i, last, context, rcontext, attr); 43 if (r) 44 first = i; 45 return r; 46 } 47 catch (expectation_failure<Iterator> const& x) 48 { 49 switch (handler(first, last, x, context)) 50 { 51 case error_handler_result::fail: 52 return false; 53 case error_handler_result::retry: 54 continue; 55 case error_handler_result::accept: 56 return true; 57 case error_handler_result::rethrow: 58 throw; 59 } 60 } 61 } 62 return false; 63 } 64 65 Handler handler; 66 }; 67 }}} 68 69 #endif 70