]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/spirit/home/x3/nonterminal/detail/rule.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / spirit / home / x3 / nonterminal / detail / rule.hpp
CommitLineData
7c673cae
FG
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_DETAIL_RULE_JAN_08_2012_0326PM)
8#define BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM
9
b32b8144 10#include <boost/core/ignore_unused.hpp>
7c673cae
FG
11#include <boost/spirit/home/x3/auxiliary/guard.hpp>
12#include <boost/spirit/home/x3/core/parser.hpp>
13#include <boost/spirit/home/x3/core/skip_over.hpp>
14#include <boost/spirit/home/x3/directive/expect.hpp>
7c673cae
FG
15#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
16#include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp>
17#include <boost/utility/addressof.hpp>
18
19#if defined(BOOST_SPIRIT_X3_DEBUG)
20#include <boost/spirit/home/x3/nonterminal/simple_trace.hpp>
21#endif
22
92f5a8d4
TL
23#include <type_traits>
24
7c673cae
FG
25namespace boost { namespace spirit { namespace x3
26{
27 template <typename ID>
28 struct identity;
29
30 template <typename ID, typename Attribute = unused_type, bool force_attribute = false>
31 struct rule;
32
33 struct parse_pass_context_tag;
34
35 namespace detail
36 {
37 // we use this so we can detect if the default parse_rule
38 // is the being called.
39 struct default_parse_rule_result
40 {
41 default_parse_rule_result(bool r)
42 : r(r) {}
43 operator bool() const { return r; }
44 bool r;
45 };
46 }
47
48 // default parse_rule implementation
49 template <typename ID, typename Attribute, typename Iterator
50 , typename Context, typename ActualAttribute>
51 inline detail::default_parse_rule_result
52 parse_rule(
53 rule<ID, Attribute> rule_
54 , Iterator& first, Iterator const& last
55 , Context const& context, ActualAttribute& attr);
56}}}
57
58namespace boost { namespace spirit { namespace x3 { namespace detail
59{
60#if defined(BOOST_SPIRIT_X3_DEBUG)
61 template <typename Iterator, typename Attribute>
62 struct context_debug
63 {
64 context_debug(
65 char const* rule_name
66 , Iterator const& first, Iterator const& last
67 , Attribute const& attr
68 , bool const& ok_parse //was parse successful?
69 )
70 : ok_parse(ok_parse), rule_name(rule_name)
71 , first(first), last(last)
72 , attr(attr)
73 , f(detail::get_simple_trace())
74 {
75 f(first, last, attr, pre_parse, rule_name);
76 }
77
78 ~context_debug()
79 {
80 auto status = ok_parse ? successful_parse : failed_parse ;
81 f(first, last, attr, status, rule_name);
82 }
83
84 bool const& ok_parse;
85 char const* rule_name;
86 Iterator const& first;
87 Iterator const& last;
88 Attribute const& attr;
89 detail::simple_trace_type& f;
90 };
91#endif
92
93 template <typename ID, typename Iterator, typename Context, typename Enable = void>
94 struct has_on_error : mpl::false_ {};
95
96 template <typename ID, typename Iterator, typename Context>
97 struct has_on_error<ID, Iterator, Context,
98 typename disable_if_substitution_failure<
99 decltype(
100 std::declval<ID>().on_error(
101 std::declval<Iterator&>()
102 , std::declval<Iterator>()
103 , std::declval<expectation_failure<Iterator>>()
104 , std::declval<Context>()
105 )
106 )>::type
107 >
108 : mpl::true_
109 {};
110
111 template <typename ID, typename Iterator, typename Attribute, typename Context, typename Enable = void>
112 struct has_on_success : mpl::false_ {};
113
114 template <typename ID, typename Iterator, typename Attribute, typename Context>
115 struct has_on_success<ID, Iterator, Context, Attribute,
116 typename disable_if_substitution_failure<
117 decltype(
118 std::declval<ID>().on_success(
119 std::declval<Iterator&>()
120 , std::declval<Iterator>()
121 , std::declval<Attribute&>()
122 , std::declval<Context>()
123 )
124 )>::type
125 >
126 : mpl::true_
127 {};
128
129 template <typename ID>
130 struct make_id
131 {
132 typedef identity<ID> type;
133 };
134
135 template <typename ID>
136 struct make_id<identity<ID>>
137 {
138 typedef identity<ID> type;
139 };
140
141 template <typename ID, typename RHS, typename Context>
142 Context const&
b32b8144 143 make_rule_context(RHS const& /* rhs */, Context const& context
7c673cae
FG
144 , mpl::false_ /* is_default_parse_rule */)
145 {
146 return context;
147 }
148
149 template <typename ID, typename RHS, typename Context>
150 auto make_rule_context(RHS const& rhs, Context const& context
151 , mpl::true_ /* is_default_parse_rule */ )
152 {
153 return make_unique_context<ID>(rhs, context);
154 }
155
156 template <typename Attribute, typename ID>
157 struct rule_parser
158 {
159 template <typename Iterator, typename Context, typename ActualAttribute>
160 static bool call_on_success(
b32b8144
FG
161 Iterator& /* first */, Iterator const& /* last */
162 , Context const& /* context */, ActualAttribute& /* attr */
7c673cae
FG
163 , mpl::false_ /* No on_success handler */ )
164 {
165 return true;
166 }
167
168 template <typename Iterator, typename Context, typename ActualAttribute>
169 static bool call_on_success(
170 Iterator& first, Iterator const& last
171 , Context const& context, ActualAttribute& attr
172 , mpl::true_ /* Has on_success handler */)
173 {
174 bool pass = true;
175 ID().on_success(
176 first
177 , last
178 , attr
179 , make_context<parse_pass_context_tag>(pass, context)
180 );
181 return pass;
182 }
183
184 template <typename RHS, typename Iterator, typename Context
185 , typename RContext, typename ActualAttribute>
186 static bool parse_rhs_main(
187 RHS const& rhs
188 , Iterator& first, Iterator const& last
189 , Context const& context, RContext& rcontext, ActualAttribute& attr
190 , mpl::false_)
191 {
192 // see if the user has a BOOST_SPIRIT_DEFINE for this rule
193 typedef
194 decltype(parse_rule(
195 rule<ID, Attribute>(), first, last
92f5a8d4 196 , make_unique_context<ID>(rhs, context), std::declval<Attribute&>()))
7c673cae
FG
197 parse_rule_result;
198
199 // If there is no BOOST_SPIRIT_DEFINE for this rule,
200 // we'll make a context for this rule tagged by its ID
201 // so we can extract the rule later on in the default
202 // (generic) parse_rule function.
203 typedef
204 is_same<parse_rule_result, default_parse_rule_result>
205 is_default_parse_rule;
206
207 Iterator i = first;
208 bool r = rhs.parse(
209 i
210 , last
211 , make_rule_context<ID>(rhs, context, is_default_parse_rule())
212 , rcontext
213 , attr
214 );
215
216 if (r)
217 {
218 auto first_ = first;
219 x3::skip_over(first_, last, context);
220 r = call_on_success(first_, i, context, attr
221 , has_on_success<ID, Iterator, Context, ActualAttribute>());
222 }
223
224 if (r)
225 first = i;
226 return r;
227 }
228
229 template <typename RHS, typename Iterator, typename Context
230 , typename RContext, typename ActualAttribute>
231 static bool parse_rhs_main(
232 RHS const& rhs
233 , Iterator& first, Iterator const& last
234 , Context const& context, RContext& rcontext, ActualAttribute& attr
235 , mpl::true_ /* on_error is found */)
236 {
237 for (;;)
238 {
239 try
240 {
241 return parse_rhs_main(
242 rhs, first, last, context, rcontext, attr, mpl::false_());
243 }
244 catch (expectation_failure<Iterator> const& x)
245 {
246 switch (ID().on_error(first, last, x, context))
247 {
248 case error_handler_result::fail:
249 return false;
250 case error_handler_result::retry:
251 continue;
252 case error_handler_result::accept:
253 return true;
254 case error_handler_result::rethrow:
255 throw;
256 }
257 }
258 }
259 }
260
261 template <typename RHS, typename Iterator
262 , typename Context, typename RContext, typename ActualAttribute>
263 static bool parse_rhs_main(
264 RHS const& rhs
265 , Iterator& first, Iterator const& last
266 , Context const& context, RContext& rcontext, ActualAttribute& attr)
267 {
268 return parse_rhs_main(
269 rhs, first, last, context, rcontext, attr
270 , has_on_error<ID, Iterator, Context>()
271 );
272 }
273
274 template <typename RHS, typename Iterator
275 , typename Context, typename RContext, typename ActualAttribute>
276 static bool parse_rhs(
277 RHS const& rhs
278 , Iterator& first, Iterator const& last
279 , Context const& context, RContext& rcontext, ActualAttribute& attr
280 , mpl::false_)
281 {
282 return parse_rhs_main(rhs, first, last, context, rcontext, attr);
283 }
284
285 template <typename RHS, typename Iterator
286 , typename Context, typename RContext, typename ActualAttribute>
287 static bool parse_rhs(
288 RHS const& rhs
289 , Iterator& first, Iterator const& last
b32b8144 290 , Context const& context, RContext& rcontext, ActualAttribute& /* attr */
7c673cae
FG
291 , mpl::true_)
292 {
293 return parse_rhs_main(rhs, first, last, context, rcontext, unused);
294 }
295
296 template <typename RHS, typename Iterator, typename Context
297 , typename ActualAttribute, typename ExplicitAttrPropagation>
298 static bool call_rule_definition(
299 RHS const& rhs
300 , char const* rule_name
301 , Iterator& first, Iterator const& last
302 , Context const& context, ActualAttribute& attr
303 , ExplicitAttrPropagation)
304 {
b32b8144
FG
305 boost::ignore_unused(rule_name);
306
7c673cae
FG
307 // do down-stream transformation, provides attribute for
308 // rhs parser
309 typedef traits::transform_attribute<
92f5a8d4 310 ActualAttribute, Attribute, parser_id>
7c673cae
FG
311 transform;
312
7c673cae 313 typedef typename transform::type transform_attr;
92f5a8d4 314 transform_attr attr_ = transform::pre(attr);
7c673cae
FG
315
316 bool ok_parse
317 //Creates a place to hold the result of parse_rhs
318 //called inside the following scope.
319 ;
320 {
321 // Create a scope to cause the dbg variable below (within
322 // the #if...#endif) to call it's DTOR before any
323 // modifications are made to the attribute, attr_ passed
324 // to parse_rhs (such as might be done in
92f5a8d4 325 // transform::post when, for example,
7c673cae
FG
326 // ActualAttribute is a recursive variant).
327#if defined(BOOST_SPIRIT_X3_DEBUG)
b32b8144
FG
328 context_debug<Iterator, transform_attr>
329 dbg(rule_name, first, last, attr_, ok_parse);
7c673cae
FG
330#endif
331 ok_parse = parse_rhs(rhs, first, last, context, attr_, attr_
332 , mpl::bool_
333 < ( RHS::has_action
334 && !ExplicitAttrPropagation::value
335 )
336 >()
337 );
338 }
339 if (ok_parse)
340 {
341 // do up-stream transformation, this integrates the results
342 // back into the original attribute value, if appropriate
92f5a8d4 343 transform::post(attr, std::forward<transform_attr>(attr_));
7c673cae
FG
344 }
345 return ok_parse;
346 }
347 };
348}}}}
349
350#endif