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
9This quick reference section is provided for convenience. You can use
10this section as a sort of a "cheat-sheet" on the most commonly used Qi
11components. It is not intended to be complete, but should give you an
12easy way to recall a particular component without having to dig up on
13pages and pages of reference documentation.
14
15[section Common Notation]
16
17[variablelist Notation
18    [[`P`]              [Parser type]]
19    [[`p, a, b, c`]     [Parser objects]]
20    [[`A, B, C`]        [Attribute types of parsers `a`, `b` and `c`]]
21    [[`I`]              [The iterator type used for parsing]]
22    [[`Unused`]         [An `unused_type`]]
23    [[`Context`]        [The enclosing rule's `Context` type]]
24    [[`attrib`]         [An attribute value]]
25    [[`Attrib`]         [An attribute type]]
26    [[`b`]              [A boolean expression]]
27    [[`fp`]             [A (lazy parser) function with signature `P(Unused, Context)`]]
28    [[`fa`]             [A (semantic action) function with signature `void(Attrib, Context, bool&)`.
29                        The third parameter is a boolean flag that can be set to false to
30                        force the parse to fail. Both `Context` and the boolean flag are
31                        optional.]]
32    [[`first`]          [An iterator pointing to the start of input]]
33    [[`last`]           [An iterator pointing to the end of input]]
34    [[`Ch`]             [Character-class specific character type (See __char_class_types__)]]
35    [[`ch`]             [Character-class specific character (See __char_class_types__)]]
36    [[`ch2`]            [Character-class specific character (See __char_class_types__)]]
37    [[`charset`]        [Character-set specifier string (example: "a-z0-9")]]
38    [[`str`]            [Character-class specific string (See __char_class_types__)]]
39    [[`Str`]            [Attribute of `str`: `std::basic_string<T>` where `T` is the underlying character type of `str`]]
40    [[`tuple<>`]        [Used as a placeholder for a fusion sequence]]
41    [[`vector<>`]       [Used as a placeholder for an STL container]]
42    [[`variant<>`]      [Used as a placeholder for a boost::variant]]
43    [[`optional<>`]     [Used as a placeholder for a boost::optional]]
44]
45
46[endsect]
47[section:qi_parsers Qi Parsers]
48
49[section:char Character Parsers]
50
51[table
52    [[Expression]                [Attribute]       [Description]]
53    [[[qi_char `ch`]]            [`Unused`]        [Matches `ch`]]
54    [[[qi_char `lit(ch)`]]       [`Unused`]        [Matches `ch`]]
55    [[[qi_char `char_`]]         [`Ch`]            [Matches any character]]
56    [[[qi_char `char_(ch)`]]     [`Ch`]            [Matches `ch`]]
57    [[[qi_char `char_("c")`]]    [`Ch`]            [Matches a single char string literal, `c`]]
58    [[[qi_char `char_(ch, ch2)`]][`Ch`]            [Matches a range of chars from `ch` to `ch2` (inclusive)]]
59    [[[qi_char `char_(charset)`]][`Ch`]            [Matches a character set `charset`]]
60
61    [[[qi_char_class `alnum`]]   [`Ch`]            [Matches a character based on the equivalent of
62                                   `std::isalnum` in the current character set]]
63    [[[qi_char_class `alpha`]]   [`Ch`]            [Matches a character based on the equivalent of
64                                   `std::isalpha` in the current character set]]
65    [[[qi_char_class `blank`]]   [`Ch`]            [Matches a character based on the equivalent of
66                                   `std::isblank` in the current character set]]
67    [[[qi_char_class `cntrl`]]   [`Ch`]            [Matches a character based on the equivalent of
68                                   `std::iscntrl` in the current character set]]
69    [[[qi_char_class `digit`]]   [`Ch`]            [Matches a character based on the equivalent of
70                                   `std::isdigit` in the current character set]]
71    [[[qi_char_class `graph`]]   [`Ch`]            [Matches a character based on the equivalent of
72                                   `std::isgraph` in the current character set]]
73    [[[qi_char_class `print`]]   [`Ch`]            [Matches a character based on the equivalent of
74                                   `std::isprint` in the current character set]]
75    [[[qi_char_class `punct`]]   [`Ch`]            [Matches a character based on the equivalent of
76                                   `std::ispunct` in the current character set]]
77    [[[qi_char_class `space`]]   [`Ch`]            [Matches a character based on the equivalent of
78                                   `std::isspace` in the current character set]]
79    [[[qi_char_class `xdigit`]]  [`Ch`]            [Matches a character based on the equivalent of
80                                   `std::isxdigit` in the current character set]]
81    [[[qi_char_class `lower`]]   [`Ch`]            [Matches a character based on the equivalent of
82                                   `std::islower` in the current character set]]
83    [[[qi_char_class `upper`]]   [`Ch`]            [Matches a character based on the equivalent of
84                                   `std::isupper` in the current character set]]
85]
86
87[endsect]
88[section:numeric Numeric Parsers]
89
90[table
91    [[Expression]                 [Attribute]           [Description]]
92    [[[qi_real_number `float_`]]  [`float`]             [Parse a floating point number into a `float`]]
93    [[[qi_real_number `float_(num)`]]  [`float`]        [Parse a floating point number into a `float`,
94                                                            a number is matched only if it's `num`]]
95    [[[qi_real_number `double_`]] [`double`]            [Parse a floating point number into a `double`]]
96    [[[qi_real_number `double_(num)`]] [`double`]            [Parse a floating point number into a `double`,
97                                                            a number is matched only if it's `num`]]
98    [[[qi_real_number `long_double`]] [`long double`]   [Parse a floating point number into a `long double`]]
99    [[[qi_real_number `long_double(num)`]] [`long double`]   [Parse a floating point number into a `long double`,
100                                                            a number is matched only if it's `num`]]
101
102    [[[qi_unsigned_int `bin`]]     [`unsigned`]                [Parse a binary integer into an `unsigned`]]
103    [[[qi_unsigned_int `oct`]]     [`unsigned`]                [Parse an octal integer into an `unsigned`]]
104    [[[qi_unsigned_int `hex`]]     [`unsigned`]                [Parse a hexadecimal integer into an `unsigned`]]
105    [[[qi_unsigned_int `ushort_`]] [`unsigned short`]          [Parse an unsigned short integer]]
106    [[[qi_unsigned_int `ushort_(num)`]] [`unsigned short`]     [Parse an unsigned short integer,
107                                                            a number is matched only if it's `num`]]
108    [[[qi_unsigned_int `ulong_`]]  [`unsigned long`]           [Parse an unsigned long integer]]
109    [[[qi_unsigned_int `ulong_(num)`]]  [`unsigned long`]      [Parse an unsigned long integer,
110                                                            a number is matched only if it's `num`]]
111    [[[qi_unsigned_int `uint_`]]   [`unsigned int`]            [Parse an unsigned int]]
112    [[[qi_unsigned_int `uint_(num)`]]   [`unsigned int`]       [Parse an unsigned int,
113                                                            a number is matched only if it's `num`]]
114    [[[qi_unsigned_int `ulong_long`]] [`unsigned long long`]   [Parse an unsigned long long]]
115    [[[qi_unsigned_int `ulong_long(num)`]] [`unsigned long long`]   [Parse an unsigned long long,
116                                                            a number is matched only if it's `num`]]
117    [[[qi_signed_int `short_`]]    [`short`]                   [Parse a short integer]]
118    [[[qi_signed_int `short_(num)`]]    [`short`]              [Parse a short integer,
119                                                            a number is matched only if it's `num`]]
120    [[[qi_signed_int `long_`]]     [`long`]                    [Parse a long integer]]
121    [[[qi_signed_int `long_(num)`]]     [`long`]               [Parse a long integer,
122                                                            a number is matched only if it's `num`]]
123    [[[qi_signed_int `int_`]]      [`int`]                     [Parse an int]]
124    [[[qi_signed_int `int_(num)`]]      [`int`]                [Parse an int,
125                                                            a number is matched only if it's `num`]]
126    [[[qi_signed_int `long_long`]] [`long long`]               [Parse a long long]]
127    [[[qi_signed_int `long_long(num)`]] [`long long`]          [Parse a long long,
128                                                            a number is matched only if it's `num`]]
129]
130
131[endsect]
132[section:string String Parsers]
133
134[table
135    [[Expression]           [Attribute]                 [Description]]
136    [[[qi_lit_string `str`]]          [`Unused`]    [Matches `str`]]
137    [[[qi_lit_string `lit(str)`]]     [`Unused`]    [Matches `str`]]
138    [[[qi_lit_string `string(str)`]]  [`Str`]       [Matches `str`]]
139
140    [[__qi_symbols__]       [N/A]                       [Declare a symbol table, `sym`. `Ch` is the
141                                                        underlying char type of the symbol table keys.
142                                                        `T` is the data type associated with each key.]]
143    [[
144``
145    sym.add
146        (str1, val1)
147        (str2, val2)
148        /*...more...*/
149    ;
150``
151    ]
152    [N/A]                                               [Add symbols into a symbol table, `sym`.
153                                                        val1 and val2 are optional data of type `T`,
154                                                        the data type associated with each key.]]
155    [[`sym`]                [`T`]                       [Matches entries in the symbol table, `sym`. If
156                                                        successful, returns the data associated with
157                                                        the key]]
158]
159
160[endsect]
161[section:auxiliary Auxiliary Parsers]
162
163[table
164    [[Expression]           [Attribute]                 [Description]]
165    [[__qi_eol__]           [`Unused`]                  [Matches the end of line (`\r` or `\n` or `\r\n`)]]
166    [[__qi_eoi__]           [`Unused`]                  [Matches the end of input (first == last)]]
167    [[__qi_eps__]           [`Unused`]                  [Match an empty string]]
168    [[__qi_eps__`(b)`]      [`Unused`]                  [If `b` is true, match an empty string]]
169    [[__qi_lazy__`(fp)`]    [Attribute of `P` where `P`
170                            is the return type of `fp`] [Invoke `fp` at parse time, returning a parser
171                                                        `p` which is then called to parse.]]
172    [[`fp`]                 [see `lazy(fp)` above]      [Equivalent to `lazy(fp)`]]
173    [[__qi_attr__]          [`Attrib`]                  [Doesn't consume/parse any input, but exposes the
174                                                         argument `attrib` as its attribute.]]
175]
176
177[endsect]
178[section:binary Binary Parsers]
179
180[table
181    [[Expression]                   [Attribute]                 [Description]]
182    [[[qi_native_binary `byte_`]]   [8 bits native endian]      [Matches an 8 bit binary in native endian representation]]
183    [[[qi_native_binary `word`]]    [16 bits native endian]     [Matches a 16 bit binary in native endian representation]]
184    [[[qi_big_binary `big_word`]]   [16 bits big endian]        [Matches a 16 bit binary in big endian representation]]
185    [[[qi_little_binary `little_word`]]  [16 bits little endian][Matches a 16 bit binary in little endian representation]]
186    [[[qi_native_binary `dword`]]   [32 bits native endian]     [Matches a 32 bit binary in native endian representation]]
187    [[[qi_big_binary `big_dword`]]  [32 bits big endian]        [Matches a 32 bit binary in big endian representation]]
188    [[[qi_little_binary `little_dword`]] [32 bits little endian][Matches a 32 bit binary in little endian representation]]
189    [[[qi_native_binary `qword`]]   [64 bits native endian]     [Matches a 64 bit binary in native endian representation]]
190    [[[qi_big_binary `big_qword`]]  [64 bits big endian]        [Matches a 64 bit binary in big endian representation]]
191    [[[qi_little_binary `little_qword`]] [64 bits little endian][Matches a 64 bit binary in little endian representation]]
192]
193
194[endsect]
195
196[section:auto Auto Parsers]
197
198See here for more information about [qi_auto Auto Parsers].
199
200[table
201    [[Expression]           [Attribute]     [Description]]
202    [[[qi_auto `auto_`]]    [`hold_any`]    [Parse input using a parser
203                                             created from the supplied attribute type
204                                             using the __create_parser__ API function.]]
205]
206
207[endsect]
208
209[section:directive Parser Directives]
210
211[table
212    [[Expression]                   [Attribute]                     [Description]]
213    [[__qi_lexeme__`[a]`]           [`A`]                           [Disable skip parsing for `a`, does pre-skipping]]
214    [[[qi_no_skip `no_skip[a]`]]    [`A`]                           [Disable skip parsing for `a`, no pre-skipping]]
215    [[__qi_no_case__`[a]`]          [`A`]                           [Inhibits case-sensitivity for `a`]]
216    [[__qi_omit__`[a]`]             [`Unused`]                      [Ignores the attribute type of `a`]]
217    [[__qi_matches__`[a]`]          [`bool`]                        [Return if the embedded parser `a` matched its input]]
218
219    [[__qi_as__`()[a]`]             [`A`]                           [Force atomic assignment for arbitrary attribute types]]
220    [[__qi_as_string__`[a]`]        [`A`]                           [Force atomic assignment for string attributes]]
221    [[__qi_as_wstring__`[a]`]       [`A`]                           [Force atomic assignment for wide character string attributes]]
222
223    [[__qi_raw__`[a]`]              [__boost_iterator_range__`<I>`] [Presents the transduction of `a` as an iterator range]]
224
225	[[__qi_expectd__`[a]`]          [`A`]                           [Throw an exception if parsing `a` fails]]
226
227	[[[qi_repeat `repeat[a]`]]      [`vector<A>`]                   [Repeat `a` zero or more times]]
228    [[[qi_repeat `repeat(N)[a]`]]         [`vector<A>`]             [Repeat `a` `N` times]]
229    [[[qi_repeat `repeat(N, M)[a]`]]      [`vector<A>`]             [Repeat `a` `N` to `M` times]]
230    [[[qi_repeat `repeat(N, inf)[a]`]]    [`vector<A>`]             [Repeat `a` `N` or more times]]
231
232    [[__qi_skip__`[a]`]             [`A`]                           [Re-establish the skipper that got inhibited by lexeme or no_skip.]]
233    [[__qi_skip__`(p)[a]`]          [`A`]                           [Use `p` as a skipper for parsing `a`]]
234]
235]
236
237[endsect]
238[section:operator Parser Operators]
239
240[table
241    [[Expression]           [Attribute]                 [Description]]
242    [[[link spirit.qi.reference.operator.not_predicate `!a`]]
243                            [`Unused`]                  [Not predicate. If the predicate `a` matches,
244                                                        fail. Otherwise, return a zero length match.]]
245    [[[link spirit.qi.reference.operator.and_predicate `&a`]]
246                            [`Unused`]                  [And predicate. If the predicate `a` matches,
247                                                        return a zero length match. Otherwise, fail.]]
248    [[[link spirit.qi.reference.operator.optional `-a`]]
249                            [`optional<A>`]             [Optional. Parse `a` zero or one time]]
250    [[[link spirit.qi.reference.operator.kleene `*a`]]
251                            [`vector<A>`]               [Kleene. Parse `a` zero or more times]]
252    [[[link spirit.qi.reference.operator.plus `+a`]]
253                            [`vector<A>`]               [Plus. Parse `a` one or more times]]
254    [[[link spirit.qi.reference.operator.alternative `a | b`]]
255                            [`variant<A, B>`]           [Alternative. Parse `a` or `b`]]
256    [[[link spirit.qi.reference.operator.sequence `a >> b`]]
257                            [`tuple<A, B>`]             [Sequence. Parse `a` followed by `b`]]
258    [[[link spirit.qi.reference.operator.expect `a > b`]]
259                            [`tuple<A, B>`]             [Expect. Parse `a` followed by `b`. `b` is
260                                                        expected to match when `a` matches, otherwise,
261                                                        an `expectation_failure` is thrown.]]
262    [[[link spirit.qi.reference.operator.difference `a - b`]]
263                            [`A`]                       [Difference. Parse `a` but not `b`]]
264    [[[link spirit.qi.reference.operator.sequential_or `a || b`]]
265                            [`tuple<`
266                                `optional<A>,`
267                                `optional<B> >`
268                            ]                           [Sequential Or. Parse `a` or `b` or `a` followed by `b`]]
269    [[[link spirit.qi.reference.operator.list `a % b`]]
270                            [`vector<A>`]               [List. Parse `a` delimited `b` one or more times]]
271    [[[link spirit.qi.reference.operator.permutation `a ^ b`]]
272                            [`tuple<`
273                                `optional<A>,`
274                                `optional<B> >`
275                            ]                           [Permutation. Parse `a` or `b` or `a` followed by `b` or `b` followed by `a`.]]
276]
277
278[endsect]
279[section:action Parser Semantic Actions]
280
281[table
282    [[Expression]           [Attribute]                 [Description]]
283    [[`p[fa]`]              [Attribute of `p`]          [Call semantic action, `fa` if p succeeds.]]
284]
285
286[endsect]
287[endsect]
288[section Compound Attribute Rules]
289
290[heading Notation]
291
292The notation we will use will be of the form:
293
294    a: A, b: B, ... --> composite-expression: composite-attribute
295
296`a`, `b`, etc. are the operands. `A`, `B`, etc. are the operand's
297attribute types. `composite-expression` is the expression involving the
298operands and `composite-attribute` is the resulting attribute type of
299the composite expression.
300
301For instance:
302
303    a: A, b: B --> (a >> b): tuple<A, B>
304
305reads as: given, `a` and `b` are parsers, and `A` is the type of the
306attribute of `a`, and `B` is the type of the attribute of `b`, then the
307type of the attribute of `a >> b` will be `tuple<A, B>`.
308
309[important In the attribute tables, we will use `vector<A>` and
310`tuple<A, B...>` as placeholders only. The notation of `vector<A>`
311stands for ['any __stl__ container] holding elements of type `A` and the
312notation `tuple<A, B...>` stands for ['any __fusion__ sequence] holding
313`A`, `B`, ... etc. elements. Finally, `Unused` stands for
314__unused_type__. ]
315
316[heading Compound Parser Attribute Types]
317
318[table
319    [[Expression]           [Attribute]]
320
321    [[__qi_sequence__ (`a >> b`)]
322[``a: A, b: B --> (a >> b): tuple<A, B>
323a: A, b: Unused --> (a >> b): A
324a: Unused, b: B --> (a >> b): B
325a: Unused, b: Unused --> (a >> b): Unused
326
327a: A, b: A --> (a >> b): vector<A>
328a: vector<A>, b: A --> (a >> b): vector<A>
329a: A, b: vector<A> --> (a >> b): vector<A>
330a: vector<A>, b: vector<A> --> (a >> b): vector<A>``]]
331
332    [[__qi_expect__ (`a > b`)]
333[``a: A, b: B --> (a > b): tuple<A, B>
334a: A, b: Unused --> (a > b): A
335a: Unused, b: B --> (a > b): B
336a: Unused, b: Unused --> (a > b): Unused
337
338a: A, b: A --> (a > b): vector<A>
339a: vector<A>, b: A --> (a > b): vector<A>
340a: A, b: vector<A> --> (a > b): vector<A>
341a: vector<A>, b: vector<A> --> (a > b): vector<A>``]]
342
343    [[__qi_alternative__ (`a | b`)]
344[``a: A, b: B --> (a | b): variant<A, B>
345a: A, b: Unused --> (a | b): optional<A>
346a: A, b: B, c: Unused --> (a | b | c): optional<variant<A, B> >
347a: Unused, b: B --> (a | b): optional<B>
348a: Unused, b: Unused --> (a | b): Unused
349a: A, b: A --> (a | b): A``]]
350
351    [[__qi_difference__ (`a - b`)]
352[``a: A, b: B --> (a - b): A
353a: Unused, b: B --> (a - b): Unused``]]
354
355    [[__qi_kleene__ (`*a`)]
356[``a: A --> *a: vector<A>
357a: Unused --> *a: Unused``]]
358    [[__qi_plus__ (`+a`)]
359[``a: A --> +a: vector<A>
360a: Unused --> +a: Unused``]]
361
362    [[__qi_list__ (`a % b`)]
363[``a: A, b: B --> (a % b): vector<A>
364a: Unused, b: B --> (a % b): Unused``]]
365
366    [[[link spirit.qi.reference.directive.repeat `repeat(...,...)[a]`]]
367[``a: A --> repeat(...,...)[a]: vector<A>
368a: Unused --> repeat(...,...)[a]: Unused``]]
369
370    [[__qi_sequential_or__ (`a || b`)]
371[``a: A, b: B --> (a || b): tuple<optional<A>, optional<B> >
372a: A, b: Unused --> (a || b): optional<A>
373a: Unused, b: B --> (a || b): optional<B>
374a: Unused, b: Unused --> (a || b): Unused
375
376a: A, b: A --> (a || b): vector<optional<A> >``]]
377
378    [[__qi_optional__ (`-a`)]
379[``a: A --> -a: optional<A>
380a: Unused --> -a: Unused``]]
381
382    [[`&a`]  [`a: A --> &a: Unused`]]
383    [[`!b`]  [`a: A --> !a: Unused`]]
384
385    [[__qi_permutation__ (`a ^ b`)]
386[``a: A, b: B --> (a ^ b): tuple<optional<A>, optional<B> >
387a: A, b: Unused --> (a ^ b): optional<A>
388a: Unused, b: B --> (a ^ b): optional<B>
389a: Unused, b: Unused --> (a ^ b): Unused``]]
390]
391
392[endsect]
393
394[section:non_terminals Nonterminals]
395
396[variablelist Notation
397    [[`RT`]                     [Synthesized attribute. The rule or grammar's return type.]]
398    [[`Arg1`, `Arg2`, `ArgN`]   [Inherited attributes. Zero or more arguments.]]
399    [[`L1`, `L2`, `LN`]         [Zero or more local variables.]]
400    [[`r, r2`]                  [Rules]]
401    [[`g`]                      [A grammar]]
402    [[`p`]                      [A parser expression]]
403    [[`my_grammar`]             [A user defined grammar]]
404]
405
406[variablelist Terminology
407    [[Signature]                [`RT(Arg1, Arg2 ... ,ArgN)`. The signature specifies
408                                the synthesized (return value) and inherited (arguments)
409                                attributes.]]
410    [[Locals]                   [`locals<L1, L2 ..., LN>`. The local variables.]]
411    [[Skipper]                  [The skip-parser type]]
412]
413
414[variablelist Template Arguments
415    [[`Iterator`]               [The iterator type you will use for parsing.]]
416    [[`A1`, `A2`, `A3`]         [Can be one of 1) Signature 2) Locals 3) Skipper.]]
417]
418
419[table
420    [[Expression]                               [Description]]
421    [[`rule<Iterator, A1, A2, A3> r(name);`]    [Rule declaration. `Iterator` is required.
422                                                `A1, A2, A3` are optional and can be specified in any order.
423                                                `name` is an optional string that gives the rule
424                                                its name, useful for debugging and error handling.]]
425    [[`rule<Iterator, A1, A2, A3> r(r2);`]      [Copy construct rule `r` from rule `r2`.]]
426    [[`r = r2;`]                                [Assign rule `r2` to `r`.]]
427    [[`r.alias()`]                              [return an alias of `r`. The alias is a parser that
428                                                holds a reference to `r`. Reference semantics.]]
429    [[`r.copy()`]                               [Get a copy of `r`.]]
430    [[`r.name(name)`]                           [Naming a rule]]
431    [[`r.name()`]                               [Getting the name of a rule]]
432    [[debug(r)]                                 [Debug rule `r`]]
433    [[`r = p;`]                                 [Rule definition]]
434    [[`r %= p;`]                                [Auto-rule definition. The attribute of `p` must be
435                                                compatible with the synthesized attribute of `r`. If `p`
436                                                is successful, its attribute is automatically propagated
437                                                to `r`'s synthesized attribute.  Semantic actions, if present,
438                                                may not change the attribute's type.]]
439
440    [[
441``
442    template <typename Iterator>
443    struct my_grammar : grammar<Iterator, A1, A2, A3>
444    {
445        my_grammar() : my_grammar::base_type(start, name)
446        {
447            // Rule definitions
448            start = /* ... */;
449        }
450
451        rule<Iterator, A1, A2, A3> start;
452        // more rule declarations...
453    };
454``
455    ]                                           [Grammar definition. `name` is an optional string that gives the
456                                                grammar its name, useful for debugging and error handling.]]
457    [[`g.name(name)`]                           [Naming a grammar]]
458    [[`g.name()`]                               [Getting the name of a grammar]]
459]
460
461[endsect]
462[section:semantic_actions Parser Semantic Actions]
463
464Has the form:
465
466    p[f]
467
468where `f` is a function with the signatures:
469
470    void f(Attrib const&);
471    void f(Attrib const&, Context&);
472    void f(Attrib const&, Context&, bool&);
473
474You can use __boost_bind__ to bind member functions. For function
475objects, the allowed signatures are:
476
477    void operator()(Attrib const&, unused_type, unused_type) const;
478    void operator()(Attrib const&, Context&, unused_type) const;
479    void operator()(Attrib const&, Context&, bool&) const;
480
481The `unused_type` is used in the signatures above to signify 'don't
482care'.
483
484For more detailed information about semantic actions see:
485[link spirit.qi.tutorials.semantic_actions here].
486
487[endsect]
488[section Phoenix]
489
490__phoenix__ makes it easier to attach semantic actions. You just
491inline your lambda expressions:
492
493    p[phoenix-lambda-expression]
494
495Spirit.Qi provides some __phoenix__ placeholders to important
496information from the `Attrib` and `Context` that are otherwise fiddly to extract.
497
498[variablelist Spirit.Qi specific Phoenix placeholders
499    [[`_1, _2... , _N`]         [Nth attribute of `p`]]
500    [[`_val`]                   [The enclosing rule's synthesized attribute.]]
501    [[`_r1, _r2... , _rN`]      [The enclosing rule's Nth inherited attribute.]]
502    [[`_a, _b... , _j`]         [The enclosing rule's local variables (`_a` refers to the first).]]
503    [[`_pass`]                  [Assign `false` to `_pass` to force a parser failure.]]
504]
505
506[important  All placeholders mentioned above are defined in the namespace
507           `boost::spirit` and, for your convenience, are available in the
508           namespace `boost::spirit::qi` as well.]
509
510For more detailed information about semantic actions see:
511[link spirit.qi.tutorials.semantic_actions here].
512
513[endsect]
514