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

Parser Basics

Lazy Argument

Some parsers (e.g. primitives and non-terminals) may take in additional attributes. Such parsers take the form:

p(a1, a2,..., aN)

where p is a parser. Each of the arguments (a1 ... aN) can either be an immediate value, or a function, f, with signature:

T f(Unused, Context)

where T, the function's return value, is compatible with the argument type expected and Context is the parser's Context type (The first argument is unused to make the Context the second argument. This is done for uniformity with Semantic Actions).

Character Encoding Namespace

Some parsers need to know which character set a char or wchar_t is operating on. For example, the alnum parser works differently with ISO8859.1 and ASCII encodings. Where necessary, Spirit encodes (tags) the parser with the character set.

We have a namespace for each character set Spirit will be supporting. That includes ascii, iso8859_1, standard and standard_wide (and in the future, unicode). In each of the character encoding namespaces, we place tagged versions of parsers such as alnum, space etc.

Example:

using boost::spirit::ascii::space; // use the ASCII space parser

Namespaces:

For ease of use, the components in this namespaces are also brought into the qi sub-namespaces with the same names:

Examples

All sections in the reference present some real world examples. The examples use a common test harness to keep the example code as minimal and direct to the point as possible. The test harness is presented below.

Some includes:

#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <boost/predef/other/endian.h>
#include <boost/proto/deep_copy.hpp>
#include <iostream>
#include <string>
#include <cstdlib>

Our test functions:

These functions test the parsers without attributes.

template <typename P>
void test_parser(
    char const* input, P const& p, bool full_match = true)
{
    using boost::spirit::qi::parse;

    char const* f(input);
    char const* l(f + strlen(f));
    if (parse(f, l, p) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

template <typename P>
void test_phrase_parser(
    char const* input, P const& p, bool full_match = true)
{
    using boost::spirit::qi::phrase_parse;
    using boost::spirit::qi::ascii::space;

    char const* f(input);
    char const* l(f + strlen(f));
    if (phrase_parse(f, l, p, space) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

These functions test the parsers with user supplied attributes.

template <typename P, typename T>
void test_parser_attr(
    char const* input, P const& p, T& attr, bool full_match = true)
{
    using boost::spirit::qi::parse;

    char const* f(input);
    char const* l(f + strlen(f));
    if (parse(f, l, p, attr) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

template <typename P, typename T>
void test_phrase_parser_attr(
    char const* input, P const& p, T& attr, bool full_match = true)
{
    using boost::spirit::qi::phrase_parse;
    using boost::spirit::qi::ascii::space;

    char const* f(input);
    char const* l(f + strlen(f));
    if (phrase_parse(f, l, p, space, attr) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

The print_info utility function prints information contained in the info class.

struct printer
{
    typedef boost::spirit::utf8_string string;

    void element(string const& tag, string const& value, int depth) const
    {
        for (int i = 0; i < (depth*4); ++i) // indent to depth
            std::cout << ' ';

        std::cout << "tag: " << tag;
        if (value != "")
            std::cout << ", value: " << value;
        std::cout << std::endl;
    }
};

void print_info(boost::spirit::info const& what)
{
    using boost::spirit::basic_info_walker;

    printer pr;
    basic_info_walker<printer> walker(pr, what.tag, 0);
    boost::apply_visitor(walker, what.value);
}

String
Header
// forwards to <boost/spirit/home/support/string_traits.hpp>
#include <boost/spirit/support_string_traits.hpp>

A string can be any object s, of type, S, that satisfies the following expression traits:

Expression

Semantics

boost::spirit::traits::is_string<S>

Metafunction that evaluates to mpl::true_ if a certain type, S is a string, mpl::false_ otherwise (See MPL Boolean Constant).

boost::spirit::traits::char_type_of<S>

Metafunction that returns the underlying char type of a string type, S.

boost::spirit::traits::get_c_string(s)

Function that returns the underlying raw C-string from s.

boost::spirit::traits::get_begin(s)

Function that returns an STL iterator from s that points to the beginning the string.

boost::spirit::traits::get_end(s)

Function that returns an STL iterator from s that points to the end of the string.

Models

Predefined models include:

The namespace boost::spirit::traits is open for users to provide their own specializations. The customization points implemented by Spirit.Qi usable to customize the behavior of parsers are described in the section Customization of Attribute Handling.


PrevUpHomeNext