
On 13 May 2010, at 4:39 PM, Hartmut Kaiser wrote:
/* Hello,
This code (second copy attached) compiles to recognize dotlists, ie "a", "a.b", etc. I want to report on incomplete list errors of the following kind
a. a.#
The parser now detects such errors by failing to parse them completely. Instead I want to expect an id after a '.'.
In dotlist_grammar() I wanted to replace this expression
start %= (id % '.') ;
with this one
start %= (id >> (*('.' > id))) ; // XXX
'>>' has difference operator precedence than '>', which means that Spirit is not able to flatten the whole expression leading to the attribute type mismatch you're seeing.
but it won't compile. Neither will this
start %= (id >> (*('.' >> id))) ; // XXX
Attribute-wise this will work. The problem is that the function signature you're attaching doesn't match the attribute type exposed by the expression it is attached to. It now exposes a fusion::vector<std::string, std::vector<std::string> >.
What's wrong? Is there a difference between the synthesized attributes of the two alternative list expressions? Or is it a different bug?
P.S. Both expressions seem to work for int_ instead of id.
HTH Regards Hartmut
--------------- Meet me at BoostCon www.boostcon.com
/* This code (compilable copy attached) compiles to recognize dotlists, ie (string % '.'), with the added expectation that an id will follow a '.'. The solution is unsatisfactory because it requires a structure to contain a dotlist, and because it uses explicit semantic actions. Do you have any suggestions about how to obviate the semantic actions? The following pseudo-code illustrates something I don't know how to do, although I am pretty sure the solution is obvious to Spirit/ Fusion users. If that's true, I think it will solve the problem of the extraneous structure. This pseudo-grammar exposes attribute vector<string> instead of some structure. What I want is to push a recognized string onto that vector, rather than onto a part of a structure. That is what I mean below by "_val.push_back(_1)" If you can show me the expression which does what I need, I thank you. template <typename Iterator> struct slotchain_grammar : qi::grammar<Iterator, vector<string> (), space> { slotchain_grammar() : slotchain_grammar::base_type(start) { using namespace qi::labels; using phoenix::at_c; using phoenix::push_back; start = id [ "_val.push_back(_1)" ] >> *('.' > id [ "_val.push_back(_1)" ]) ; } id_grammar<Iterator> id; qi::rule<Iterator, vector<string>(), space> start; }; */