1 /*============================================================================= 2 Copyright (arg) 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_ACTION_JANUARY_07_2007_1128AM) 8 #define BOOST_SPIRIT_X3_ACTION_JANUARY_07_2007_1128AM 9 10 #include <boost/spirit/home/x3/support/context.hpp> 11 #include <boost/spirit/home/x3/support/traits/attribute_of.hpp> 12 #include <boost/spirit/home/x3/core/call.hpp> 13 #include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp> 14 #include <boost/range/iterator_range_core.hpp> 15 16 namespace boost { namespace spirit { namespace x3 17 { 18 struct raw_attribute_type; 19 struct parse_pass_context_tag; 20 21 template <typename Context> _pass(Context const & context)22 inline bool& _pass(Context const& context) 23 { 24 return x3::get<parse_pass_context_tag>(context); 25 } 26 27 template <typename Subject, typename Action> 28 struct action : unary_parser<Subject, action<Subject, Action>> 29 { 30 typedef unary_parser<Subject, action<Subject, Action>> base_type; 31 static bool const is_pass_through_unary = true; 32 static bool const has_action = true; 33 actionboost::spirit::x3::action34 constexpr action(Subject const& subject, Action f) 35 : base_type(subject), f(f) {} 36 37 template <typename Iterator, typename Context, typename RuleContext, typename Attribute> call_actionboost::spirit::x3::action38 bool call_action( 39 Iterator& first, Iterator const& last 40 , Context const& context, RuleContext& rcontext, Attribute& attr) const 41 { 42 bool pass = true; 43 auto action_context = make_context<parse_pass_context_tag>(pass, context); 44 call(f, first, last, action_context, rcontext, attr); 45 return pass; 46 } 47 48 template <typename Iterator, typename Context 49 , typename RuleContext, typename Attribute> parse_mainboost::spirit::x3::action50 bool parse_main(Iterator& first, Iterator const& last 51 , Context const& context, RuleContext& rcontext, Attribute& attr) const 52 { 53 Iterator save = first; 54 if (this->subject.parse(first, last, context, rcontext, attr)) 55 { 56 if (call_action(first, last, context, rcontext, attr)) 57 return true; 58 59 // reset iterators if semantic action failed the match 60 // retrospectively 61 first = save; 62 } 63 return false; 64 } 65 66 // attr==raw_attribute_type, action wants iterator_range (see raw.hpp) 67 template <typename Iterator, typename Context, typename RuleContext> parse_mainboost::spirit::x3::action68 bool parse_main(Iterator& first, Iterator const& last 69 , Context const& context, RuleContext& rcontext, raw_attribute_type&) const 70 { 71 boost::iterator_range<Iterator> rng; 72 // synthesize the attribute since one is not supplied 73 return parse_main(first, last, context, rcontext, rng); 74 } 75 76 // attr==unused, action wants attribute 77 template <typename Iterator, typename Context, typename RuleContext> parseboost::spirit::x3::action78 bool parse(Iterator& first, Iterator const& last 79 , Context const& context, RuleContext& rcontext, unused_type) const 80 { 81 typedef typename 82 traits::attribute_of<action<Subject, Action>, Context>::type 83 attribute_type; 84 85 // synthesize the attribute since one is not supplied 86 attribute_type attr{}; 87 return parse_main(first, last, context, rcontext, attr); 88 } 89 90 // main parse function 91 template <typename Iterator, typename Context 92 , typename RuleContext, typename Attribute> parseboost::spirit::x3::action93 bool parse(Iterator& first, Iterator const& last 94 , Context const& context, RuleContext& rcontext, Attribute& attr) const 95 { 96 return parse_main(first, last, context, rcontext, attr); 97 } 98 99 Action f; 100 }; 101 102 template <typename P, typename Action> 103 constexpr action<typename extension::as_parser<P>::value_type, Action> operator /(P const & p,Action f)104 operator/(P const& p, Action f) 105 { 106 return { as_parser(p), f }; 107 } 108 }}} 109 110 #endif 111