1 [/==============================================================================
2 Copyright (C) 2001-2011 Hartmut Kaiser
3 Copyright (C) 2001-2011 Joel de Guzman
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:operator Generator Operators]
11 Operators are used as a means for object composition and embedding.
12 Simple generators may be composed to form composites through operator
13 overloading, crafted to approximate the syntax of __peg__ (PEG). An
18 yields a new generator type which is a composite of its operands, `a` and
21 This module includes different generators which get instantiated if one of the
22 overloaded operators is used with more primitive generator constructs. It
23 includes sequences (`a << b`), alternatives (`a | b`), Kleene star (unary `*`),
24 plus (unary `+`), optional (unary `-`), lists (`a % b`), and the two predicates, the
25 /and/ predicate (unary `&`) and the /not/ predicate (unary `!`).
27 [heading Module Header]
29 // forwards to <boost/spirit/home/karma/operator.hpp>
30 #include <boost/spirit/include/karma_operator.hpp>
32 Also, see __include_structure__.
34 [/////////////////////////////////////////////////////////////////////////////]
35 [section:sequence Sequence Generator (`a << b`)]
39 Generator sequences are used to consecutively combine different, more primitive
40 generators. All generators in a sequence are invoked from left to right as long
45 // forwards to <boost/spirit/home/karma/operator/sequence.hpp>
46 #include <boost/spirit/include/karma_sequence.hpp>
48 Also, see __include_structure__.
52 [:__nary_generator_concept__]
54 [heading Expression Semantics]
56 Semantics of an expression is defined only where it differs from, or is not
57 defined in __nary_generator_concept__.
60 [[Expression] [Semantics]]
61 [[`a << b`] [The generators `a` and `b` are executed sequentially
62 from left to right and as long as they succeed. A
63 failed generator stops the execution of the entire
64 sequence and makes the sequence fail as well.]]
67 It is important to note, that sequences don't perform any buffering of the
68 output generated by its elements. That means that any failing sequence might
69 have already generated some output, which is /not/ rolled back.
71 [tip The simplest way to force a sequence to behave as if it did buffering
72 is to wrap it into a buffering directive (see __karma_buffer__):
74 ``buffer[a << b << c]``
76 which will /not/ generate any output in case of a failing sequence.]
80 See __karma_comp_attr_notation__.
83 [[Expression] [Attribute]]
84 [[`a << b` (sequence)]
85 [``a: A, b: B --> (a << b): tuple<A, B>
86 a: A, b: Unused --> (a << b): A
87 a: Unused, b: B --> (a << b): B
88 a: Unused, b: Unused --> (a << b): Unused
90 a: A, b: A --> (a << b): vector<A>
91 a: vector<A>, b: A --> (a << b): vector<A>
92 a: A, b: vector<A> --> (a << b): vector<A>
93 a: vector<A>, b: vector<A> --> (a << b): vector<A>``]]
96 [important The table above uses `tuple<A, B>` and `vector<A>` as placeholders
99 The notation `tuple<A, B>` stands for /any fusion sequence of two
100 elements/, where `A` is the type of its first element and `B` is the
101 type of its second element.
103 The notation of `vector<A>` stands for /any STL container/ holding
104 elements of type `A`.]
106 The attribute composition and propagation rules as shown in the table above make
107 sequences somewhat special as they can operate in two modes if all elements have
108 the same attribute type: consuming fusion sequences and consuming STL
109 containers. The selected mode depends on the type of the attribute supplied.
113 [:The overall complexity of the sequence generator is defined by the sum of the
114 complexities of its elements. The complexity of the sequence itself is O(N),
115 where N is the number of elements in the sequence.]
119 [note The test harness for the example(s) below is presented in the
120 __karma_basics_examples__ section.]
124 [reference_karma_includes]
126 Some using declarations:
128 [reference_karma_using_declarations_sequence]
130 Basic usage of a sequence:
132 [reference_karma_sequence]
136 [/////////////////////////////////////////////////////////////////////////////]
137 [section:alternative Alternative Generator (`a | b`)]
139 [heading Description]
141 Generator alternatives are used to combine different, more primitive generators
142 into alternatives. All generators in an alternative are invoked from left to
143 right until one of them succeeds.
147 // forwards to <boost/spirit/home/karma/operator/alternative.hpp>
148 #include <boost/spirit/include/karma_alternative.hpp>
150 Also, see __include_structure__.
154 [:__nary_generator_concept__]
156 [heading Expression Semantics]
158 Semantics of an expression is defined only where it differs from, or is not
159 defined in __nary_generator_concept__.
162 [[Expression] [Semantics]]
163 [[`a | b`] [The generators `a` and `b` are executed sequentially
164 from left to right until one of them succeeds. A
165 failed generator forces the alternative generator to
166 try the next one. The alternative fails as a whole
167 only if all elements of the alternative fail. Each
168 element of the alternative gets passed the whole
169 attribute of the alternative.]]
172 Alternatives intercept and buffer the output of the currently executed element.
173 This allows to avoid partial outputs from failing elements as the buffered
174 content will be forwarded to the actual output only after an element succeeded.
178 See __karma_comp_attr_notation__.
181 [[Expression] [Attribute]]
182 [[`a | b` (alternative)]
183 [``a: A, b: B --> (a | b): variant<A, B>
184 a: A, b: Unused --> (a | b): A
185 a: Unused, b: B --> (a | b): B
186 a: Unused, b: Unused --> (a | b): Unused
187 a: A, b: A --> (a | b): A``]]
190 [important The table above uses `variant<A, B>` as a placeholder only. The
191 notation `variant<A, B>` stands for the type `boost::variant<A, B>`.
194 The attribute handling of Alternatives is special as their behavior is
195 not completely defined at compile time. First of all the selected alternative
196 element depends on the actual type of the attribute supplied to the alternative
197 generator (i.e. what is stored in the variant). The attribute type supplied at
198 /runtime/ narrows the set of considered alternatives to those being compatible
199 attribute wise. The remaining alternatives are tried sequentially until the
200 first of them succeeds. See below for an example of this behavior.
204 [:The overall complexity of the alternative generator is defined by the sum of
205 the complexities of its elements. The complexity of the alternative itself is
206 O(N), where N is the number of elements in the alternative.]
210 [note The test harness for the example(s) below is presented in the
211 __karma_basics_examples__ section.]
215 [reference_karma_includes]
217 Some using declarations:
219 [reference_karma_using_declarations_alternative]
221 Basic usage of an alternative. While being only the second alternative, the
222 `double_` generator is chosen for output formatting because the supplied
223 attribute type is not compatible (i.e. not convertible) to the attribute type
224 of the `string` alternative.
226 [reference_karma_alternative1]
228 The same formatting rules may be used to output a string. This time we supply
229 the string `"example"`, resulting in the first alternative to be chosen for the
232 [reference_karma_alternative2]
236 [/////////////////////////////////////////////////////////////////////////////]
237 [section:kleene Kleene Star Generator (`*a`)]
239 [heading Description]
241 Kleene star generators are used to repeat the execution of an embedded generator
242 zero or more times. Regardless of the success of the embedded generator, the
243 Kleene star generator always succeeds.
247 // forwards to <boost/spirit/home/karma/operator/kleene.hpp>
248 #include <boost/spirit/include/karma_kleene.hpp>
250 Also, see __include_structure__.
254 [:__unary_generator_concept__]
256 [heading Expression Semantics]
258 Semantics of an expression is defined only where it differs from, or is not
259 defined in __unary_generator_concept__.
262 [[Expression] [Semantics]]
263 [[`*a`] [The generator `a` is executed zero or more times
264 depending on the availability of an attribute. The
265 execution of `a` stops after the attribute values
266 passed to the Kleene star generator are exhausted.
267 The Kleene star always succeeds (unless the
268 underlying output stream reports an error).]]
271 [note All failing iterations of the embedded generator will consume one element
272 from the supplied attribute.]
276 See __karma_comp_attr_notation__.
279 [[Expression] [Attribute]]
280 [[`*a` (Kleene star, unary `*`)]
281 [``a: A --> *a: vector<A>
282 a: Unused --> *a: Unused``]]
285 [important The table above uses `vector<A>` as a placeholder only. The notation
286 of `vector<A>` stands for /any STL container/ holding elements of
289 The Kleene star generator will execute its embedded generator once for each
290 element in the provided container attribute as long as the embedded
291 generator succeeds. On each iteration it will pass the next consecutive element
292 from the container attribute to the embedded generator. Therefore the number of
293 iterations will not be larger than the number of elements in the container
294 passed as its attribute. An empty container will make the Kleene star
295 generate no output at all.
297 It is important to note, that the Kleene star does not perform any buffering
298 of the output generated by its embedded elements. That means that any failing
299 element generator might have already generated some output, which is /not/
302 [tip The simplest way to force a Kleene star to behave as if it did
303 buffering is to wrap it into a buffering directive (see
308 which will /not/ generate any output in case of a failing generator `*a`.
313 will not generate any partial output from a generator `a` if it fails
314 generating in the middle of its output. The overall expression will
315 still generate the output as produced by all successful invocations of
320 [:The overall complexity of the Kleene star generator is defined by the
321 complexity of its embedded generator multiplied by the number of executed
322 iterations. The complexity of the Kleene star itself is O(N), where N is the
323 number of elements in the container passed as its attribute.]
327 [note The test harness for the example(s) below is presented in the
328 __karma_basics_examples__ section.]
332 [reference_karma_includes]
334 Some using declarations:
336 [reference_karma_using_declarations_kleene]
338 Basic usage of a Kleene star generator:
340 [reference_karma_kleene]
344 [/////////////////////////////////////////////////////////////////////////////]
345 [section:plus Plus Generator (`+a`)]
347 [heading Description]
349 The Plus generator is used to repeat the execution of an embedded generator
350 one or more times. It succeeds if the embedded generator has been successfully
351 executed at least once.
355 // forwards to <boost/spirit/home/karma/operator/plus.hpp>
356 #include <boost/spirit/include/karma_plus.hpp>
358 Also, see __include_structure__.
362 [:__unary_generator_concept__]
364 [heading Expression Semantics]
366 Semantics of an expression is defined only where it differs from, or is not
367 defined in __unary_generator_concept__.
370 [[Expression] [Semantics]]
371 [[`+a`] [The generator `a` is executed one or more times
372 depending on the availability of an attribute. The
373 execution of `a` stops after the attribute values
374 passed to the plus generator are exhausted.
375 The plus generator succeeds as long as its embedded
376 generator has been successfully executed at least once
377 (unless the underlying output stream reports an
381 [note All failing iterations of the embedded generator will consume one element
382 from the supplied attribute. The overall `+a` will succeed as long as at
383 least one invocation of the embedded generator will succeed (unless the
384 underlying output stream reports an error).]
388 See __karma_comp_attr_notation__.
391 [[Expression] [Attribute]]
393 [``a: A --> +a: vector<A>
394 a: Unused --> +a: Unused``]]
397 [important The table above uses `vector<A>` as a placeholder only. The notation
398 of `vector<A>` stands for /any STL container/ holding elements of
401 The Plus generator will execute its embedded generator once for each
402 element in the provided container attribute as long as the embedded
403 generator succeeds. On each iteration it will pass the next consecutive element
404 from the container attribute to the embedded generator. Therefore the number of
405 iterations will not be larger than the number of elements in the container
406 passed as its attribute. An empty container will make the plus generator fail.
408 It is important to note, that the plus generator does not perform any buffering
409 of the output generated by its embedded elements. That means that any failing
410 element generator might have already generated some output, which is /not/
413 [tip The simplest way to force a plus generator to behave as if it did
414 buffering is to wrap it into a buffering directive (see
419 which will /not/ generate any output in case of a failing generator `+a`.
424 will not generate any partial output from a generator `a` if it fails
425 generating in the middle of its output. The overall expression will
426 still generate the output as produced by all successful invocations of
431 [:The overall complexity of the plus generator is defined by the
432 complexity of its embedded generator multiplied by the number of executed
433 iterations. The complexity of the plus generator itself is O(N), where N is
434 the number of elements in the container passed as its attribute.]
438 [note The test harness for the example(s) below is presented in the
439 __karma_basics_examples__ section.]
443 [reference_karma_includes]
445 Some using declarations:
447 [reference_karma_using_declarations_plus]
449 Basic usage of a plus generator:
451 [reference_karma_plus1]
453 A more sophisticated use case showing how to leverage the fact that plus is
454 failing for empty containers passed as its attribute:
456 [reference_karma_plus2]
460 [/////////////////////////////////////////////////////////////////////////////]
461 [section:list List Generator (`a % b`)]
463 [heading Description]
465 The list generator is used to repeat the execution of an embedded generator
466 and intersperse it with the output of another generator one or more times.
467 It succeeds if the embedded generator has been successfully executed at least
472 // forwards to <boost/spirit/home/karma/operator/list.hpp>
473 #include <boost/spirit/include/karma_list.hpp>
475 Also, see __include_structure__.
479 [:__binary_generator_concept__]
481 [heading Expression Semantics]
483 Semantics of an expression is defined only where it differs from, or is not
484 defined in __binary_generator_concept__.
487 [[Expression] [Semantics]]
488 [[`a % b`] [The generator `a` is executed one or more times
489 depending on the availability of an attribute. The
490 output generated by `a` is interspersed with the output
491 generated by `b`. The list generator succeeds if
492 its first embedded generator has been
493 successfully executed at least once (unless the
494 underlying output stream reports an error).]]
497 The list expression `a % b` is a shortcut for `a << *(b << a)`. It is almost
498 semantically equivalent, except for the attribute of `b`, which gets ignored
499 in the case of the list generator.
501 [note All failing iterations of the embedded generator will consume one element
502 from the supplied attribute. The overall `a % b` will succeed as long as at
503 least one invocation of the embedded generator, `a`, will succeed (unless
504 the underlying output stream reports an error).]
508 See __karma_comp_attr_notation__.
511 [[Expression] [Attribute]]
513 [``a: A, b: B --> (a % b): vector<A>
514 a: Unused, b: B --> (a % b): Unused``]]
517 [important The table above uses `vector<A>` as a placeholder only. The notation
518 of `vector<A>` stands for /any STL container/ holding elements of
521 The list generator will execute its embedded generator once for each
522 element in the provided container attribute and as long as the embedded
523 generator succeeds. The output generated by its first generator will be
524 interspersed by the output generated by the second generator. On each iteration
525 it will pass the next consecutive element from the container attribute to the
526 first embedded generator. The second embedded generator does not get passed
527 any attributes (it gets invoked using an `unused_type` as its attribute).
528 Therefore the number of iterations will not be larger than the number of
529 elements in the container passed as its attribute. An empty container will make
530 the list generator fail.
532 [tip If you want to use the list generator and still allow for an empty
533 attribute, you can use the optional operator (see __karma_optional__):
537 which will succeed even if the provided container attribute does not
538 contain any elements.
543 [:The overall complexity of the list generator is defined by the
544 complexity of its embedded generators multiplied by the number of executed
545 iterations. The complexity of the list generator itself is O(N), where N is
546 the number of elements in the container passed as its attribute.]
550 [note The test harness for the example(s) below is presented in the
551 __karma_basics_examples__ section.]
555 [reference_karma_includes]
557 Some using declarations:
559 [reference_karma_using_declarations_list]
561 Basic usage of a list generator:
563 [reference_karma_list]
567 [/////////////////////////////////////////////////////////////////////////////]
568 [section:optional Optional Generator (`-a`)]
570 [heading Description]
572 The optional generator is used to conditionally execute an embedded generator.
577 // forwards to <boost/spirit/home/karma/operator/optional.hpp>
578 #include <boost/spirit/include/karma_optional.hpp>
580 Also, see __include_structure__.
584 [:__unary_generator_concept__]
586 [heading Expression Semantics]
588 Semantics of an expression is defined only where it differs from, or is not
589 defined in __unary_generator_concept__.
592 [[Expression] [Semantics]]
593 [[`-a`] [The generator `a` is executed depending on the
594 availability of an attribute. The optional generator
595 succeeds if its embedded generator succeeds
596 (unless the underlying output stream reports an
602 See __karma_comp_attr_notation__.
605 [[Expression] [Attribute]]
606 [[`-a` (optional, unary `-`)]
607 [``a: A --> -a: optional<A>
608 a: Unused --> -a: Unused``]]
611 [important The table above uses `optional<A>` as a placeholder only. The
612 notation of `optional<A>` stands for the data type
613 `boost::optional<A>`.]
615 The optional generator will execute its embedded generator once if the provided
616 attribute holds a valid value. It forwards the value held in its attribute
617 to the embedded generator.
619 It is important to note, that the optional generator does not perform any
620 buffering of the output generated by its embedded elements. That means that any
621 failing element might have already generated some output, which is /not/
624 [tip The simplest way to force a optional generator to behave as if it did
625 buffering is to wrap it into a buffering directive (see
630 which will /not/ generate any output in case of a failing generator `-a`.
635 [:The overall complexity of the optional generator is defined by the
636 complexity of its embedded generator. The complexity of the optional
637 generator itself is O(1).]
641 [note The test harness for the example(s) below is presented in the
642 __karma_basics_examples__ section.]
646 [reference_karma_includes]
648 Some using declarations:
650 [reference_karma_using_declarations_optional]
652 Basic usage of an optional generator:
654 [reference_karma_optional1]
656 Usage and result of an empty optional generator:
658 [reference_karma_optional2]
662 [/////////////////////////////////////////////////////////////////////////////]
663 [section:and_predicate And-Predicate Generator (`&a`)]
665 [heading Description]
667 The and-predicate generator is used to test, whether the embedded generator
668 succeeds without generating any output. It succeeds if the embedded generator
673 // forwards to <boost/spirit/home/karma/operator/and_predicate.hpp>
674 #include <boost/spirit/include/karma_and_predicate.hpp>
676 Also, see __include_structure__.
680 [:__unary_generator_concept__]
682 [heading Expression Semantics]
684 Semantics of an expression is defined only where it differs from, or is not
685 defined in __unary_generator_concept__.
688 [[Expression] [Semantics]]
689 [[`&a`] [The generator `a` is executed for the sole purpose of
690 testing whether it succeeds. The and-predicate
691 generator succeeds if its embedded generator
692 succeeds (unless the underlying output stream
693 reports an error). The and-predicate never produces
697 The and generator is implemented by redirecting all output produced by its
698 embedded generator into a discarding device.
702 See __karma_comp_attr_notation__.
705 [[Expression] [Attribute]]
706 [[`&a` (and-predicate, unary `&`)] [`a: A --> &a: A`]]
709 [note The attribute of the and-predicate is not always `unused_type`, which is
710 different from Qi's and-predicate. This is necessary as the generator the
711 and predicate is attached to most of the time needs an attribute.
716 [:The overall complexity of the and-predicate generator is defined by the
717 complexity of its embedded generator. The complexity of the and-predicate
718 generator itself is O(1).]
722 [note The test harness for the example(s) below is presented in the
723 __karma_basics_examples__ section.]
727 [reference_karma_includes]
729 Some using declarations:
731 [reference_karma_using_declarations_and_predicate]
733 Basic usage of an and predicate generator:
735 [reference_karma_and_predicate]
739 [/////////////////////////////////////////////////////////////////////////////]
740 [section:not_predicate Not-Predicate Generator (`!a`)]
742 [heading Description]
744 The not-predicate generator is used to test, whether the embedded generator
745 fails, without generating any output. It succeeds if the embedded generator
750 // forwards to <boost/spirit/home/karma/operator/not_predicate.hpp>
751 #include <boost/spirit/include/karma_not_predicate.hpp>
753 Also, see __include_structure__.
757 [:__unary_generator_concept__]
759 [heading Expression Semantics]
761 Semantics of an expression is defined only where it differs from, or is not
762 defined in __unary_generator_concept__.
765 [[Expression] [Semantics]]
766 [[`!a`] [The generator `a` is executed for the sole purpose of
767 testing whether it succeeds. The not-predicate
768 generator succeeds if its embedded generator
769 fails (unless the underlying output stream
770 reports an error). The not-predicate never produces
774 The not generator is implemented by redirecting all output produced by its
775 embedded generator into a discarding device.
779 See __karma_comp_attr_notation__.
782 [[Expression] [Attribute]]
783 [[`!a` (not-predicate, unary `!`)] [`a: A --> !a: A`]]
786 [note The attribute of the not-predicate is not always `unused_type`, which is
787 different from Qi's not-predicate. This is necessary as the generator the
788 and-predicate is attached to most of the time needs an attribute.
793 [:The overall complexity of the not-predicate generator is defined by the
794 complexity of its embedded generator. The complexity of the not-predicate
795 generator itself is O(1).]
799 [note The test harness for the example(s) below is presented in the
800 __karma_basics_examples__ section.]
804 [reference_karma_includes]
806 Some using declarations:
808 [reference_karma_using_declarations_not_predicate]
810 Basic usage of a not predicate generator:
812 [reference_karma_not_predicate]