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