How can I prevent the Boost Spirit Symbol parser from accepting a keyword (s) when it starts with a valid keyword (s). I would like the constructor not to parse "ONEMORE as a whole and not be able to parse" ONE, because it is a valid keyword, and then "MORE" crashes.
Here is the actual code output below:
Keyword as a number: 1 Keyword as a number: 2 Keyword as a number: 1 Invalid keyword: MORETHREE
And I like it:
Keyword as a number: 1 Keyword as a number: 2 Invalid keyword: ONEMORE Keyword as a number: 3
The code is just a sample to get the point.
#include <boost/config/warning_disable.hpp> #include <boost/spirit/include/qi.hpp> #include <iostream> #include <string> using namespace std; namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; void printNumber( unsigned u ) { cout << "Keyword as a number: " << u << endl; } void printInvalidKeyword( const string &s ) { cout << "Invalid keyword: " << s << endl; } template <typename Iterator> struct keyword_parser : qi::grammar<Iterator, ascii::space_type> { struct mySymbols_ : qi::symbols<char, unsigned> { mySymbols_() { add ("ONE" , 1) ("TWO" , 2) ("THREE" , 2) ; } } mySymbols; keyword_parser() : keyword_parser::base_type(start) { using qi::_1; using qi::raw; using ascii::char_; start %= *( mySymbols[&printNumber] | invalid[&printInvalidKeyword] ); invalid = +char_; } qi::rule<Iterator, ascii::space_type> start; qi::rule<Iterator, std::string(), ascii::space_type> invalid; }; int main() { using boost::spirit::ascii::space; typedef std::string::const_iterator iterator_type; typedef keyword_parser<iterator_type> keyword_parser; std::string s = "ONE TWO ONEMORE THREE"; iterator_type b = s.begin(); iterator_type e = s.end(); phrase_parse(b, e, keyword_parser(), space); return 0; }
source share