Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Sum - adding numbers

Here's a parser that sums a comma-separated list of numbers.

Ok we've glossed over some details in our previous examples. First, our includes:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <iostream>
#include <string>

Then some using directives:

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;

using qi::double_;
using qi::_1;
using ascii::space;
using phoenix::ref;

Namespace

Description

boost::phoenix

All of phoenix

boost::spirit

All of spirit

boost::spirit::qi

All of spirit.qi

boost::spirit::ascii

ASCII version of char_ and all char related parsers. Other encodings are also provided (e.g. also an ISO8859.1)

boost::spirit::arg_names

Special phoenix placeholders for spirit

[Note] Note

If you feel uneasy with using whole namespaces, feel free to qualify your code, use namespace aliases, etc. For the purpose of this tutorial, we will be presenting unqualified names for both Spirit and Phoenix. No worries, we will always present the full working code, so you won't get lost. In fact, all examples in this tutorial have a corresponding cpp file that QuickBook (the documentation tool we are using) imports in here as code snippets.

Now the actual parser:

template <typename Iterator>
bool adder(Iterator first, Iterator last, double& n)
{
    bool r = qi::phrase_parse(first, last,

        //  Begin grammar
        (
            double_[ref(n) = _1] >> *(',' >> double_[ref(n) += _1])
        )
        ,
        //  End grammar

        space);

    if (first != last) // fail if we did not get a full match
        return false;
    return r;
}

The full cpp file for this example can be found here: ../../example/qi/sum.cpp

This is almost like our original numbers list example. We're incrementally building on top of our examples. This time though, like in the complex number example, we'll be adding the smarts. There's an accumulator (double& n) that adds the numbers parsed. On a successful parse, this number is the sum of all the parsed numbers.

The first double_ parser attaches this action:

ref(n) = _1

This assigns the parsed result (actually, the attribute of double_) to n. ref(n) tells Phoenix that n is a mutable reference. _1 is a Phoenix placeholder for the parsed result attribute.

The second double_ parser attaches this action:

ref(n) += _1

So, subsequent numbers add into n.

That wasn't too bad, was it :-) ?


PrevUpHomeNext