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