Boost logo

Boost :

Subject: [boost] [Spirit/Qi] Sequential-or attribute access in semantic action
From: Adam Butcher (dev.lists_at_[hidden])
Date: 2009-12-04 04:23:12


Hi,

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/quick_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.)

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>>>'.

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?

It may or may not be relevant but I am using both spirit.classic and
spirit 2.1 in the same file. This is historical and will be fixed in time
but I guess it could be important. So far I have had no problems with the
combination however.

Additional info: I am using gcc 4.4.2, stlport 5.1.3 and boost 1.41.0.

Regards,
Adam




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