1[/============================================================================== 2 Copyright (C) 2001-2011 Hartmut Kaiser 3 Copyright (C) 2001-2011 Joel de Guzman 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:operator Generator Operators] 10 11Operators are used as a means for object composition and embedding. 12Simple generators may be composed to form composites through operator 13overloading, crafted to approximate the syntax of __peg__ (PEG). An 14expression such as: 15 16 a | b 17 18yields a new generator type which is a composite of its operands, `a` and 19`b`. 20 21This module includes different generators which get instantiated if one of the 22overloaded operators is used with more primitive generator constructs. It 23includes sequences (`a << b`), alternatives (`a | b`), Kleene star (unary `*`), 24plus (unary `+`), optional (unary `-`), lists (`a % b`), and the two predicates, the 25/and/ predicate (unary `&`) and the /not/ predicate (unary `!`). 26 27[heading Module Header] 28 29 // forwards to <boost/spirit/home/karma/operator.hpp> 30 #include <boost/spirit/include/karma_operator.hpp> 31 32Also, see __include_structure__. 33 34[/////////////////////////////////////////////////////////////////////////////] 35[section:sequence Sequence Generator (`a << b`)] 36 37[heading Description] 38 39Generator sequences are used to consecutively combine different, more primitive 40generators. All generators in a sequence are invoked from left to right as long 41as they succeed. 42 43[heading Header] 44 45 // forwards to <boost/spirit/home/karma/operator/sequence.hpp> 46 #include <boost/spirit/include/karma_sequence.hpp> 47 48Also, see __include_structure__. 49 50[heading Model of] 51 52[:__nary_generator_concept__] 53 54[heading Expression Semantics] 55 56Semantics of an expression is defined only where it differs from, or is not 57defined in __nary_generator_concept__. 58 59[table 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.]] 65] 66 67It is important to note, that sequences don't perform any buffering of the 68output generated by its elements. That means that any failing sequence might 69have already generated some output, which is /not/ rolled back. 70 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__): 73 74 ``buffer[a << b << c]`` 75 76 which will /not/ generate any output in case of a failing sequence.] 77 78[heading Attributes] 79 80See __karma_comp_attr_notation__. 81 82[table 83 [[Expression] [Attribute]] 84 [[`a << b` (sequence)] 85[``a: A, b: B --> (a << b): tuple<A, B> 86a: A, b: Unused --> (a << b): A 87a: Unused, b: B --> (a << b): B 88a: Unused, b: Unused --> (a << b): Unused 89 90a: A, b: A --> (a << b): vector<A> 91a: vector<A>, b: A --> (a << b): vector<A> 92a: A, b: vector<A> --> (a << b): vector<A> 93a: vector<A>, b: vector<A> --> (a << b): vector<A>``]] 94] 95 96[important The table above uses `tuple<A, B>` and `vector<A>` as placeholders 97 only. 98 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. 102 103 The notation of `vector<A>` stands for /any STL container/ holding 104 elements of type `A`.] 105 106The attribute composition and propagation rules as shown in the table above make 107sequences somewhat special as they can operate in two modes if all elements have 108the same attribute type: consuming fusion sequences and consuming STL 109containers. The selected mode depends on the type of the attribute supplied. 110 111[heading Complexity] 112 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.] 116 117[heading Example] 118 119[note The test harness for the example(s) below is presented in the 120 __karma_basics_examples__ section.] 121 122Some includes: 123 124[reference_karma_includes] 125 126Some using declarations: 127 128[reference_karma_using_declarations_sequence] 129 130Basic usage of a sequence: 131 132[reference_karma_sequence] 133 134[endsect] 135 136[/////////////////////////////////////////////////////////////////////////////] 137[section:alternative Alternative Generator (`a | b`)] 138 139[heading Description] 140 141Generator alternatives are used to combine different, more primitive generators 142into alternatives. All generators in an alternative are invoked from left to 143right until one of them succeeds. 144 145[heading Header] 146 147 // forwards to <boost/spirit/home/karma/operator/alternative.hpp> 148 #include <boost/spirit/include/karma_alternative.hpp> 149 150Also, see __include_structure__. 151 152[heading Model of] 153 154[:__nary_generator_concept__] 155 156[heading Expression Semantics] 157 158Semantics of an expression is defined only where it differs from, or is not 159defined in __nary_generator_concept__. 160 161[table 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.]] 170] 171 172Alternatives intercept and buffer the output of the currently executed element. 173This allows to avoid partial outputs from failing elements as the buffered 174content will be forwarded to the actual output only after an element succeeded. 175 176[heading Attributes] 177 178See __karma_comp_attr_notation__. 179 180[table 181 [[Expression] [Attribute]] 182 [[`a | b` (alternative)] 183[``a: A, b: B --> (a | b): variant<A, B> 184a: A, b: Unused --> (a | b): A 185a: Unused, b: B --> (a | b): B 186a: Unused, b: Unused --> (a | b): Unused 187a: A, b: A --> (a | b): A``]] 188] 189 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>`. 192] 193 194The attribute handling of Alternatives is special as their behavior is 195not completely defined at compile time. First of all the selected alternative 196element depends on the actual type of the attribute supplied to the alternative 197generator (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 199attribute wise. The remaining alternatives are tried sequentially until the 200first of them succeeds. See below for an example of this behavior. 201 202[heading Complexity] 203 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.] 207 208[heading Example] 209 210[note The test harness for the example(s) below is presented in the 211 __karma_basics_examples__ section.] 212 213Some includes: 214 215[reference_karma_includes] 216 217Some using declarations: 218 219[reference_karma_using_declarations_alternative] 220 221Basic usage of an alternative. While being only the second alternative, the 222`double_` generator is chosen for output formatting because the supplied 223attribute type is not compatible (i.e. not convertible) to the attribute type 224of the `string` alternative. 225 226[reference_karma_alternative1] 227 228The same formatting rules may be used to output a string. This time we supply 229the string `"example"`, resulting in the first alternative to be chosen for the 230generated output. 231 232[reference_karma_alternative2] 233 234[endsect] 235 236[/////////////////////////////////////////////////////////////////////////////] 237[section:kleene Kleene Star Generator (`*a`)] 238 239[heading Description] 240 241Kleene star generators are used to repeat the execution of an embedded generator 242zero or more times. Regardless of the success of the embedded generator, the 243Kleene star generator always succeeds. 244 245[heading Header] 246 247 // forwards to <boost/spirit/home/karma/operator/kleene.hpp> 248 #include <boost/spirit/include/karma_kleene.hpp> 249 250Also, see __include_structure__. 251 252[heading Model of] 253 254[:__unary_generator_concept__] 255 256[heading Expression Semantics] 257 258Semantics of an expression is defined only where it differs from, or is not 259defined in __unary_generator_concept__. 260 261[table 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).]] 269] 270 271[note All failing iterations of the embedded generator will consume one element 272 from the supplied attribute.] 273 274[heading Attributes] 275 276See __karma_comp_attr_notation__. 277 278[table 279 [[Expression] [Attribute]] 280 [[`*a` (Kleene star, unary `*`)] 281[``a: A --> *a: vector<A> 282a: Unused --> *a: Unused``]] 283] 284 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 287 type `A`.] 288 289The Kleene star generator will execute its embedded generator once for each 290element in the provided container attribute as long as the embedded 291generator succeeds. On each iteration it will pass the next consecutive element 292from the container attribute to the embedded generator. Therefore the number of 293iterations will not be larger than the number of elements in the container 294passed as its attribute. An empty container will make the Kleene star 295generate no output at all. 296 297It is important to note, that the Kleene star does not perform any buffering 298of the output generated by its embedded elements. That means that any failing 299element generator might have already generated some output, which is /not/ 300rolled back. 301 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 304 __karma_buffer__): 305 306 ``buffer[*a]`` 307 308 which will /not/ generate any output in case of a failing generator `*a`. 309 The expression: 310 311 ``*(buffer[a])`` 312 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 316 the generator `a`.] 317 318[heading Complexity] 319 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.] 324 325[heading Example] 326 327[note The test harness for the example(s) below is presented in the 328 __karma_basics_examples__ section.] 329 330Some includes: 331 332[reference_karma_includes] 333 334Some using declarations: 335 336[reference_karma_using_declarations_kleene] 337 338Basic usage of a Kleene star generator: 339 340[reference_karma_kleene] 341 342[endsect] 343 344[/////////////////////////////////////////////////////////////////////////////] 345[section:plus Plus Generator (`+a`)] 346 347[heading Description] 348 349The Plus generator is used to repeat the execution of an embedded generator 350one or more times. It succeeds if the embedded generator has been successfully 351executed at least once. 352 353[heading Header] 354 355 // forwards to <boost/spirit/home/karma/operator/plus.hpp> 356 #include <boost/spirit/include/karma_plus.hpp> 357 358Also, see __include_structure__. 359 360[heading Model of] 361 362[:__unary_generator_concept__] 363 364[heading Expression Semantics] 365 366Semantics of an expression is defined only where it differs from, or is not 367defined in __unary_generator_concept__. 368 369[table 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 378 error).]] 379] 380 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).] 385 386[heading Attributes] 387 388See __karma_comp_attr_notation__. 389 390[table 391 [[Expression] [Attribute]] 392 [[`+a` (unary `+`)] 393[``a: A --> +a: vector<A> 394a: Unused --> +a: Unused``]] 395] 396 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 399 type `A`.] 400 401The Plus generator will execute its embedded generator once for each 402element in the provided container attribute as long as the embedded 403generator succeeds. On each iteration it will pass the next consecutive element 404from the container attribute to the embedded generator. Therefore the number of 405iterations will not be larger than the number of elements in the container 406passed as its attribute. An empty container will make the plus generator fail. 407 408It is important to note, that the plus generator does not perform any buffering 409of the output generated by its embedded elements. That means that any failing 410element generator might have already generated some output, which is /not/ 411rolled back. 412 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 415 __karma_buffer__): 416 417 ``buffer[+a]`` 418 419 which will /not/ generate any output in case of a failing generator `+a`. 420 The expression: 421 422 ``+(buffer[a])`` 423 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 427 the generator `a`.] 428 429[heading Complexity] 430 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.] 435 436[heading Example] 437 438[note The test harness for the example(s) below is presented in the 439 __karma_basics_examples__ section.] 440 441Some includes: 442 443[reference_karma_includes] 444 445Some using declarations: 446 447[reference_karma_using_declarations_plus] 448 449Basic usage of a plus generator: 450 451[reference_karma_plus1] 452 453A more sophisticated use case showing how to leverage the fact that plus is 454failing for empty containers passed as its attribute: 455 456[reference_karma_plus2] 457 458[endsect] 459 460[/////////////////////////////////////////////////////////////////////////////] 461[section:list List Generator (`a % b`)] 462 463[heading Description] 464 465The list generator is used to repeat the execution of an embedded generator 466and intersperse it with the output of another generator one or more times. 467It succeeds if the embedded generator has been successfully executed at least 468once. 469 470[heading Header] 471 472 // forwards to <boost/spirit/home/karma/operator/list.hpp> 473 #include <boost/spirit/include/karma_list.hpp> 474 475Also, see __include_structure__. 476 477[heading Model of] 478 479[:__binary_generator_concept__] 480 481[heading Expression Semantics] 482 483Semantics of an expression is defined only where it differs from, or is not 484defined in __binary_generator_concept__. 485 486[table 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).]] 495] 496 497The list expression `a % b` is a shortcut for `a << *(b << a)`. It is almost 498semantically equivalent, except for the attribute of `b`, which gets ignored 499in the case of the list generator. 500 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).] 505 506[heading Attributes] 507 508See __karma_comp_attr_notation__. 509 510[table 511 [[Expression] [Attribute]] 512 [[`a % b` (list)] 513[``a: A, b: B --> (a % b): vector<A> 514a: Unused, b: B --> (a % b): Unused``]] 515] 516 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 519 type `A`.] 520 521The list generator will execute its embedded generator once for each 522element in the provided container attribute and as long as the embedded 523generator succeeds. The output generated by its first generator will be 524interspersed by the output generated by the second generator. On each iteration 525it will pass the next consecutive element from the container attribute to the 526first embedded generator. The second embedded generator does not get passed 527any attributes (it gets invoked using an `unused_type` as its attribute). 528Therefore the number of iterations will not be larger than the number of 529elements in the container passed as its attribute. An empty container will make 530the list generator fail. 531 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__): 534 535 ``-(a % b)`` 536 537 which will succeed even if the provided container attribute does not 538 contain any elements. 539] 540 541[heading Complexity] 542 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.] 547 548[heading Example] 549 550[note The test harness for the example(s) below is presented in the 551 __karma_basics_examples__ section.] 552 553Some includes: 554 555[reference_karma_includes] 556 557Some using declarations: 558 559[reference_karma_using_declarations_list] 560 561Basic usage of a list generator: 562 563[reference_karma_list] 564 565[endsect] 566 567[/////////////////////////////////////////////////////////////////////////////] 568[section:optional Optional Generator (`-a`)] 569 570[heading Description] 571 572The optional generator is used to conditionally execute an embedded generator. 573It succeeds always. 574 575[heading Header] 576 577 // forwards to <boost/spirit/home/karma/operator/optional.hpp> 578 #include <boost/spirit/include/karma_optional.hpp> 579 580Also, see __include_structure__. 581 582[heading Model of] 583 584[:__unary_generator_concept__] 585 586[heading Expression Semantics] 587 588Semantics of an expression is defined only where it differs from, or is not 589defined in __unary_generator_concept__. 590 591[table 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 597 error).]] 598] 599 600[heading Attributes] 601 602See __karma_comp_attr_notation__. 603 604[table 605 [[Expression] [Attribute]] 606 [[`-a` (optional, unary `-`)] 607[``a: A --> -a: optional<A> 608a: Unused --> -a: Unused``]] 609] 610 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>`.] 614 615The optional generator will execute its embedded generator once if the provided 616attribute holds a valid value. It forwards the value held in its attribute 617to the embedded generator. 618 619It is important to note, that the optional generator does not perform any 620buffering of the output generated by its embedded elements. That means that any 621failing element might have already generated some output, which is /not/ 622rolled back. 623 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 626 __karma_buffer__): 627 628 ``buffer[-a]`` 629 630 which will /not/ generate any output in case of a failing generator `-a`. 631] 632 633[heading Complexity] 634 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).] 638 639[heading Example] 640 641[note The test harness for the example(s) below is presented in the 642 __karma_basics_examples__ section.] 643 644Some includes: 645 646[reference_karma_includes] 647 648Some using declarations: 649 650[reference_karma_using_declarations_optional] 651 652Basic usage of an optional generator: 653 654[reference_karma_optional1] 655 656Usage and result of an empty optional generator: 657 658[reference_karma_optional2] 659 660[endsect] 661 662[/////////////////////////////////////////////////////////////////////////////] 663[section:and_predicate And-Predicate Generator (`&a`)] 664 665[heading Description] 666 667The and-predicate generator is used to test, whether the embedded generator 668succeeds without generating any output. It succeeds if the embedded generator 669succeeds. 670 671[heading Header] 672 673 // forwards to <boost/spirit/home/karma/operator/and_predicate.hpp> 674 #include <boost/spirit/include/karma_and_predicate.hpp> 675 676Also, see __include_structure__. 677 678[heading Model of] 679 680[:__unary_generator_concept__] 681 682[heading Expression Semantics] 683 684Semantics of an expression is defined only where it differs from, or is not 685defined in __unary_generator_concept__. 686 687[table 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 694 any output.]] 695] 696 697The and generator is implemented by redirecting all output produced by its 698embedded generator into a discarding device. 699 700[heading Attributes] 701 702See __karma_comp_attr_notation__. 703 704[table 705 [[Expression] [Attribute]] 706 [[`&a` (and-predicate, unary `&`)] [`a: A --> &a: A`]] 707] 708 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. 712] 713 714[heading Complexity] 715 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).] 719 720[heading Example] 721 722[note The test harness for the example(s) below is presented in the 723 __karma_basics_examples__ section.] 724 725Some includes: 726 727[reference_karma_includes] 728 729Some using declarations: 730 731[reference_karma_using_declarations_and_predicate] 732 733Basic usage of an and predicate generator: 734 735[reference_karma_and_predicate] 736 737[endsect] 738 739[/////////////////////////////////////////////////////////////////////////////] 740[section:not_predicate Not-Predicate Generator (`!a`)] 741 742[heading Description] 743 744The not-predicate generator is used to test, whether the embedded generator 745fails, without generating any output. It succeeds if the embedded generator 746fails. 747 748[heading Header] 749 750 // forwards to <boost/spirit/home/karma/operator/not_predicate.hpp> 751 #include <boost/spirit/include/karma_not_predicate.hpp> 752 753Also, see __include_structure__. 754 755[heading Model of] 756 757[:__unary_generator_concept__] 758 759[heading Expression Semantics] 760 761Semantics of an expression is defined only where it differs from, or is not 762defined in __unary_generator_concept__. 763 764[table 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 771 any output.]] 772] 773 774The not generator is implemented by redirecting all output produced by its 775embedded generator into a discarding device. 776 777[heading Attributes] 778 779See __karma_comp_attr_notation__. 780 781[table 782 [[Expression] [Attribute]] 783 [[`!a` (not-predicate, unary `!`)] [`a: A --> !a: A`]] 784] 785 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. 789] 790 791[heading Complexity] 792 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).] 796 797[heading Example] 798 799[note The test harness for the example(s) below is presented in the 800 __karma_basics_examples__ section.] 801 802Some includes: 803 804[reference_karma_includes] 805 806Some using declarations: 807 808[reference_karma_using_declarations_not_predicate] 809 810Basic usage of a not predicate generator: 811 812[reference_karma_not_predicate] 813 814[endsect] 815 816[endsect] 817