]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/doc/x3/tutorial/actions.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / doc / x3 / tutorial / actions.qbk
CommitLineData
7c673cae
FG
1[/==============================================================================
2 Copyright (C) 2001-2015 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 polymorphic function objects that are called whenever a part
19of the parser successfully recognizes a portion of the input. Say you have a
20parser `p`, and a polymorphic C++ function object `f`. You can make the parser
21call `f` whenever it matches an input by attaching `f`:
22
23 p[f]
24
25The expression above links `f` to the parser, `p`. `f` is expected to be a
26polymorphic function object with the signature:
27
28 template <typename Context>
29 void operator()(Context const& ctx) const;
30
31We can also use C++14 generic lambdas of the form:
32
33 [](auto& ctx) { /*...*/ }
34
35From the context, we can extract relevant information:
36
37[table Parse Context Access Functions
38 [[Function] [Description] [Example]]
39 [[`_val`] [A reference to the attribute of the
40 innermost rule that directly or indirectly
41 invokes the parser `p`] [`_val(ctx) = "Gotya!"`]]
42 [[`_where`] [Iterator range to the input stream] [`_where(ctx).begin()`]]
43 [[`_attr`] [A reference to the attribute of the
44 parser `p`] [`_val(ctx) += _attr(ctx)`]]
45 [[`_pass`] [A reference to a `bool` flag that
46 can be used to force the `p` to fail] [`_pass(ctx) = false`]]
47]
48
49[heading Examples of Semantic Actions]
50
51Given:
52
53 struct print_action
54 {
55 template <typename Context>
56 void operator()(Context const& ctx) const
57 {
58 std::cout << _attr(ctx) << std::endl;
59 }
60 };
61
62Take note that with function objects, we need to have an `operator()` with
63the Context argument. If we don't care about the context, we can use
64`unused_type`. We'll see more of `unused_type` elsewhere. `unused_type` is a
65Spirit supplied support class.
66
67All examples parse inputs of the form:
68
69 "{NNN}"
70
71Where NNN is an integer inside the curly braces (e.g. {44}).
72
73The first example shows how to attach a function object:
74
75 parse(first, last, '{' >> int_[print_action()] >> '}');
76
77What's new? Well `int_` is the sibling of `double_`. I'm sure you can guess
78what this parser does.
79
80The next example shows how use C++14 lambda:
81
82 auto f = [](auto& ctx){ std::cout << _attr(ctx) << std::endl; };
83 parse(first, last, '{' >> int_[f] >> '}');
84
85Attaching semantic actions is the first hurdle one has to tackle when getting
86started with parsing with Spirit. Familiarize yourself with this task.
87
88The examples above can be found here: [@../../../example/x3/actions.cpp]
89
90[endsect]