• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Complex - Our first complex parser]
10
11Well, not really a complex parser, but a parser that parses complex numbers.
12
13Here's a simple parser expression for complex numbers:
14
15        '(' >> double_ >> -(',' >> double_) >> ')'
16    |   double_
17
18What's new? Well, we have:
19
20# Alternates: e.g. `a | b`. Try `a` first. If it succeeds, good. If not, try the
21  next alternative, `b`.
22# Optionals: e.g. -p. Match the parser p zero or one time.
23
24The complex parser presented above reads as:
25
26* One or two real numbers in parentheses, separated by comma (the second number is optional)
27* *OR* a single real number.
28
29This parser can parse complex numbers of the form:
30
31    (123.45, 987.65)
32    (123.45)
33    123.45
34
35Here goes, this time with actions:
36
37    namespace client
38    {
39        template <typename Iterator>
40        bool parse_complex(Iterator first, Iterator last, std::complex<double>& c)
41        {
42            using boost::spirit::x3::double_;
43            using boost::spirit::x3::_attr;
44            using boost::spirit::x3::phrase_parse;
45            using boost::spirit::x3::ascii::space;
46
47            double rN = 0.0;
48            double iN = 0.0;
49            auto fr = [&](auto& ctx){ rN = _attr(ctx); };
50            auto fi = [&](auto& ctx){ iN = _attr(ctx); };
51
52            bool r = phrase_parse(first, last,
53
54                //  Begin grammar
55                (
56                        '(' >> double_[fr]
57                            >> -(',' >> double_[fi]) >> ')'
58                    |   double_[fr]
59                ),
60                //  End grammar
61
62                space);
63
64            if (!r || first != last) // fail if we did not get a full match
65                return false;
66            c = std::complex<double>(rN, iN);
67            return r;
68        }
69    }
70
71The full cpp file for this example can be found here:
72[@../../../example/x3/complex_number.cpp complex_number.cpp]
73
74The `double_` parser attaches this action:
75
76    [&](auto& ctx){ n = _attr(ctx); }
77
78This assigns the parsed result (actually, the attribute of `double_`) to n.
79
80[endsect]
81