File: complex.qbk

package info (click to toggle)
boost1.74 1.74.0-9
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 464,084 kB
  • sloc: cpp: 3,338,324; xml: 131,293; python: 33,088; ansic: 14,336; asm: 4,034; sh: 3,351; makefile: 1,193; perl: 1,036; yacc: 478; php: 212; ruby: 102; lisp: 24; sql: 13; csh: 6
file content (80 lines) | stat: -rw-r--r-- 2,469 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
[/==============================================================================
    Copyright (C) 2001-2015 Joel de Guzman
    Copyright (C) 2001-2011 Hartmut Kaiser

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
===============================================================================/]

[section Complex - Our first complex parser]

Well, not really a complex parser, but a parser that parses complex numbers.

Here's a simple parser expression for complex numbers:

        '(' >> double_ >> -(',' >> double_) >> ')'
    |   double_

What's new? Well, we have:

# Alternates: e.g. `a | b`. Try `a` first. If it succeeds, good. If not, try the
  next alternative, `b`.
# Optionals: e.g. -p. Match the parser p zero or one time.

The complex parser presented above reads as:

* One or two real numbers in parentheses, separated by comma (the second number is optional)
* *OR* a single real number.

This parser can parse complex numbers of the form:

    (123.45, 987.65)
    (123.45)
    123.45

Here goes, this time with actions:

    namespace client
    {
        template <typename Iterator>
        bool parse_complex(Iterator first, Iterator last, std::complex<double>& c)
        {
            using boost::spirit::x3::double_;
            using boost::spirit::x3::_attr;
            using boost::spirit::x3::phrase_parse;
            using boost::spirit::x3::ascii::space;

            double rN = 0.0;
            double iN = 0.0;
            auto fr = [&](auto& ctx){ rN = _attr(ctx); };
            auto fi = [&](auto& ctx){ iN = _attr(ctx); };

            bool r = phrase_parse(first, last,

                //  Begin grammar
                (
                        '(' >> double_[fr]
                            >> -(',' >> double_[fi]) >> ')'
                    |   double_[fr]
                ),
                //  End grammar

                space);

            if (!r || first != last) // fail if we did not get a full match
                return false;
            c = std::complex<double>(rN, iN);
            return r;
        }
    }

The full cpp file for this example can be found here:
[@../../../example/x3/complex_number.cpp complex_number.cpp]

The `double_` parser attaches this action:

    [&](auto& ctx){ n = _attr(ctx); }

This assigns the parsed result (actually, the attribute of `double_`) to n.

[endsect]