
2011/5/11 Daniel F. <the.source@web.de>
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.