]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/include/boost/spirit/home/classic/core/non_terminal/impl/rule.ipp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / classic / core / non_terminal / impl / rule.ipp
CommitLineData
7c673cae
FG
1/*=============================================================================
2 Copyright (c) 1998-2003 Joel de Guzman
3 http://spirit.sourceforge.net/
4
5 Use, modification and distribution is subject to the Boost Software
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 http://www.boost.org/LICENSE_1_0.txt)
8=============================================================================*/
9#if !defined(BOOST_SPIRIT_RULE_IPP)
10#define BOOST_SPIRIT_RULE_IPP
11
12#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
13#include <boost/preprocessor/repeat.hpp>
14#include <boost/preprocessor/repeat_from_to.hpp>
15#include <boost/preprocessor/enum_params.hpp>
16#include <boost/preprocessor/enum_params_with_defaults.hpp>
17#include <boost/preprocessor/facilities/intercept.hpp>
18#include <boost/preprocessor/inc.hpp>
19#include <boost/preprocessor/cat.hpp>
20#endif
21
22#include <boost/spirit/home/classic/core/parser.hpp>
23#include <boost/spirit/home/classic/core/scanner/scanner.hpp>
24#include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp>
25#include <boost/spirit/home/classic/core/non_terminal/parser_id.hpp>
26#include <boost/type_traits/is_base_and_derived.hpp>
27#include <boost/mpl/if.hpp>
28
29///////////////////////////////////////////////////////////////////////////////
30namespace boost { namespace spirit {
31
32BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
33
34#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
35
36 template <
37 BOOST_PP_ENUM_BINARY_PARAMS(
38 BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
39 typename ScannerT, = mpl::void_ BOOST_PP_INTERCEPT
40 )
41 >
42 struct scanner_list;
43
44#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
45
46 ///////////////////////////////////////////////////////////////////////////
47 namespace impl
48 {
49 template <typename BaseT, typename DefaultT
50 , typename T0, typename T1, typename T2>
51 struct get_param
52 {
53 typedef typename mpl::if_<
54 is_base_and_derived<BaseT, T0>
55 , T0
56 , typename mpl::if_<
57 is_base_and_derived<BaseT, T1>
58 , T1
59 , typename mpl::if_<
60 is_base_and_derived<BaseT, T2>
61 , T2
62 , DefaultT
63 >::type
64 >::type
65 >::type type;
66 };
67
68 template <typename T0, typename T1, typename T2>
69 struct get_context
70 {
71 typedef typename get_param<
72 parser_context_base, parser_context<>, T0, T1, T2>::type
73 type;
74 };
75
76 template <typename T0, typename T1, typename T2>
77 struct get_tag
78 {
79 typedef typename get_param<
80 parser_tag_base, parser_address_tag, T0, T1, T2>::type
81 type;
82 };
83
84 template <typename T0, typename T1, typename T2>
85 struct get_scanner
86 {
87 typedef typename get_param<
88 scanner_base, scanner<>, T0, T1, T2>::type
89 type;
90 };
91
92 ///////////////////////////////////////////////////////////////////////
93 //
94 // rule_base class
95 //
96 // The rule_base class implements the basic plumbing for rules
97 // minus the storage mechanism. It is up to the derived class
98 // to actually store the definition somewhere. The rule_base
99 // class assumes that the derived class provides a get() function
100 // that will return a pointer to a parser. The get() function
101 // may return NULL. See rule below for details.
102 //
103 // <<< For framework use only. Not for public consumption. >>>
104 //
105 ///////////////////////////////////////////////////////////////////////
106 template <
107 typename DerivedT // derived class
108 , typename EmbedT // how derived class is embedded
109 , typename T0 = nil_t // see rule class
110 , typename T1 = nil_t // see rule class
111 , typename T2 = nil_t // see rule class
112 >
113 class rule_base; // forward declaration
114
115 class rule_base_access
116 {
117#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
118 || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
119 public: // YUCK!
120#else
121 template <
122 typename DerivedT
123 , typename EmbedT
124 , typename T0
125 , typename T1
126 , typename T2
127 >
128 friend class rule_base;
129#endif
130 template <typename RuleT>
131 static typename RuleT::abstract_parser_t*
132 get(RuleT const& r)
133 {
134 return r.get();
135 }
136 };
137
138 template <
139 typename DerivedT // derived class
140 , typename EmbedT // how derived class is embedded
141 , typename T0 // see rule class
142 , typename T1 // see rule class
143 , typename T2 // see rule class
144 >
145 class rule_base
146 : public parser<DerivedT>
147 , public impl::get_context<T0, T1, T2>::type::base_t
148 , public context_aux<
149 typename impl::get_context<T0, T1, T2>::type, DerivedT>
150 , public impl::get_tag<T0, T1, T2>::type
151 {
152 public:
153
154 typedef typename impl::get_scanner<T0, T1, T2>::type scanner_t;
155 typedef typename impl::get_context<T0, T1, T2>::type context_t;
156 typedef typename impl::get_tag<T0, T1, T2>::type tag_t;
157
158 typedef EmbedT embed_t;
159 typedef typename context_t::context_linker_t linked_context_t;
160 typedef typename linked_context_t::attr_t attr_t;
161
162 template <typename ScannerT>
163 struct result
164 {
165 typedef typename match_result<ScannerT, attr_t>::type type;
166 };
167
168 template <typename ScannerT>
169 typename parser_result<DerivedT, ScannerT>::type
170 parse(ScannerT const& scan) const
171 {
172 typedef parser_scanner_linker<ScannerT> linked_scanner_t;
173 typedef typename parser_result<DerivedT, ScannerT>::type result_t;
174 BOOST_SPIRIT_CONTEXT_PARSE(
175 scan, *this, linked_scanner_t, linked_context_t, result_t);
176 }
177
178 template <typename ScannerT>
179 typename parser_result<DerivedT, ScannerT>::type
180 parse_main(ScannerT const& scan) const
181 {
182 typename parser_result<DerivedT, ScannerT>::type hit;
183
184 // MWCW 8.3 needs this cast to be done through a pointer,
185 // not a reference. Otherwise, it will silently construct
186 // a temporary, causing an infinite runtime recursion.
187 DerivedT const* derived_this = static_cast<DerivedT const*>(this);
188
189 if (rule_base_access::get(*derived_this))
190 {
191 typename ScannerT::iterator_t s(scan.first);
192 hit = rule_base_access::get(*derived_this)
193 ->do_parse_virtual(scan);
194 scan.group_match(hit, this->id(), s, scan.first);
195 }
196 else
197 {
198 hit = scan.no_match();
199 }
200 return hit;
201 }
202 };
203
204 ///////////////////////////////////////////////////////////////////////
205 //
206 // abstract_parser class
207 //
208 ///////////////////////////////////////////////////////////////////////
209 template <typename ScannerT, typename AttrT>
210 struct abstract_parser
211 {
212 abstract_parser() {}
213 virtual ~abstract_parser() {}
214
215 virtual typename match_result<ScannerT, AttrT>::type
216 do_parse_virtual(ScannerT const& scan) const = 0;
217
218 virtual abstract_parser*
219 clone() const = 0;
220 };
221
222 ///////////////////////////////////////////////////////////////////////
223 //
224 // concrete_parser class
225 //
226 ///////////////////////////////////////////////////////////////////////
227#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
228#pragma warning(push)
229#pragma warning(disable:4512) //assignment operator could not be generated
230#endif
231
232 template <typename ParserT, typename ScannerT, typename AttrT>
233 struct concrete_parser : abstract_parser<ScannerT, AttrT>
234 {
235 concrete_parser(ParserT const& p_) : p(p_) {}
236 virtual ~concrete_parser() {}
237
238 virtual typename match_result<ScannerT, AttrT>::type
239 do_parse_virtual(ScannerT const& scan) const
240 {
241 return p.parse(scan);
242 }
243
244 virtual abstract_parser<ScannerT, AttrT>*
245 clone() const
246 {
247 return new concrete_parser(p);
248 }
249
250 typename ParserT::embed_t p;
251 };
252
253#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
254#pragma warning(pop)
255#endif
256
257#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
258
259 ///////////////////////////////////////////////////////////////////////
260 //
261 // This generates partial specializations for the class
262 //
263 // abstract_parser
264 //
265 // with an increasing number of different ScannerT template parameters
266 // and corresponding do_parse_virtual function declarations for each
267 // of the different required scanner types:
268 //
269 // template <typename ScannerT0, ..., typename AttrT>
270 // struct abstract_parser<scanner_list<ScannerT0, ...>, AttrT>
271 // {
272 // abstract_parser() {}
273 // virtual ~abstract_parser() {}
274 //
275 // virtual typename match_result<ScannerT0, AttrT>::type
276 // do_parse_virtual(ScannerT0 const &scan) const = 0;
277 //
278 // virtual abstract_parser*
279 // clone() const = 0;
280 //
281 // ...
282 // };
283 //
284 ///////////////////////////////////////////////////////////////////////
285 #define BOOST_SPIRIT_RULE_ENUM_DOPARSE_A(z, N, _) \
286 virtual typename match_result< \
287 BOOST_PP_CAT(ScannerT, N), AttrT \
288 >::type \
289 do_parse_virtual( \
290 BOOST_PP_CAT(ScannerT, N) const& scan) const = 0; \
291
292 #define BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS(z, N, _) \
293 template < \
294 BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT), \
295 typename AttrT \
296 > \
297 struct abstract_parser< \
298 scanner_list< \
299 BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \
300 >, \
301 AttrT \
302 > \
303 { \
304 abstract_parser() {} \
305 virtual ~abstract_parser() {} \
306 \
307 BOOST_PP_REPEAT_ ## z( \
308 BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_A, _) \
309 \
310 virtual abstract_parser* \
311 clone() const = 0; \
312 }; \
313
314 BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
315 BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS, _)
316
317 #undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_A
318 #undef BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS
319 ///////////////////////////////////////////////////////////////////////
320
321 ///////////////////////////////////////////////////////////////////////
322 //
323 // This generates partial specializations for the class
324 //
325 // concrete_parser
326 //
327 // with an increasing number of different ScannerT template parameters
328 // and corresponding do_parse_virtual function declarations for each
329 // of the different required scanner types:
330 //
331 // template <
332 // typename ParserT, typename ScannerT0, ..., typename AttrT
333 // >
334 // struct concrete_parser<
335 // ParserT, scanner_list<ScannerT0, ...>, AttrT
336 // >
337 // : public abstract_parser<scanner_list<ScannerT0, ...>, AttrT>
338 // {
339 // concrete_parser(ParserT const& p_) : p(p_) {}
340 // virtual ~concrete_parser() {}
341 //
342 // virtual typename match_result<ScannerT0, AttrT>::type
343 // do_parse_virtual(ScannerT0 const &scan) const
344 // { return p.parse(scan); }
345 //
346 // virtual abstract_parser<scanner_list<ScannerT0, ...>, AttrT>*
347 // clone() const
348 // {
349 // return new concrete_parser(p);
350 // }
351 //
352 // ...
353 //
354 // typename ParserT::embed_t p;
355 // };
356 //
357 ///////////////////////////////////////////////////////////////////////
358 #define BOOST_SPIRIT_RULE_ENUM_DOPARSE_C(z, N, _) \
359 virtual typename match_result< \
360 BOOST_PP_CAT(ScannerT, N), AttrT \
361 >::type \
362 do_parse_virtual( \
363 BOOST_PP_CAT(ScannerT, N) const& scan) const \
364 { return p.parse(scan); } \
365
366 #define BOOST_SPIRIT_ENUM_CONCRETE_PARSERS(z, N, _) \
367 template < \
368 typename ParserT, \
369 BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT), \
370 typename AttrT \
371 > \
372 struct concrete_parser< \
373 ParserT, \
374 scanner_list< \
375 BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \
376 >, \
377 AttrT \
378 > \
379 : abstract_parser< \
380 scanner_list< \
381 BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \
382 >, \
383 AttrT \
384 > \
385 { \
386 concrete_parser(ParserT const& p_) : p(p_) {} \
387 virtual ~concrete_parser() {} \
388 \
389 BOOST_PP_REPEAT_ ## z( \
390 BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_C, _) \
391 \
392 virtual abstract_parser< \
393 scanner_list< \
394 BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \
395 >, \
396 AttrT \
397 >* \
398 clone() const \
399 { \
400 return new concrete_parser(p); \
401 } \
402 \
403 typename ParserT::embed_t p; \
404 }; \
405
406 BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
407 BOOST_SPIRIT_ENUM_CONCRETE_PARSERS, _)
408
409 #undef BOOST_SPIRIT_ENUM_CONCRETE_PARSERS
410 #undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_C
411 ///////////////////////////////////////////////////////////////////////
412
413#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
414
415 } // namespace impl
416
417BOOST_SPIRIT_CLASSIC_NAMESPACE_END
418
419}} // namespace boost::spirit
420
421#endif