1[/==============================================================================
2    Copyright (C) 2001-2011 Joel de Guzman
3    Copyright (C) 2001-2011 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
9[section Generator Concepts]
10
11__karma__ generators fall into a couple of generalized __concepts__. The
12/Generator/ is the most fundamental concept. All __karma__ generators are
13models of the /Generator/ concept. /PrimitiveGenerator/, /UnaryGenerator/,
14/BinaryGenerator/, /NaryGenerator/, and /Nonterminal/ are all refinements of
15the /Generator/ concept.
16
17The following sections provide details on these concepts.
18
19[/////////////////////////////////////////////////////////////////////////////]
20[section Generator]
21
22[heading Description]
23
24The /Generator/ is the most fundamental concept. A Generator has a member
25function, `generate`, that accepts an `OutputIterator` and
26returns bool as its result. The iterator receives the data being generated.
27The Generator's `generate` member function returns `true` if the generator
28succeeds. Each Generator can represent a specific pattern or algorithm, or it
29can be a more complex generator formed as a composition of other Generators.
30
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__.]]
40]
41
42[heading Valid Expressions]
43
44In 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
47and by the actual models thereof.
48
49For any Generator the following expressions must be valid:
50
51[table
52    [[Expression]           [Semantics]                         [Return type]]
53    [[
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__]]
61]
62
63[heading Type Expressions]
64
65[table
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`]]
75]
76
77[heading Postcondition]
78
79Upon return from `g.generate` the following post conditions should hold:
80
81* On successful generation, `sink` receives the generated characters/tokens
82  sequence.
83* No pre-delimits: `delimit` characters/tokens will not be emitted in front of
84  any other output.
85* The attribute `attrib` has not been modified.
86
87[heading Models]
88
89All generators in __karma__ are models of the /Generator/ concept.
90
91[endsect] [/ Generator Concept]
92
93[/////////////////////////////////////////////////////////////////////////////]
94[section PrimitiveGenerator]
95
96[heading Description]
97
98/PrimitiveGenerator/ is the most basic building block that the client uses
99to build more complex generators.
100
101[heading Refinement of]
102
103[:__generator_concept__]
104
105[heading Post-delimit]
106
107Before exiting the `generate` member function, a PrimitiveGenerator is required
108to do a post-delimit. This will generate a single delimiting character/token
109sequence. Only PrimitiveGenerator's are required to perform this post-delimit.
110This is typically carried out through a call to `karma::delimit_out`:
111
112    karma::delimit_out(sink, delimit);
113
114[heading Type Expressions]
115
116[table
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__).]]
121]
122
123[heading Models]
124
125The following generators conform to this model:
126
127* __karma_eol__,
128* __karma_eps__,
129* [link spirit.karma.reference.numeric Numeric generators],
130* [karma_char Character generators].
131
132__fixme__ Add more links to /PrimitiveGenerator/ models here.
133
134[endsect] [/ PrimitiveGenerator Concept]
135
136[/////////////////////////////////////////////////////////////////////////////]
137[section UnaryGenerator]
138
139[heading Description]
140
141/UnaryGenerator/ is a composite generator that has a single subject. The
142UnaryGenerator may change the behavior of its subject following the
143__delegate_pattern__.
144
145[heading Refinement of]
146
147[:__generator_concept__]
148
149[variablelist Notation
150    [[`g`]              [A UnaryGenerator.]]
151    [[`G`]              [A UnaryGenerator type.]]
152]
153
154[heading Valid Expressions]
155
156In addition to the requirements defined in __generator_concept__, for any
157UnaryGenerator the following must be met:
158
159[table
160    [[Expression]       [Semantics]             [Return type]]
161    [[`g.subject`]      [Subject generator.]    [__generator_concept__]]
162]
163
164[heading Type Expressions]
165
166[table
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__).]]
172]
173
174[heading Invariants]
175
176For any UnaryGenerator, `G`, the following invariant always holds:
177
178* `traits::is_generator<G::subject_type>::type` evaluates to `mpl::true_`
179
180[heading Models]
181
182The following generators conform to this model:
183
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.
196
197
198__fixme__ Add more links to models of UnaryGenerator concept
199
200[endsect] [/ UnaryGenerator Concept]
201
202[/////////////////////////////////////////////////////////////////////////////]
203[section BinaryGenerator]
204
205[heading Description]
206
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
209way as a single instance of a __generator_concept__ following the
210__composite_pattern__.
211
212[heading Refinement of]
213
214[:__generator_concept__]
215
216[variablelist Notation
217    [[`g`]              [A BinaryGenerator.]]
218    [[`G`]              [A BinaryGenerator type.]]
219]
220
221[heading Valid Expressions]
222
223In addition to the requirements defined in __generator_concept__, for any
224BinaryGenerator the following must be met:
225
226[table
227    [[Expression]       [Semantics]             [Return type]]
228    [[`g.left`]         [Left generator.]       [__generator_concept__]]
229    [[`g.right`]        [Right generator.]      [__generator_concept__]]
230]
231
232[heading Type Expressions]
233
234[table
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__).]]
241]
242
243[heading Invariants]
244
245For any BinaryGenerator, `G`, the following invariants always hold:
246
247* `traits::is_generator<G::left_type>::type` evaluates to `mpl::true_`
248* `traits::is_generator<G::right_type>::type` evaluates to `mpl::true_`
249
250[heading Models]
251
252The following generators conform to this model:
253
254* __karma_list__.
255
256__fixme__ Add more links to models of BinaryGenerator concept
257
258[endsect] [/ BinaryGenerator Concept]
259
260[/////////////////////////////////////////////////////////////////////////////]
261[section NaryGenerator]
262
263[heading Description]
264
265/NaryGenerator/ is a composite generator that has one or more subjects. The
266NaryGenerator allows its subjects to be treated in the same way as a single
267instance of a __generator_concept__ following the __composite_pattern__.
268
269[heading Refinement of]
270
271[:__generator_concept__]
272
273[variablelist Notation
274    [[`g`]              [A NaryGenerator.]]
275    [[`G`]              [A NaryGenerator type.]]
276]
277
278[heading Valid Expressions]
279
280In addition to the requirements defined in __generator_concept__, for any
281NaryGenerator the following must be met:
282
283[table
284    [[Expression]       [Semantics]                 [Return type]]
285    [[`g.elements`]     [The tuple of elements.]    [A __fusion__ Sequence of __generator_concept__ types.]]
286]
287
288[heading Type Expressions]
289
290[table
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__).]]
296]
297
298[heading Invariants]
299
300For each element, `E`, in any NaryGenerator, `G`, the following
301invariant always holds:
302
303* `traits::is_generator<E>::type` evaluates to `mpl::true_`
304
305[heading Models]
306
307The following generators conform to this model:
308
309* __karma_sequence__,
310* __karma_alternative__.
311
312__fixme__ Add more links to models of NaryGenerator concept
313
314[endsect] [/ NaryGenerator Concept]
315
316[/////////////////////////////////////////////////////////////////////////////]
317[section Nonterminal]
318
319[heading Description]
320
321A Nonterminal is a symbol in a __peg__ production that represents a
322grammar fragment. Nonterminals may self reference to specify recursion.
323This is one of the most important concepts and the reason behind the
324word "recursive" in recursive descent generation.
325
326[heading Refinement of]
327
328[:__generator_concept__]
329
330[heading Signature]
331
332Nonterminals can have both consumed and inherited attributes. The
333Nonterminal's /Signature/ specifies both the consumed and inherited
334attributes. The specification uses the function declarator syntax:
335
336    RT(A0, A1, A2, ..., AN)
337
338where `RT` is the Nonterminal's consumed attribute and `A0` ... `AN`
339are the Nonterminal's inherited attributes.
340
341The default value is `void()` (no consumed and inherited attributes).
342
343[heading Attributes]
344
345The Nonterminal models a C++ function. The Nonterminal's consumed attribute is
346analogous to the function return value as it is the type -exposed- by the
347Nonterminal. Its inherited attributes are analogous to function arguments.
348The inherited attributes (arguments) can be passed in just like any
349__karma_lazy_argument__, e.g.:
350
351    r(expr) // Evaluate expr at parse time and pass the result to the Nonterminal r
352
353[heading `_val`]
354
355The `boost::spirit::karma::_val` placeholder can be used in __phoenix__
356semantic actions anywhere in the Nonterminal's definition. This
357__phoenix__ placeholder refers to the Nonterminal's (consumed)
358attribute. The `_val` placeholder acts like an immutable reference to the
359Nonterminal's attribute.
360
361[note Starting with __spirit__ V2.5 (distributed with Boost V1.47) the
362      placeholder `_val` can be used in semantic actions attached to top level
363      generator components as well. See __generator_api__ for more information.]
364
365[heading `_r1`...`r10`]
366
367The `boost::spirit::_r1`...`boost::spirit::r10` placeholders can be used
368in __phoenix__ semantic actions anywhere in the Nonterminal's
369definition. These __phoenix__ placeholders refer to the Nonterminal's
370inherited attributes.
371
372[heading Locals]
373
374Nonterminals can have local variables that will be created on the stack
375at runtime. A locals descriptor added to the Nonterminal declaration
376will give the Nonterminal local variables:
377
378    template <typename T0, typename T1, typename T2, ..., typename TN>
379    struct locals;
380
381where `T0` ... `TN` are the types of local variables accessible in your
382__phoenix__ semantic actions using the placeholders:
383
384* `boost::spirit::_a`
385* `boost::spirit::_b`
386* `boost::spirit::_c`
387* `boost::spirit::_d`
388* `boost::spirit::_e`
389* `boost::spirit::_f`
390* `boost::spirit::_g`
391* `boost::spirit::_h`
392* `boost::spirit::_i`
393* `boost::spirit::_j`
394
395which correspond to the Nonterminal's local variables `T0` ... `T9`.
396
397[variablelist Notation
398    [[`x`]                          [A Nonterminal]]
399    [[`X`]                          [A Nonterminal type]]
400    [[`arg1`, `arg2`, ..., `argN`]  [__karma_lazy_arguments__ that evaluate to each of
401                                    the Nonterminal's inherited attributes.]]
402]
403
404[heading Valid Expressions]
405
406In addition to the requirements defined in __generator_concept__, for any
407Nonterminal the following must be met:
408
409[table
410    [[Expression]               [Semantics]                                         [Return type]]
411    [[`x`]                      [In a generator expression, invoke Nonterminal `x`] [`X`]]
412    [[`x(arg1, arg2, ..., argN)`][In a generator expression, invoke Nonterminal `x`
413                                passing in inherited attributes
414                                `arg1`...`argN`]                                    [`X`]]
415    [[`x.name(name)`]           [Set the name of a Nonterminal]                     [`void`]]
416    [[`x.name()`]               [Get the name of a Nonterminal]                     [`std::string`]]
417]
418
419[heading Type Expressions]
420
421[table
422    [[Expression]       [Description]]
423    [[`X::sig_type`]    [The Signature of `X`: In a function signature form
424                        as described above in the Signature paragraph.]]
425    [[`X::locals_type`] [The local variables of `X`: An __mpl_fwd_sequence__.]]
426]
427
428[heading Models]
429
430* __karma_rule__
431* __karma_grammar__
432
433[endsect]
434
435[endsect]
436