|
Boost : |
Subject: Re: [boost] [spirit][qi] Dynamically combine Boost.Spirit.Qi rules at runtime
From: Daniel F. (the.source_at_[hidden])
Date: 2011-05-07 17:55:22
Thank you! I posted on stackoverflow first to make sure it's not some
simple beginners mistake, but since I didn't get an answer I figured it
was worth a shot here. :)
Looking forward to seeing what you come up with.
Daniel
On 5/7/2011 11:42 PM, Hartmut Kaiser wrote:
>> I recently tried to combine an arbitrary number of rules as alternatives
>> in Boost.Spirit.Qi. Since rules are implemented as objects it seemed
>> feasible to me. My motivation was to make certain parts of my grammar
>> easily extensible. Unfortunately, I ran into some problems, so I wrote a
>> simple program (see attachment for the complete code) demonstrating the
>> unexpected behavior. Here's the key part:
>>
>> // "Dynamic" version - Does not compile! :(
>> /*
>> std::vector<rule_t> rules;
>>
>> rules.push_back(qi::char_('a')[qi::_r1 = px::val(0)]);
>> rules.push_back(qi::char_('b')[qi::_r1 = px::val(1)]);
>> rules.push_back(qi::char_('c')[qi::_r1 = px::val(2)]);
>>
>> std::vector<rule_t>::iterator i(rules.begin()), last(rules.end());
>>
>> rule_t grammar;
>>
>> grammar = (*i)(qi::_r1); //[no_op]
>>
>> for(++i; i!=last; ++i)
>> {
>> grammar = grammar.copy() | (*i)(qi::_r1); //[no_op] } */
>>
>> // "Dynamic" version - Kind of works! :-/
>>
>> std::vector<rule_t> rules;
>>
>> rules.push_back(qi::char_('a')[qi::_r1 = px::val(0)]);
>> rules.push_back(qi::char_('b')[qi::_r1 = px::val(1)]);
>> rules.push_back(qi::char_('c')[qi::_r1 = px::val(2)]);
>>
>> std::vector<rule_t>::iterator i(rules.begin()), last(rules.end());
>>
>> qi::rule<iterator_t, int()> temp;
>>
>> temp = (*i)(qi::_val); //[no_op]
>>
>> for(++i; i!=last; ++i)
>> {
>> temp = temp.copy() | (*i)(qi::_val); //[no_op] }
>>
>> rule_t grammar;
>>
>> grammar = temp[qi::_r1 = qi::_1];
>>
>> Now, I suppose that the first version (commented out) doesn't compile,
>> because I'm not passing the inherited attribute down to grammar.copy().
>> I would love to know if there's a better way of doing this than the
>> workaround that is the second version.
>>
>> The second version actually compiles and it seems to do the right thing.
>> However, once I attach a simple semantic action as indicated in the code
>> using comments (see "[no_op]"), the behavior becomes really weird.
>> Rather than printing 0,1,2 as before, the program prints 0,0,2. So I'm
>> wondering, is what I'm trying to accomplish resulting in undefined
>> behavior? Is this a bug? Or, quite possibly, am I just using something
>> (e.g. semantic actions?) the wrong way?
>
> Just as a heads up: I saw your question on stackoverflow and I'm currently
> trying to find a solution for you.
>
> Regards Hartmut
> ---------------
> http://boost-spirit.com
>
>
>
> _______________________________________________
> Unsubscribe& other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk