1 [/==============================================================================
2 Copyright (C) 2001-2011 Joel de Guzman
3 Copyright (C) 2001-2011 Hartmut Kaiser
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 ===============================================================================/]
9 [section Generator Concepts]
11 __karma__ generators fall into a couple of generalized __concepts__. The
12 /Generator/ is the most fundamental concept. All __karma__ generators are
13 models of the /Generator/ concept. /PrimitiveGenerator/, /UnaryGenerator/,
14 /BinaryGenerator/, /NaryGenerator/, and /Nonterminal/ are all refinements of
15 the /Generator/ concept.
17 The following sections provide details on these concepts.
19 [/////////////////////////////////////////////////////////////////////////////]
24 The /Generator/ is the most fundamental concept. A Generator has a member
25 function, `generate`, that accepts an `OutputIterator` and
26 returns bool as its result. The iterator receives the data being generated.
27 The Generator's `generate` member function returns `true` if the generator
28 succeeds. Each Generator can represent a specific pattern or algorithm, or it
29 can be a more complex generator formed as a composition of other Generators.
31 [variablelist Notation
32 [[`g`] [A `Generator`.]]
33 [[`G`] [A `Generator` type.]]
34 [[`OutIter`] [An `OutputIterator` type.]]
35 [[`sink`] [An `OutputIterator` instance.]]
36 [[`Context`] [The generator's __karma_context__ type.]]
37 [[`context`] [The generator's __karma_context__, or __unused__.]]
38 [[`delimit`] [A delimiter Generator, or __unused__.]]
39 [[`attrib`] [A __karma_compatible_attribute__, or __unused__.]]
42 [heading Valid Expressions]
44 In the expressions below, the behavior of the generator, `g`, as well as how
45 `delimit` and `attrib` are handled by `g`, are left unspecified in the base
46 `Generator` concept. These are specified in subsequent, more refined concepts
47 and by the actual models thereof.
49 For any Generator the following expressions must be valid:
52 [[Expression] [Semantics] [Return type]]
54 ``g.generate(sink, context, delimit, attrib)``]
55 [Generate the output sequence by inserting the
56 generated characters/tokens into `sink`. Use the
57 `delimit` generator for delimiting. Return
58 `true` if successful, otherwise
59 return `false`.] [`bool`]]
60 [[`g.what(context)`] [Get information about a Generator.] [__info__]]
63 [heading Type Expressions]
66 [[Expression] [Description]]
67 [[`G::template attribute<Context>::type`] [The Generator's attribute.]]
68 [[`traits::is_generator<G>::type`] [Metafunction that evaluates to `mpl::true_` if
69 a certain type, `G` is a Generator, `mpl::false_`
70 otherwise (See __mpl_boolean_constant__).]]
71 [[`G::properties`] [An `mpl::int_` (See __mpl_int_constant__) holding
72 a value from the `karma::generator_properties`
73 enumeration. The default value is
74 `generator_properties::no_properties`]]
77 [heading Postcondition]
79 Upon return from `g.generate` the following post conditions should hold:
81 * On successful generation, `sink` receives the generated characters/tokens
83 * No pre-delimits: `delimit` characters/tokens will not be emitted in front of
85 * The attribute `attrib` has not been modified.
89 All generators in __karma__ are models of the /Generator/ concept.
91 [endsect] [/ Generator Concept]
93 [/////////////////////////////////////////////////////////////////////////////]
94 [section PrimitiveGenerator]
98 /PrimitiveGenerator/ is the most basic building block that the client uses
99 to build more complex generators.
101 [heading Refinement of]
103 [:__generator_concept__]
105 [heading Post-delimit]
107 Before exiting the `generate` member function, a PrimitiveGenerator is required
108 to do a post-delimit. This will generate a single delimiting character/token
109 sequence. Only PrimitiveGenerator's are required to perform this post-delimit.
110 This is typically carried out through a call to `karma::delimit_out`:
112 karma::delimit_out(sink, delimit);
114 [heading Type Expressions]
117 [[Expression] [Description]]
118 [[`traits::is_primitive_generator<G>::type`] [Metafunction that evaluates to `mpl::true_` if
119 a certain type, `G`, is a PrimitiveGenerator, `mpl::false_`
120 otherwise (See __mpl_boolean_constant__).]]
125 The following generators conform to this model:
129 * [link spirit.karma.reference.numeric Numeric generators],
130 * [karma_char Character generators].
132 __fixme__ Add more links to /PrimitiveGenerator/ models here.
134 [endsect] [/ PrimitiveGenerator Concept]
136 [/////////////////////////////////////////////////////////////////////////////]
137 [section UnaryGenerator]
139 [heading Description]
141 /UnaryGenerator/ is a composite generator that has a single subject. The
142 UnaryGenerator may change the behavior of its subject following the
143 __delegate_pattern__.
145 [heading Refinement of]
147 [:__generator_concept__]
149 [variablelist Notation
150 [[`g`] [A UnaryGenerator.]]
151 [[`G`] [A UnaryGenerator type.]]
154 [heading Valid Expressions]
156 In addition to the requirements defined in __generator_concept__, for any
157 UnaryGenerator the following must be met:
160 [[Expression] [Semantics] [Return type]]
161 [[`g.subject`] [Subject generator.] [__generator_concept__]]
164 [heading Type Expressions]
167 [[Expression] [Description]]
168 [[`G::subject_type`] [The subject generator type.]]
169 [[`traits::is_unary_generator<G>::type`] [Metafunction that evaluates to `mpl::true_` if
170 a certain type, `G` is a UnaryGenerator, `mpl::false_`
171 otherwise (See __mpl_boolean_constant__).]]
176 For any UnaryGenerator, `G`, the following invariant always holds:
178 * `traits::is_generator<G::subject_type>::type` evaluates to `mpl::true_`
182 The following generators conform to this model:
184 * [karma_kleene Kleene Star (unary `*`)] operator,
185 * __karma_plus__ operator,
186 * __karma_optional__ operator,
187 * __karma_and_predicate__ and __karma_not_predicate__ operators,
188 * [karma_align `left_align`], [karma_align `center`], and [karma_align `right_align`] directives,
189 * [karma_repeat `repeat`] directive,
190 * __karma_verbatim__ directive,
191 * [karma_delimit `delimit`] directive,
192 * [karma_upperlower `lower`] and [karma_upperlower `upper`] directives,
193 * [karma_maxwidth `maxwidth`] directive,
194 * __karma_buffer__ directive,
195 * __karma_omit__ directive.
198 __fixme__ Add more links to models of UnaryGenerator concept
200 [endsect] [/ UnaryGenerator Concept]
202 [/////////////////////////////////////////////////////////////////////////////]
203 [section BinaryGenerator]
205 [heading Description]
207 /BinaryGenerator/ is a composite generator that has a two subjects, `left` and
208 `right`. The BinaryGenerator allows its subjects to be treated in the same
209 way as a single instance of a __generator_concept__ following the
210 __composite_pattern__.
212 [heading Refinement of]
214 [:__generator_concept__]
216 [variablelist Notation
217 [[`g`] [A BinaryGenerator.]]
218 [[`G`] [A BinaryGenerator type.]]
221 [heading Valid Expressions]
223 In addition to the requirements defined in __generator_concept__, for any
224 BinaryGenerator the following must be met:
227 [[Expression] [Semantics] [Return type]]
228 [[`g.left`] [Left generator.] [__generator_concept__]]
229 [[`g.right`] [Right generator.] [__generator_concept__]]
232 [heading Type Expressions]
235 [[Expression] [Description]]
236 [[`G::left_type`] [The left generator type.]]
237 [[`G::right_type`] [The right generator type.]]
238 [[`traits::is_binary_generator<G>::type`] [Metafunction that evaluates to `mpl::true_` if
239 a certain type, `G` is a BinaryGenerator, `mpl::false_`
240 otherwise (See __mpl_boolean_constant__).]]
245 For any BinaryGenerator, `G`, the following invariants always hold:
247 * `traits::is_generator<G::left_type>::type` evaluates to `mpl::true_`
248 * `traits::is_generator<G::right_type>::type` evaluates to `mpl::true_`
252 The following generators conform to this model:
256 __fixme__ Add more links to models of BinaryGenerator concept
258 [endsect] [/ BinaryGenerator Concept]
260 [/////////////////////////////////////////////////////////////////////////////]
261 [section NaryGenerator]
263 [heading Description]
265 /NaryGenerator/ is a composite generator that has one or more subjects. The
266 NaryGenerator allows its subjects to be treated in the same way as a single
267 instance of a __generator_concept__ following the __composite_pattern__.
269 [heading Refinement of]
271 [:__generator_concept__]
273 [variablelist Notation
274 [[`g`] [A NaryGenerator.]]
275 [[`G`] [A NaryGenerator type.]]
278 [heading Valid Expressions]
280 In addition to the requirements defined in __generator_concept__, for any
281 NaryGenerator the following must be met:
284 [[Expression] [Semantics] [Return type]]
285 [[`g.elements`] [The tuple of elements.] [A __fusion__ Sequence of __generator_concept__ types.]]
288 [heading Type Expressions]
291 [[Expression] [Description]]
292 [[`g.elements_type`] [Elements tuple type.]]
293 [[`traits::is_nary_generator<G>::type`] [Metafunction that evaluates to `mpl::true_` if
294 a certain type, `G` is a NaryGenerator, `mpl::false_`
295 otherwise (See __mpl_boolean_constant__).]]
300 For each element, `E`, in any NaryGenerator, `G`, the following
301 invariant always holds:
303 * `traits::is_generator<E>::type` evaluates to `mpl::true_`
307 The following generators conform to this model:
309 * __karma_sequence__,
310 * __karma_alternative__.
312 __fixme__ Add more links to models of NaryGenerator concept
314 [endsect] [/ NaryGenerator Concept]
316 [/////////////////////////////////////////////////////////////////////////////]
317 [section Nonterminal]
319 [heading Description]
321 A Nonterminal is a symbol in a __peg__ production that represents a
322 grammar fragment. Nonterminals may self reference to specify recursion.
323 This is one of the most important concepts and the reason behind the
324 word "recursive" in recursive descent generation.
326 [heading Refinement of]
328 [:__generator_concept__]
332 Rules can have both consumed and inherited attributes. The rule's
333 /Signature/ specifies both the consumed and inherited attributes. The
334 specification uses the function declarator syntax:
336 RT(A0, A1, A2, ..., AN)
338 where `RT` is the rule's consumed attribute and `A0` ... `AN` are the
339 rule's inherited attributes.
343 The rule models a C++ function. The rule's consumed attribute is
344 analogous to the function return value as it is the type -exposed- by the rule.
345 Its inherited attributes are analogous to function arguments. The inherited
346 attributes (arguments) can be passed in just like any __karma_lazy_argument__,
349 r(expr) // Evaluate expr at parse time and pass the result to the Nonterminal r
353 The `boost::spirit::karma::_val` placeholder can be used in __phoenix__
354 semantic actions anywhere in the Nonterminal's definition. This
355 __phoenix__ placeholder refers to the Nonterminal's (consumed)
356 attribute. The `_val` placeholder acts like an immutable reference to the
357 Nonterminal's attribute.
359 [note Starting with __spirit__ V2.5 (distributed with Boost V1.47) the
360 placeholder `_val` can be used in semantic actions attached to top level
361 generator components as well. See __generator_api__ for more information.]
363 [heading `_r1`...`r10`]
365 The `boost::spirit::_r1`...`boost::spirit::r10` placeholders can be used
366 in __phoenix__ semantic actions anywhere in the Nonterminal's
367 definition. These __phoenix__ placeholders refer to the Nonterminal's
368 inherited attributes.
372 Nonterminals can have local variables that will be created on the stack
373 at runtime. A locals descriptor added to the Nonterminal declaration
374 will give the Nonterminal local variables:
376 template <typename T0, typename T1, typename T2, ..., typename TN>
379 where `T0` ... `TN` are the types of local variables accessible in your
380 __phoenix__ semantic actions using the placeholders:
382 * `boost::spirit::_a`
383 * `boost::spirit::_b`
384 * `boost::spirit::_c`
385 * `boost::spirit::_d`
386 * `boost::spirit::_e`
387 * `boost::spirit::_f`
388 * `boost::spirit::_g`
389 * `boost::spirit::_h`
390 * `boost::spirit::_i`
391 * `boost::spirit::_j`
393 which correspond to the Nonterminal's local variables `T0` ... `T9`.
395 [variablelist Notation
396 [[`x`] [A Nonterminal]]
397 [[`X`] [A Nonterminal type]]
398 [[`arg1`, `arg2`, ..., `argN`] [__karma_lazy_arguments__ that evaluate to each of
399 the Nonterminal's inherited attributes.]]
402 [heading Valid Expressions]
404 In addition to the requirements defined in __generator_concept__, for any
405 Nonterminal the following must be met:
408 [[Expression] [Semantics] [Return type]]
409 [[`x`] [In a generator expression, invoke Nonterminal `x`] [`X`]]
410 [[`x(arg1, arg2, ..., argN)`][In a generator expression, invoke Nonterminal `x`
411 passing in inherited attributes
412 `arg1`...`argN`] [`X`]]
413 [[`x.name(name)`] [Set the name of a Nonterminal] [`void`]]
414 [[`x.name()`] [Get the name of a Nonterminal] [`std::string`]]
417 [heading Type Expressions]
420 [[Expression] [Description]]
421 [[`X::sig_type`] [The Signature of `X`: An __mpl_fwd_sequence__.
422 The first element is the Nonterminal's consumed attribute
423 type and the rest are the inherited attribute types.]]
424 [[`X::locals_type`] [The local variables of `X`: An __mpl_fwd_sequence__.]]