Boost logo

Boost :

Subject: Re: [boost] [spirit][qi] Dynamically combine Boost.Spirit.Qi rules at runtime
From: TONGARI (tongari95_at_[hidden])
Date: 2011-05-11 13:42:03


2011/5/11 Daniel F. <the.source_at_[hidden]>

> Just to let everybody know, I found a slightly contorted version that seems
> to work. It uses a phoenix function to keep adding rules until there are no
> more left. This is the phoenix function:
>
> struct get_next_impl
> {
> template<typename F>
> struct result { typedef rule_t type; };
>
> std::vector<rule_t>::iterator& i;
> std::vector<rule_t>::iterator& j;
>
> get_next_impl(std::vector<rule_t>::iterator& _i,
> std::vector<rule_t>::iterator& _j) : i(_i), j(_j) {}
>
> rule_t operator()(px::function<get_next_impl>& get_next) const
> {
> rule_t next;
>
> if(i==j) return qi::eps(false);
>
> return (*i++)(qi::_r1)[no_op] | (qi::eps[px::ref(next) =
> get_next(px::ref(get_next))] >> next(qi::_r1));
> }
> };
>
> And here's the example adapted to use it:
>
>
> 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());
>
> px::function<get_next_impl> get_next = get_next_impl(i, last);
>
> rule_t grammar;
> rule_t next;
>
> grammar = qi::eps[px::ref(next) = get_next(px::ref(get_next))] >>
> next(qi::_r1);
>
> So far I haven't experienced any unexpected behavior.
>

It's a interesting idea, I never thought like that before.
But I doubt that if the "rule_t next;" living inside the function's scope
could ever be passed out.


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