Home | Libraries | People | FAQ | More |
Spirit.X3 implement well defined attribute type propagation rules for all compound parsers, such as sequences, alternatives, Kleene star, etc. The main attribute propagation rule for a sequences is for instance:
a: A, b: B --> (a >> b): tuple<A, B>
which reads as:
Given
a
andb
are parsers, andA
is the attribute type ofa
, andB
is the attribute type ofb
, then the attribute type ofa >> b
(a << b
) will betuple<A, B>
.
Note | |
---|---|
The notation |
As you can see, in order for a type to be compatible with the attribute type of a compound expression it has to
Each compound component implements its own set of attribute propagation rules. For a full list of how the different compound parsers consume attributes see the sections Parser Compound Attribute Rules.
Sequences require an attribute type to expose the concept of a fusion sequence, where all elements of that fusion sequence have to be compatible with the corresponding element of the component sequence. For example, the expression:
double_ >> double_
is compatible with any fusion sequence holding two types, where both types
have to be compatible with double
.
The first element of the fusion sequence has to be compatible with the attribute
of the first double_
, and
the second element of the fusion sequence has to be compatible with the attribute
of the second double_
. If
we assume to have an instance of a std::pair<double, double>
,
we can directly use the expressions above to do both, parse input to fill
the attribute:
// the following parses "1.0 2.0" into a pair of double std::string input("1.0 2.0"); std::string::iterator strbegin = input.begin(); std::pair<double, double> p; x3::phrase_parse(strbegin, input.end(), x3::double_ >> x3::double_, // parser grammar x3::space, // delimiter grammar p); // attribute to fill while parsing
Tip | |
---|---|
For sequences only: To keep it simple,
unlike __Spirit.qi__, Spirit.X3 does not support more
than one attribute anymore in the |
Alternative parsers are all about - well - alternatives. In order to store possibly different result (attribute) types from the different alternatives we use the data type Boost.Variant. The main attribute propagation rule of these components is:
a: A, b: B --> (a | b): variant<A, B>
Alternatives have a second very important attribute propagation rule:
a: A, b: A --> (a | b): A
often simplifying things significantly. If all sub expressions of an alternative expose the same attribute type, the overall alternative will expose exactly the same attribute type as well.