| Home | Libraries | People | FAQ | More

### Attributes of Compound Components

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` and `b` are parsers, and `A` is the attribute type of `a`, and `B` is the attribute type of `b`, then the attribute type of `a >> b` (`a << b`) will be `tuple<A, B>`.

| Note
The notation `tuple<A, B>` is used as a placeholder expression for any fusion sequence holding the types A and B, such as `boost::fusion::tuple<A, B>` or `std::pair<A, B>` (for more information see Boost.Fusion).

As you can see, in order for a type to be compatible with the attribute type of a compound expression it has to

- either be convertible to the attribute type,
- or it has to expose certain functionalities, i.e. it needs to conform to a concept compatible with the component.

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.

##### The Attribute of Sequence Parsers

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 `parse` and `phrase_parse` function. Just use `std:tuple'. Be sure to include` boost/fusion/adapted/std_tuple.hpp' in this case.

##### The Attribute of Alternative Parsers

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.