#include #include #include #include namespace client { namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; struct word { std::string identifier; std::string word_type; void print(std::ostream& o) const { using namespace std; o << identifier << " "; o << (word_type.empty() ? "untyped": word_type) << endl; } }; std::ostream& operator<<(std::ostream& o, const word& b) { b.print(o); }; } BOOST_FUSION_ADAPT_STRUCT( // global scope required client::word, (std::string, identifier) (std::string, word_type) ) namespace client { struct test { std::vector words; std::string filler; test() {}; test(const test& that) { words = that.words; filler = that.filler; }; void print(std::ostream& o) const { using namespace std; o << words.size() << " words" << endl; { // why does this work... ///////////////////////////////////// int i=0; BOOST_FOREACH(client::word w, words) { using namespace std; o << i++ << ": " << w; o << endl; // <-------- } ///////////////////////////////////// } o << endl; { // while this crashes? ///////////////////////////////////// int i=0; BOOST_FOREACH(client::word w, words) { using namespace std; o << i++ << ": " << w << endl; // <-------- } ///////////////////////////////////// } } }; std::ostream& operator<<(std::ostream& o, const test& b) { b.print(o); }; } BOOST_FUSION_ADAPT_STRUCT( // global scope required client::test, (std::vector,words) (std::string,filler) ) namespace client { template struct word_grammar : qi::grammar { word_grammar() : word_grammar::base_type(start) { using qi::eps; using qi::lit; using qi::lexeme; using ascii::alnum; using ascii::alpha; id %= lexeme[('_' | alpha) >> *(alnum | '_' | '-')]; wtyp = ((':' >> id) | eps); start %= id >> wtyp; } qi::rule wtyp; qi::rule id; qi::rule start; }; template struct test_grammar : qi::grammar { test_grammar() : test_grammar::base_type(start) { using qi::lit; using qi::eps; using qi::lexeme; using ascii::alnum; using ascii::alpha; words %= (word % ','); id %= lexeme[('_' | alpha) >> *(alnum | '_' | '-')]; start %= ((lit("words") >> words) | eps) >> ((lit("constraints")>> id) | eps); } qi::rule id; client::word_grammar word; qi::rule(), ascii::space_type> words; qi::rule start; }; } int main() { using boost::spirit::ascii::space; typedef std::string::const_iterator string_iterator; client::test tst; client::test_grammar c; std::string str; str += "words word0:type0, word1, word2"; std::string::const_iterator iter = str.begin(); std::string::const_iterator end = str.end(); bool r = phrase_parse(iter, end, c, space, tst); if (r && iter == end) { std::cout << "OK\n"; std::cout << tst; } else { std::string rest(iter, end); std::cout << "fail: " << rest << "\n"; } return 0; }