• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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