#include #include #include #include namespace qi = boost::spirit::qi; namespace px = boost::phoenix; typedef std::string::const_iterator iterator_t; typedef qi::rule rule_t; template inline bool parse_full(const std::string& input, const Expr& expr) { iterator_t first(input.begin()), last(input.end()); bool result = qi::phrase_parse(first, last, expr, boost::spirit::ascii::space); return first == input.end() && result; } void no_op() {} int main(int argc, char *argv[]) { int attr = -1; // "Static" version - Works fine! /* rule_t grammar; rule_t ruleA = qi::char_('a')[qi::_r1 = px::val(0)]; rule_t ruleB = qi::char_('b')[qi::_r1 = px::val(1)]; rule_t ruleC = qi::char_('c')[qi::_r1 = px::val(2)]; grammar = ruleA(qi::_r1) | //[no_op] ruleB(qi::_r1) | //[no_op] ruleC(qi::_r1); //[no_op] */ // "Dynamic" version - Does not compile! :( /* std::vector 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::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 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::iterator i(rules.begin()), last(rules.end()); qi::rule 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]; // Tests if(parse_full("a", grammar(px::ref(attr)))) std::cout << attr << std::endl; // Should print: 0 if(parse_full("b", grammar(px::ref(attr)))) std::cout << attr << std::endl; // Should print: 1 if(parse_full("c", grammar(px::ref(attr)))) std::cout << attr << std::endl; // Should print: 2 std::cin.ignore(std::numeric_limits::max(), '\n'); return 0; }