Boost logo

Boost :

Subject: Re: [boost] [Spirit/Qi] Sequential-or attribute access in semantic action
From: Hartmut Kaiser (hartmut.kaiser_at_[hidden])
Date: 2009-12-04 09:37:34


> 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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk