]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (c) 2009 Francois Barel |
2 | // Copyright (c) 2001-2011 Joel de Guzman | |
3 | // Copyright (c) 2001-2012 Hartmut Kaiser | |
4 | // | |
5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | #if !defined(BOOST_SPIRIT_REPOSITORY_KARMA_SUBRULE_AUGUST_12_2009_0813PM) | |
9 | #define BOOST_SPIRIT_REPOSITORY_KARMA_SUBRULE_AUGUST_12_2009_0813PM | |
10 | ||
11 | #if defined(_MSC_VER) | |
12 | #pragma once | |
13 | #endif | |
14 | ||
15 | #include <boost/spirit/home/karma/domain.hpp> | |
16 | #include <boost/spirit/home/karma/meta_compiler.hpp> | |
17 | #include <boost/spirit/home/karma/generator.hpp> | |
18 | #include <boost/spirit/home/karma/reference.hpp> | |
19 | #include <boost/spirit/home/karma/nonterminal/detail/generator_binder.hpp> | |
20 | #include <boost/spirit/home/karma/nonterminal/detail/parameterized.hpp> | |
21 | #include <boost/spirit/home/support/argument.hpp> | |
22 | #include <boost/spirit/home/support/assert_msg.hpp> | |
23 | #include <boost/spirit/home/karma/detail/attributes.hpp> | |
24 | #include <boost/spirit/home/support/info.hpp> | |
25 | #include <boost/spirit/home/support/unused.hpp> | |
26 | #include <boost/spirit/home/support/nonterminal/extract_param.hpp> | |
27 | #include <boost/spirit/home/support/nonterminal/locals.hpp> | |
28 | #include <boost/spirit/repository/home/support/subrule_context.hpp> | |
29 | ||
30 | #include <boost/fusion/include/as_map.hpp> | |
31 | #include <boost/fusion/include/at_key.hpp> | |
32 | #include <boost/fusion/include/cons.hpp> | |
33 | #include <boost/fusion/include/front.hpp> | |
34 | #include <boost/fusion/include/has_key.hpp> | |
35 | #include <boost/fusion/include/join.hpp> | |
36 | #include <boost/fusion/include/make_map.hpp> | |
37 | #include <boost/fusion/include/make_vector.hpp> | |
38 | #include <boost/fusion/include/size.hpp> | |
39 | #include <boost/fusion/include/vector.hpp> | |
40 | #include <boost/mpl/bool.hpp> | |
41 | #include <boost/mpl/identity.hpp> | |
42 | #include <boost/mpl/int.hpp> | |
43 | #include <boost/mpl/vector.hpp> | |
44 | #include <boost/type_traits/add_reference.hpp> | |
45 | #include <boost/type_traits/is_same.hpp> | |
46 | #include <boost/type_traits/remove_reference.hpp> | |
47 | ||
48 | #if defined(BOOST_MSVC) | |
49 | # pragma warning(push) | |
50 | # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning | |
51 | #endif | |
52 | ||
53 | /////////////////////////////////////////////////////////////////////////////// | |
54 | namespace boost { namespace spirit { namespace repository { namespace karma | |
55 | { | |
56 | /////////////////////////////////////////////////////////////////////////// | |
11fdf7f2 | 57 | // subrule_group_generator: |
7c673cae FG |
58 | // - generator representing a group of subrule definitions (one or more), |
59 | // invokes first subrule on entry, | |
7c673cae FG |
60 | /////////////////////////////////////////////////////////////////////////// |
61 | template <typename Defs> | |
11fdf7f2 TL |
62 | struct subrule_group_generator |
63 | : spirit::karma::generator<subrule_group_generator<Defs> > | |
7c673cae | 64 | { |
7c673cae FG |
65 | // Fusion associative sequence, associating each subrule ID in this |
66 | // group (as an MPL integral constant) with its definition | |
67 | typedef Defs defs_type; | |
68 | ||
11fdf7f2 | 69 | typedef subrule_group_generator<Defs> this_type; |
7c673cae | 70 | |
11fdf7f2 TL |
71 | explicit subrule_group_generator(Defs const& defs) |
72 | : defs(defs) | |
7c673cae FG |
73 | { |
74 | } | |
7c673cae FG |
75 | // from a subrule ID, get the type of a reference to its definition |
76 | template <int ID> | |
77 | struct def_type | |
78 | { | |
79 | typedef mpl::int_<ID> id_type; | |
80 | ||
81 | // If you are seeing a compilation error here, you are trying | |
82 | // to use a subrule which was not defined in this group. | |
83 | BOOST_SPIRIT_ASSERT_MSG( | |
84 | (fusion::result_of::has_key< | |
85 | defs_type const, id_type>::type::value) | |
86 | , subrule_used_without_being_defined, (mpl::int_<ID>)); | |
87 | ||
88 | typedef typename | |
89 | fusion::result_of::at_key<defs_type const, id_type>::type | |
90 | type; | |
91 | }; | |
92 | ||
93 | // from a subrule ID, get a reference to its definition | |
94 | template <int ID> | |
95 | typename def_type<ID>::type def() const | |
96 | { | |
97 | return fusion::at_key<mpl::int_<ID> >(defs); | |
98 | } | |
99 | ||
100 | template <typename Context, typename Iterator> | |
101 | struct attribute | |
102 | // Forward to first subrule. | |
103 | : mpl::identity< | |
104 | typename remove_reference< | |
105 | typename fusion::result_of::front<Defs>::type | |
106 | >::type::second_type::attr_type> {}; | |
107 | ||
108 | template <typename OutputIterator, typename Context | |
109 | , typename Delimiter, typename Attribute> | |
110 | bool generate(OutputIterator& sink, Context& context | |
111 | , Delimiter const& delimiter, Attribute const& attr) const | |
112 | { | |
113 | // Forward to first subrule. | |
114 | return generate_subrule(fusion::front(defs).second | |
115 | , sink, context, delimiter, attr); | |
116 | } | |
117 | ||
118 | template <typename OutputIterator, typename Context | |
119 | , typename Delimiter, typename Attribute | |
120 | , typename Params> | |
121 | bool generate(OutputIterator& sink, Context& context | |
122 | , Delimiter const& delimiter, Attribute const& attr | |
123 | , Params const& params) const | |
124 | { | |
125 | // Forward to first subrule. | |
126 | return generate_subrule(fusion::front(defs).second | |
127 | , sink, context, delimiter, attr, params); | |
128 | } | |
129 | ||
130 | template <int ID, typename OutputIterator, typename Context | |
131 | , typename Delimiter, typename Attribute> | |
132 | bool generate_subrule_id(OutputIterator& sink | |
133 | , Context& context, Delimiter const& delimiter | |
134 | , Attribute const& attr) const | |
135 | { | |
136 | return generate_subrule(def<ID>() | |
137 | , sink, context, delimiter, attr); | |
138 | } | |
139 | ||
140 | template <int ID, typename OutputIterator, typename Context | |
141 | , typename Delimiter, typename Attribute, typename Params> | |
142 | bool generate_subrule_id(OutputIterator& sink | |
143 | , Context& context, Delimiter const& delimiter | |
144 | , Attribute const& attr, Params const& params) const | |
145 | { | |
146 | return generate_subrule(def<ID>() | |
147 | , sink, context, delimiter, attr, params); | |
148 | } | |
149 | ||
150 | template <typename Def, typename OutputIterator, typename Context | |
151 | , typename Delimiter, typename Attribute> | |
152 | bool generate_subrule(Def const& def, OutputIterator& sink | |
153 | , Context& /*caller_context*/, Delimiter const& delimiter | |
154 | , Attribute const& attr) const | |
155 | { | |
156 | // compute context type for this subrule | |
157 | typedef typename Def::locals_type subrule_locals_type; | |
158 | typedef typename Def::attr_type subrule_attr_type; | |
159 | typedef typename Def::attr_reference_type subrule_attr_reference_type; | |
160 | typedef typename Def::parameter_types subrule_parameter_types; | |
161 | ||
162 | typedef | |
163 | subrule_context< | |
164 | this_type | |
165 | , fusion::cons< | |
166 | subrule_attr_reference_type, subrule_parameter_types> | |
167 | , subrule_locals_type | |
168 | > | |
169 | context_type; | |
170 | ||
92f5a8d4 TL |
171 | typedef traits::transform_attribute<Attribute const |
172 | , subrule_attr_type, spirit::karma::domain> transform; | |
7c673cae FG |
173 | |
174 | // If you are seeing a compilation error here, you are probably | |
175 | // trying to use a subrule which has inherited attributes, | |
176 | // without passing values for them. | |
92f5a8d4 | 177 | context_type context(*this, transform::pre(attr)); |
7c673cae FG |
178 | |
179 | return def.binder(sink, context, delimiter); | |
180 | } | |
181 | ||
182 | template <typename Def, typename OutputIterator, typename Context | |
183 | , typename Delimiter, typename Attribute, typename Params> | |
184 | bool generate_subrule(Def const& def, OutputIterator& sink | |
185 | , Context& caller_context, Delimiter const& delimiter | |
186 | , Attribute const& attr, Params const& params) const | |
187 | { | |
188 | // compute context type for this subrule | |
189 | typedef typename Def::locals_type subrule_locals_type; | |
190 | typedef typename Def::attr_type subrule_attr_type; | |
191 | typedef typename Def::attr_reference_type subrule_attr_reference_type; | |
192 | typedef typename Def::parameter_types subrule_parameter_types; | |
193 | ||
194 | typedef | |
195 | subrule_context< | |
196 | this_type | |
197 | , fusion::cons< | |
198 | subrule_attr_reference_type, subrule_parameter_types> | |
199 | , subrule_locals_type | |
200 | > | |
201 | context_type; | |
202 | ||
92f5a8d4 TL |
203 | typedef traits::transform_attribute<Attribute const |
204 | , subrule_attr_type, spirit::karma::domain> transform; | |
7c673cae FG |
205 | |
206 | // If you are seeing a compilation error here, you are probably | |
207 | // trying to use a subrule which has inherited attributes, | |
208 | // passing values of incompatible types for them. | |
209 | context_type context(*this | |
92f5a8d4 | 210 | , transform::pre(attr), params, caller_context); |
7c673cae FG |
211 | |
212 | return def.binder(sink, context, delimiter); | |
213 | } | |
214 | ||
215 | template <typename Context> | |
216 | info what(Context& context) const | |
217 | { | |
218 | // Forward to first subrule. | |
219 | return fusion::front(defs).second.binder.g.what(context); | |
220 | } | |
221 | ||
11fdf7f2 TL |
222 | Defs defs; |
223 | }; | |
224 | ||
225 | /////////////////////////////////////////////////////////////////////////// | |
226 | // subrule_group: | |
227 | // - a Proto terminal, so that a group behaves like any Spirit | |
228 | // expression. | |
229 | /////////////////////////////////////////////////////////////////////////// | |
230 | template <typename Defs> | |
231 | struct subrule_group | |
232 | : proto::extends< | |
233 | typename proto::terminal< | |
234 | subrule_group_generator<Defs> | |
235 | >::type | |
236 | , subrule_group<Defs> | |
237 | > | |
238 | { | |
239 | typedef subrule_group_generator<Defs> generator_type; | |
240 | typedef typename proto::terminal<generator_type>::type terminal; | |
241 | ||
242 | struct properties | |
243 | // Forward to first subrule. | |
244 | : remove_reference< | |
245 | typename fusion::result_of::front<Defs>::type | |
246 | >::type::second_type::subject_type::properties {}; | |
247 | ||
248 | static size_t const params_size = | |
249 | // Forward to first subrule. | |
250 | remove_reference< | |
251 | typename fusion::result_of::front<Defs>::type | |
252 | >::type::second_type::params_size; | |
253 | ||
254 | explicit subrule_group(Defs const& defs) | |
255 | : subrule_group::proto_extends(terminal::make(generator_type(defs))) | |
256 | { | |
257 | } | |
258 | ||
259 | generator_type const& generator() const { return proto::value(*this); } | |
260 | ||
261 | Defs const& defs() const { return generator().defs; } | |
262 | ||
7c673cae FG |
263 | template <typename Defs2> |
264 | subrule_group< | |
265 | typename fusion::result_of::as_map< | |
266 | typename fusion::result_of::join< | |
267 | Defs const, Defs2 const>::type>::type> | |
268 | operator,(subrule_group<Defs2> const& other) const | |
269 | { | |
270 | typedef subrule_group< | |
271 | typename fusion::result_of::as_map< | |
272 | typename fusion::result_of::join< | |
273 | Defs const, Defs2 const>::type>::type> result_type; | |
11fdf7f2 TL |
274 | return result_type(fusion::as_map(fusion::join(defs(), other.defs()))); |
275 | } | |
276 | ||
277 | // non-const versions needed to suppress proto's comma op kicking in | |
278 | template <typename Defs2> | |
279 | friend subrule_group< | |
280 | typename fusion::result_of::as_map< | |
281 | typename fusion::result_of::join< | |
282 | Defs const, Defs2 const>::type>::type> | |
283 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
284 | operator,(subrule_group&& left, subrule_group<Defs2>&& other) | |
285 | #else | |
286 | operator,(subrule_group& left, subrule_group<Defs2>& other) | |
287 | #endif | |
288 | { | |
289 | return static_cast<subrule_group const&>(left) | |
290 | .operator,(static_cast<subrule_group<Defs2> const&>(other)); | |
7c673cae FG |
291 | } |
292 | ||
293 | // bring in the operator() overloads | |
11fdf7f2 TL |
294 | generator_type const& get_parameterized_subject() const { return generator(); } |
295 | typedef generator_type parameterized_subject_type; | |
7c673cae | 296 | #include <boost/spirit/home/karma/nonterminal/detail/fcall.hpp> |
7c673cae FG |
297 | }; |
298 | ||
299 | /////////////////////////////////////////////////////////////////////////// | |
300 | // subrule_definition: holds one particular definition of a subrule | |
301 | /////////////////////////////////////////////////////////////////////////// | |
302 | template < | |
303 | int ID_ | |
304 | , typename Locals | |
305 | , typename Attr | |
306 | , typename AttrRef | |
307 | , typename Parameters | |
308 | , size_t ParamsSize | |
309 | , typename Subject | |
310 | , bool Auto_ | |
311 | > | |
312 | struct subrule_definition | |
313 | { | |
314 | typedef mpl::int_<ID_> id_type; | |
315 | BOOST_STATIC_CONSTANT(int, ID = ID_); | |
316 | ||
317 | typedef Locals locals_type; | |
318 | typedef Attr attr_type; | |
319 | typedef AttrRef attr_reference_type; | |
320 | typedef Parameters parameter_types; | |
321 | static size_t const params_size = ParamsSize; | |
322 | ||
323 | typedef Subject subject_type; | |
324 | typedef mpl::bool_<Auto_> auto_type; | |
325 | BOOST_STATIC_CONSTANT(bool, Auto = Auto_); | |
326 | ||
327 | typedef spirit::karma::detail::generator_binder< | |
328 | Subject, auto_type> binder_type; | |
329 | ||
330 | subrule_definition(Subject const& subject, std::string const& name) | |
331 | : binder(subject), name(name) | |
332 | { | |
333 | } | |
334 | ||
335 | binder_type const binder; | |
336 | std::string const name; | |
337 | }; | |
338 | ||
339 | /////////////////////////////////////////////////////////////////////////// | |
340 | // subrule placeholder: | |
341 | // - on subrule definition: helper for creation of subrule_group, | |
342 | // - on subrule invocation: Proto terminal and generator. | |
343 | /////////////////////////////////////////////////////////////////////////// | |
344 | template < | |
345 | int ID_ | |
346 | , typename T1 = unused_type | |
347 | , typename T2 = unused_type | |
348 | > | |
349 | struct subrule | |
350 | : proto::extends< | |
351 | typename proto::terminal< | |
352 | spirit::karma::reference<subrule<ID_, T1, T2> const> | |
353 | >::type | |
354 | , subrule<ID_, T1, T2> | |
355 | > | |
356 | , spirit::karma::generator<subrule<ID_, T1, T2> > | |
357 | { | |
358 | //FIXME should go fetch the real properties of this subrule's definition in the current context, but we don't | |
359 | // have the context here (properties would need to be 'template<typename Context> struct properties' instead) | |
360 | typedef mpl::int_< | |
361 | spirit::karma::generator_properties::all_properties> properties; | |
362 | ||
363 | typedef mpl::int_<ID_> id_type; | |
364 | BOOST_STATIC_CONSTANT(int, ID = ID_); | |
365 | ||
366 | typedef subrule<ID_, T1, T2> this_type; | |
367 | typedef spirit::karma::reference<this_type const> reference_; | |
368 | typedef typename proto::terminal<reference_>::type terminal; | |
369 | typedef proto::extends<terminal, this_type> base_type; | |
370 | ||
371 | typedef mpl::vector<T1, T2> template_params; | |
372 | ||
11fdf7f2 | 373 | // The subrule's locals_type: a sequence of types to be used as local variables |
7c673cae FG |
374 | typedef typename |
375 | spirit::detail::extract_locals<template_params>::type | |
376 | locals_type; | |
377 | ||
11fdf7f2 TL |
378 | // The subrule's encoding type |
379 | typedef typename | |
380 | spirit::detail::extract_encoding<template_params>::type | |
381 | encoding_type; | |
382 | ||
383 | // The subrule's signature | |
7c673cae | 384 | typedef typename |
11fdf7f2 TL |
385 | spirit::detail::extract_sig<template_params, encoding_type |
386 | , spirit::karma::domain>::type | |
7c673cae FG |
387 | sig_type; |
388 | ||
389 | // This is the subrule's attribute type | |
390 | typedef typename | |
391 | spirit::detail::attr_from_sig<sig_type>::type | |
392 | attr_type; | |
393 | typedef typename add_reference< | |
394 | typename add_const<attr_type>::type>::type attr_reference_type; | |
395 | ||
396 | // parameter_types is a sequence of types passed as parameters to the subrule | |
397 | typedef typename | |
398 | spirit::detail::params_from_sig<sig_type>::type | |
399 | parameter_types; | |
400 | ||
401 | static size_t const params_size = | |
402 | fusion::result_of::size<parameter_types>::type::value; | |
403 | ||
404 | explicit subrule(std::string const& name_ = "unnamed-subrule") | |
405 | : base_type(terminal::make(reference_(*this))) | |
406 | , name_(name_) | |
407 | { | |
408 | } | |
409 | ||
410 | // compute type of this subrule's definition for expr type Expr | |
411 | template <typename Expr, bool Auto> | |
412 | struct def_type_helper | |
413 | { | |
414 | // Report invalid expression error as early as possible. | |
415 | // If you got an error_invalid_expression error message here, | |
416 | // then the expression (Expr) is not a valid spirit karma expression. | |
417 | BOOST_SPIRIT_ASSERT_MATCH(spirit::karma::domain, Expr); | |
418 | ||
419 | typedef typename result_of::compile< | |
420 | spirit::karma::domain, Expr>::type subject_type; | |
421 | ||
422 | typedef subrule_definition< | |
423 | ID_ | |
424 | , locals_type | |
425 | , attr_type | |
426 | , attr_reference_type | |
427 | , parameter_types | |
428 | , params_size | |
429 | , subject_type | |
430 | , Auto | |
431 | > const type; | |
432 | }; | |
433 | ||
434 | // compute type of subrule group containing only this | |
435 | // subrule's definition for expr type Expr | |
436 | template <typename Expr, bool Auto> | |
437 | struct group_type_helper | |
438 | { | |
439 | typedef typename def_type_helper<Expr, Auto>::type def_type; | |
440 | ||
441 | // create Defs map with only one entry: (ID -> def) | |
442 | typedef typename | |
443 | #ifndef BOOST_FUSION_HAS_VARIADIC_MAP | |
444 | fusion::result_of::make_map<id_type, def_type>::type | |
445 | #else | |
446 | fusion::result_of::make_map<id_type>::template apply<def_type>::type | |
447 | #endif | |
448 | defs_type; | |
449 | ||
450 | typedef subrule_group<defs_type> type; | |
451 | }; | |
452 | ||
453 | template <typename Expr> | |
454 | typename group_type_helper<Expr, false>::type | |
455 | operator=(Expr const& expr) const | |
456 | { | |
457 | typedef group_type_helper<Expr, false> helper; | |
458 | typedef typename helper::def_type def_type; | |
459 | typedef typename helper::type result_type; | |
460 | return result_type(fusion::make_map<id_type>( | |
461 | def_type(compile<spirit::karma::domain>(expr), name_))); | |
462 | } | |
463 | ||
11fdf7f2 TL |
464 | #define SUBRULE_MODULUS_ASSIGN_OPERATOR(lhs_ref, rhs_ref) \ |
465 | template <typename Expr> \ | |
466 | friend typename group_type_helper<Expr, true>::type \ | |
467 | operator%=(subrule lhs_ref sr, Expr rhs_ref expr) \ | |
468 | { \ | |
469 | typedef group_type_helper<Expr, true> helper; \ | |
470 | typedef typename helper::def_type def_type; \ | |
471 | typedef typename helper::type result_type; \ | |
472 | return result_type(fusion::make_map<id_type>( \ | |
473 | def_type(compile<spirit::karma::domain>(expr), sr.name_))); \ | |
474 | } \ | |
475 | /**/ | |
7c673cae FG |
476 | |
477 | // non-const versions needed to suppress proto's %= kicking in | |
11fdf7f2 TL |
478 | SUBRULE_MODULUS_ASSIGN_OPERATOR(const&, const&) |
479 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
480 | SUBRULE_MODULUS_ASSIGN_OPERATOR(const&, &&) | |
481 | #else | |
482 | SUBRULE_MODULUS_ASSIGN_OPERATOR(const&, &) | |
483 | #endif | |
484 | SUBRULE_MODULUS_ASSIGN_OPERATOR(&, const&) | |
485 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
486 | SUBRULE_MODULUS_ASSIGN_OPERATOR(&, &&) | |
487 | #else | |
488 | SUBRULE_MODULUS_ASSIGN_OPERATOR(&, &) | |
489 | #endif | |
490 | ||
491 | #undef SUBRULE_MODULUS_ASSIGN_OPERATOR | |
7c673cae FG |
492 | |
493 | std::string const& name() const | |
494 | { | |
495 | return name_; | |
496 | } | |
497 | ||
498 | void name(std::string const& str) | |
499 | { | |
500 | name_ = str; | |
501 | } | |
502 | ||
503 | template <typename Context, typename Iterator> | |
504 | struct attribute | |
505 | { | |
506 | typedef attr_type type; | |
507 | }; | |
508 | ||
509 | template <typename OutputIterator, typename Group | |
510 | , typename Attributes, typename Locals | |
511 | , typename Delimiter, typename Attribute> | |
512 | bool generate(OutputIterator& sink | |
513 | , subrule_context<Group, Attributes, Locals>& context | |
514 | , Delimiter const& delimiter, Attribute const& attr) const | |
515 | { | |
516 | return context.group.template generate_subrule_id<ID_>( | |
517 | sink, context, delimiter, attr); | |
518 | } | |
519 | ||
520 | template <typename OutputIterator, typename Context | |
521 | , typename Delimiter, typename Attribute> | |
522 | bool generate(OutputIterator& /*sink*/ | |
523 | , Context& /*context*/ | |
524 | , Delimiter const& /*delimiter*/, Attribute const& /*attr*/) const | |
525 | { | |
526 | // If you are seeing a compilation error here, you are trying | |
527 | // to use a subrule as a generator outside of a subrule group. | |
528 | BOOST_SPIRIT_ASSERT_FAIL(OutputIterator | |
529 | , subrule_used_outside_subrule_group, (id_type)); | |
530 | ||
531 | return false; | |
532 | } | |
533 | ||
534 | template <typename OutputIterator, typename Group | |
535 | , typename Attributes, typename Locals | |
536 | , typename Delimiter, typename Attribute | |
537 | , typename Params> | |
538 | bool generate(OutputIterator& sink | |
539 | , subrule_context<Group, Attributes, Locals>& context | |
540 | , Delimiter const& delimiter, Attribute const& attr | |
541 | , Params const& params) const | |
542 | { | |
543 | return context.group.template generate_subrule_id<ID_>( | |
544 | sink, context, delimiter, attr, params); | |
545 | } | |
546 | ||
547 | template <typename OutputIterator, typename Context | |
548 | , typename Delimiter, typename Attribute | |
549 | , typename Params> | |
550 | bool generate(OutputIterator& /*sink*/ | |
551 | , Context& /*context*/ | |
552 | , Delimiter const& /*delimiter*/, Attribute const& /*attr*/ | |
553 | , Params const& /*params*/) const | |
554 | { | |
555 | // If you are seeing a compilation error here, you are trying | |
556 | // to use a subrule as a generator outside of a subrule group. | |
557 | BOOST_SPIRIT_ASSERT_FAIL(OutputIterator | |
558 | , subrule_used_outside_subrule_group, (id_type)); | |
559 | ||
560 | return false; | |
561 | } | |
562 | ||
563 | template <typename Context> | |
564 | info what(Context& /*context*/) const | |
565 | { | |
566 | return info(name_); | |
567 | } | |
568 | ||
569 | // bring in the operator() overloads | |
570 | this_type const& get_parameterized_subject() const { return *this; } | |
571 | typedef this_type parameterized_subject_type; | |
572 | #include <boost/spirit/home/karma/nonterminal/detail/fcall.hpp> | |
573 | ||
574 | std::string name_; | |
575 | }; | |
576 | }}}} | |
577 | ||
578 | #if defined(BOOST_MSVC) | |
579 | # pragma warning(pop) | |
580 | #endif | |
581 | ||
582 | #endif |