#ifndef _constituent_ #define _constituent_ #include #include #include #include #include #include #include #include #include #include #include #include //#include namespace ecgp { namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; namespace fusion = boost::fusion; namespace phoenix = boost::phoenix; struct constituent { int constituent_kind; std::string left; std::string right; std::vector probs; void print(std::ostream& o) const { using namespace std; o << constituent_kind << " " << left << " " << right << "["; BOOST_FOREACH(double p, probs) { o << p << ", "; } o << "]"; o << endl; } }; std::ostream& operator<<(std::ostream& o, const constituent& b) { b.print(o); return o; }; } BOOST_FUSION_ADAPT_STRUCT( // global scope required ecgp::constituent, (int, constituent_kind) (std::string, left) (std::string, right) (std::vector, probs) ) namespace ecgp { template struct constituent_grammar : qi::grammar(),ascii::space_type> { constituent_grammar() : constituent_grammar::base_type(start,"constituents") { using namespace qi::labels; using qi::eps; using qi::lit; using qi::_val; using qi::fail; using qi::lexeme; using qi::double_; using qi::on_error; using ascii::alpha; using ascii::alnum; using phoenix::construct; using phoenix::val; constitkind %= ((lit("extraposed") [_val = 2]) | (lit("optional") [_val = 1]) | (eps [_val = 0]) ); probs %= ("[" > (double_ % ',') > "]") | eps; id %= lexeme[(('_' | alpha) >> *(alnum | '_' | '-'))]; /* Questions: Why can't I use an expectation point before the second "id"? See attached error message. Why are the parentheses necessary in the expression (id > ':')? How should I cause on_error for a missing '[', for example, in probs? */ start %= (constitkind >> ((id > ':') >> id) >> probs) % ","; // COMPILES // start %= (constitkind >> ((id > ':') > id) >> probs) % ","; // FAILS constitkind.name("constituent_kind"); id.name("identifier"); probs.name("probabilities"); on_error ( start , std::cout << val("constituent: expected ") << _4 // what failed? << val(" here: \"") << construct(_3, _2) // iterators to error-pos, end << val("\"") << std::endl ); } qi::rule id; qi::rule constitkind; qi::rule(), ascii::space_type> probs; qi::rule(), ascii::space_type> start; }; } #endif