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

Auto Parser

Description

This module includes the description of the auto_ parser. This parser can be used to automatically create a parser based on the supplied attribute type.

Header
// forwards to <boost/spirit/home/qi/auto.hpp>
#include <boost/spirit/include/qi_auto.hpp>

Also, see Include Structure.

Namespace

Name

boost::spirit::auto_ // alias: boost::spirit::qi::auto_

Model of

PrimitiveParser

Expression Semantics

Semantics of an expression is defined only where it differs from, or is not defined in PrimitiveGenerator.

Expression

Description

auto_

Create a parser instance compatible with the supplied attribute type and use it for input matching.

Additional Requirements

The auto_ parsers can be used to match input for any data type for which a mapping to a parser type is defined (the meta function traits::create_parser_exists returns mpl::true_). The following table outlines the predefined mapping rules from the attribute type to the parser type. These rules are applied recursively to create the parser type which can be used to match input for the given attribute type.

Attribute type

Parser type

char, wchar_t

standard::char_, standard_wide::char_

short, int, long

short_, int_, long_

unsigned short, unsigned int, unsigned long

ushort_, uint_, ulong_

float, double, long double

float_, double_, long_double

long long, unsigned long long

long_long, ulong_long

bool

bool_

Any (STL) container

Kleene Star (unary '*')

Any Fusion sequence

Sequence operator ('>>')

boost::optional<>

Optional operator (unary '-')

boost::variant<>

Alternative operator ('|')

It is possible to add support for any custom data type by implementing a specialization of the customization point traits::create_parser. This customization can be used also to redefined any of the predefined mappings.

Attributes

Expression

Attribute

auto_

hold_any

[Important] Important

The attribute type hold_any exposed by the auto_ parser is semantically and syntactically equivalent to the type implemented by Boost.Any. It has been added to Spirit as it has better a performance and a smaller footprint if compared to Boost.Any.

Complexity

The complexity of the auto_ parser depends on the supplied attribute type. Each attribute type results in a different parser type to be instantiated which defines the overall complexity.

Example
[Note] Note

The test harness for the example(s) below is presented in the Basics Examples section.

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>

Some using declarations:

using boost::spirit::qi::auto_;

And a class definition used in the examples:

// a simple complex number representation z = a + bi
struct complex
{
    complex (double a = 0.0, double b = 0.0)
      : a(a), b(b)
    {}

    double a;
    double b;
};

The following construct is required to allow the complex data structure to be utilized as a Boost.Fusion sequence. This is required as we will emit output for this data structure with a Spirit.Qi sequence: '{' >> qi::double_ >> ',' >> qi::double_ >> '}'.

BOOST_FUSION_ADAPT_STRUCT(
    complex,
    (double, a)
    (double, b)
)

We add a specialization for the create_parser customization point defining a custom output format for the complex type. Generally, any specialization for create_parser is expected to return the proto expression to be used to match input for the type the customization point has been specialized for.

We need to utilize proto::deep_copy as the expression contains literals (the '{', ',', and '}') which normally get embedded in the proto expression by reference only. The deep copy converts the proto tree to hold this by value. The deep copy operation can be left out for simpler proto expressions (not containing references to temporaries). Alternatively you could use the proto::make_expr facility to build the required proto expression.

namespace boost { namespace spirit { namespace traits
{
    template <>
    struct create_parser<complex>
    {
        typedef proto::result_of::deep_copy<
            BOOST_TYPEOF('{' >> qi::double_ >> ',' >> qi::double_ >> '}')
        >::type type;

        static type call()
        {
            return proto::deep_copy(
                '{' >> qi::double_ >> ',' >> qi::double_ >> '}');
        }
    };
}}}

Some usage examples of auto_ parsers:

Parse a simple integer using the generated parser component int_:

int i = 0;
test_parser_attr("123", auto_, i);
std::cout << i << std::endl;                    // prints: 123

Parse an instance of the complex data type as defined above using the parser as generated by the defined customization point:

complex c;
test_parser_attr("{1.2,2.4}", auto_, c);
std::cout << c.a << "," << c.b << std::endl;    // prints: 1.2,2.4


PrevUpHomeNext