Boost logo

Boost :

Subject: Re: [boost] [spirit][qi] Dynamically combine Boost.Spirit.Qi rules at runtime
From: Hartmut Kaiser (hartmut.kaiser_at_[hidden])
Date: 2011-05-07 17:42:26


> 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


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