...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
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.
// forwards to <boost/spirit/home/qi/auto.hpp> #include <boost/spirit/include/qi_auto.hpp>
Also, see Include Structure.
Name |
---|
|
Semantics of an expression is defined only where it differs from, or is
not defined in PrimitiveGenerator
.
Expression |
Description |
---|---|
|
Create a parser instance compatible with the supplied attribute type and use it for input matching. |
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 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Any (STL) container |
Kleene Star (unary |
Any Fusion sequence |
Sequence operator ( |
|
Optional operator (unary |
|
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.
Expression |
Attribute |
---|---|
|
|
Important | |
---|---|
The attribute type |
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.
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