]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/doc/qi/actions.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / doc / qi / actions.qbk
CommitLineData
7c673cae
FG
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:semantic_actions Parser Semantic Actions]
10
11The example in the previous section was very simplistic. It only recognized
12data, but did nothing with it. It answered the question: "Did the input match?".
13Now, we want to extract information from what was parsed. For example, we would
14want to store the parsed number after a successful match. To do this, you will
15need ['semantic actions].
16
17Semantic actions may be attached to any point in the grammar specification.
18These actions are C++ functions or function objects that are called whenever a
19part of the parser successfully recognizes a portion of the input. Say you have
20a parser `P`, and a C++ function `F`. You can make the parser call `F` whenever
21it matches an input by attaching `F`:
22
23 P[F]
24
25The expression above links `F` to the parser, `P`.
26
27The function/function object signature depends on the type of the parser to
28which it is attached. The parser `double_` passes the parsed number. Thus, if we
29were to attach a function `F` to `double_`, we need `F` to be declared as:
30
31 void F(double n);
32
33There are actually 2 more arguments being passed (the parser context and a
34reference to a boolean 'hit' parameter). We don't need these, for now, but we'll
35see more on these other arguments later. Spirit.Qi allows us to bind a single
36argument function, like above. The other arguments are simply ignored.
37
38[heading Examples of Semantic Actions]
39
40Presented are various ways to attach semantic actions:
41
42* Using plain function pointer
43* Using simple function object
44* Using __boost_bind__ with a plain function
45* Using __boost_bind__ with a member function
46* Using __boost_lambda__
47
48[import ../../example/qi/actions.cpp]
49
50Given:
51
52[tutorial_semantic_action_functions]
53
54Take note that with function objects, we need to have an `operator()` with 3
55arguments. Since we don't care about the other two, we can use `unused_type` for
56these. We'll see more of `unused_type` elsewhere. `unused_type` is a Spirit
57supplied support class.
58
59All examples parse inputs of the form:
60
61 "{integer}"
62
63An integer inside the curly braces.
64
65The first example shows how to attach a plain function:
66
67[tutorial_attach_actions1]
68
69What's new? Well `int_` is the sibling of `double_`. I'm sure you can guess
70what this parser does.
71
72The next example shows how to attach a simple function object:
73
74[tutorial_attach_actions2]
75
76We can use __boost_bind__ to 'bind' member functions:
77
78[tutorial_attach_actions4]
79
80Likewise, we can also use __boost_bind__ to 'bind' plain functions:
81
82[tutorial_attach_actions3]
83
84Yep, we can also use __boost_lambda__:
85
86[tutorial_attach_actions5]
87
88There are more ways to bind semantic action functions, but the examples above
89are the most common. Attaching semantic actions is the first hurdle one has
90to tackle when getting started with parsing with Spirit. Familiarize yourself
91with this task and get intimate with the tools behind it such as __boost_bind__
92and __boost_lambda__.
93
94The examples above can be found here: [@../../example/qi/actions.cpp]
95
96[heading Phoenix]
97
98__phoenix__, a companion library bundled with Spirit, is specifically suited
99for binding semantic actions. It is like __boost_lambda__ on steroids, with
100special custom features that make it easy to integrate semantic actions with
101Spirit. If your requirements go beyond simple to moderate parsing, it is
102suggested that you use this library. All the following examples in this tutorial
103will use __phoenix__ for semantic actions.
104
105[important There are different ways to write semantic actions for __qi__:
106 using plain functions, __boost_bind__, __boost_lambda__, or
107 __phoenix__. The latter three allow you to use special placeholders
108 to control parameter placement (`_1`, `_2`, etc.). Each of those
109 libraries has it's own implementation of the placeholders, all
110 in different namespaces. You have to make sure not to mix
111 placeholders with a library they don't belong to and not to
112 use different libraries while writing a semantic action.
113
114 Generally, for __boost_bind__, use `::_1`, `::_2`, etc. (yes, these
115 placeholders are defined in the global namespace).
116
117 For __boost_lambda__ use the placeholders defined in the namespace
118 `boost::lambda`.
119
120 For semantic actions written using __phoenix__ use the placeholders
121 defined in the namespace `boost::spirit`. Please note that all
122 existing placeholders for your convenience are also available from
123 the namespace `boost::spirit::qi`.]
124
125[endsect]