![]() |
Home | Libraries | People | FAQ | More |
While parsing input, it is often desirable to combine some constant elements
with variable parts. For instance, let us look at the example of parsing
or formatting a complex number, which is written as (real, imag),
where real and imag are the variables representing the
real and imaginary parts of our complex number. This can be achieved by writing:
'(' >> double_ >> ", " >> double_ >> ')'
Literals (such as '(' and ", ") do not
expose any attribute (well actually, they do expose the special type unused_type, but in this context unused_type is interpreted as if the component
does not expose any attribute at all). It is very important to understand
that the literals don't consume any of the elements of a fusion sequence
passed to this component sequence. As said, they just don't expose any attribute
and don't produce (consume) any data. The following example shows this:
// 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::parse(strbegin, input.end(), '(' >> x3::double_ >> ", " >> x3::double_ >> ')', // parser grammar p); // attribute to fill while parsing
where the first element of the pair passed in as the data to generate is
still associated with the first double_,
and the second element is associated with the second double_
parser.
This behavior should be familiar as it conforms to the way other input and
output formatting libraries such as scanf,
printf or boost::format
are handling their variable parts. In this context you can think about Spirit.X3's
primitive components (such as the double_
above) as of being type safe placeholders for the attribute values.
![]() |
Tip |
|---|---|
For sequences only: To keep it simple,
unlike __Spirit.qi__, Spirit.X3 does not support more
than one attribute anymore in the |
Let's take a look at this from a more formal perspective:
a: A, b: Unused --> (a >> b): A
which reads as:
Given
aandbare parsers, andAis the attribute type ofa, andunused_typeis the attribute type ofb, then the attribute type ofa >> b(a << b) will beAas well. This rule applies regardless of the position the element exposing theunused_typeis at.
This rule is the key to the understanding of the attribute handling in sequences
as soon as literals are involved. It is as if elements with unused_type attributes 'disappeared' during
attribute propagation. Notably, this is not only true for sequences but for
any compound components. For instance, for alternative components the corresponding
rule is:
a: A, b: Unused --> (a | b): A
again, allowing to simplify the overall attribute type of an expression.