change support python version
[platform/upstream/boost.git] / boost / spirit / home / x3 / core / action.hpp
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.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>
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
34         action(Subject const& subject, Action f)
35           : base_type(subject), f(f) {}
36
37         template <typename Iterator, typename Context, typename RuleContext, typename Attribute>
38         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>
50         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>
68         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>
78         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>
93         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     inline action<typename extension::as_parser<P>::value_type, Action>
104     operator/(P const& p, Action f)
105     {
106         return { as_parser(p), f };
107     }
108 }}}
109
110 #endif