
I am having a bit trouble with the semantic action of a sequential-or parser. Specifically my problem is with accessing the attribute of the sequential-or parser. My first observation is that the documentation at http://www.boost.org/doc/libs/1_41_0/libs/spirit/doc/html/spirit/qi/qui ck_reference/qi_parsers/operator.html defines the attribute type of (a || b) as tuple<A, B>. Unless I've misunderstood, this must be a typo as they should both be optional (it is never valid for both to be omitted but I would expect that client code be able to determine which out of (a), (b) or (a >> b) were provided.)
Yes, that's a documentation error. The correct attribute propagation rules should be: a: A, b: B --> (a || b): tuple<optional<A>, optional<B> > a: A, b: Unused --> (a || b): optional<A> a: Unused, b: B --> (a || b): optional<B> a: Unused, b: Unused --> (a || b): Unused I'll fix that in the docs asap.
My real problem is that applying a semantic action to [what I think is] an expression returning a sequential-or parser, results in the _1 referring to the attribute of the last parser on the right-hand-side of the sequential-or rather than the attribute of the sequential-or parser itself. In the following snippet (assume 'start' has an attribute of type S),
idxspec = '[' >> (start || (':' >> -start)) [ _val = access_index (_r1,lvalue,_1) ] >> ']';
the function 'access_index' is called with an arg3 of type 'optional<S>' rather than the expected 'tuple<optional<S>, optional<optional<S>>>'.
Well, a sequential-or is (attribute-wise) very much the same as a plain sequence: a >> b. That means if you attach an action to the whole thing _1 will refer to the attribute of the first and _2 to the attribute of the second element in that sequence. I'll add a note to the documentation making this clear.
Wrapping the sequential-or expression in a 'repeat' directive as
repeat(1)[start || (':' >> -start)]
solved the problem but obviously gave me an unwanted sequence (albeit with only one element). The attribute type of the above came out to be
vector<tuple<optional<S>, optional<optional<S>>>>
as expected.
To remove the sequence I created a parser directive called 'identity' following the form of 'repeat' which I have attached. My final rule is now
idxspec = '[' >> identity[start || (':' >> -start)] [ _val = access_index (_r1,lvalue,_1) ] >> ']';
which is working fine; the _1 delivers an argument of type
tuple<optional<S>, optional<optional<S>>>
as required. However, I would have expected this behaviour from the first expression. Is this a a proto issue, a spirit issue or have I completely misunderstood something somewhere?
That's expected as well, as your identity[] directive exposes the _whole_ attribute of the embedded parser as its own attribute. Regards Hartmut ------------------- Meet me at BoostCon http://boostcon.com