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