
I have another question in general on Spirit.Qi. I read the manual many times and I still can't figure out how to read 'words' from the parser. In the following example I want to parse the name of something but I can not use the semantic assignment on std::string. ? The pattern is matched if I disable the assignment line but it doesn't compile with the line "[ref(name) = _1]". Again this is boost 1.43 with gcc 4.4.
#include
#include #include using boost::spirit::qi::double_; using boost::spirit::qi::int_; using boost::spirit::qi::lexeme; using boost::spirit::qi::char_; using boost::spirit::qi::_1; using boost::spirit::qi::phrase_parse; using boost::spirit::ascii::space; using boost::phoenix::ref;
int main(){ std::string test_line = " atom -1.4275 -1.84343 -1.9255 1 center_atom 12"; std::string::iterator first = test_line.begin(), last = test_line.end(); double x=9999., y=9999., z=9999.; int type=-1; std::string name ; int index=-1; bool parsed = phrase_parse(first, last, ( "atom" >> double_[ref(x) = _1] >> double_[ref(y) = _1] >> double_[ref(z) = _1] >> int_[ref(type) = _1] >> (+char_-' ') [ref(name) = _1] // < problem in this line, it
My guess is that you meant to write: lexeme[+(char_-' ') [phx::ref(name) += _1]] adding the matched characters one by one to the string and avoiding to skip the spaces in between characters. The expression +~char_(' ') is equivalent but more efficient, btw. It means 'match everything but ' ' at least once'.
doesn't compile >> int_[ref(index) = _1] ), space ); if(not parsed) std::clog << "can not interpret line, values read can be incomplete" << std::endl; std::clog <<"just read: x = " << x << " y = " << y << " z = " << z << " type = " << type << " name = " << name << " index = " << index << std::endl; return 0; }
As a rule, I'd suggest to avoid semantic actions altogether. If you write: bool parsed = phrase_parse(first, last, "atom" >> double_ >> double_ >> double_ >> int_ >> lexeme[+~char_(' ')] >> int_, space, x, y, z, type, name, index ); you get the same result, just a lot simpler and cleaner. Regards Hartmut --------------- http://boost-spirit.com