In addition to the βmanualβ approach suggested by Mike, you can
- use convenience shell rule
- use
distinct parser in Spirit repository
1. Use a convenient wrapper
I just remembered, once I came up with this quick and dirty assistant:
static const qi::rule<It, qi::unused_type(const char*)> kw = qi::lit(qi::_r1) >> !qi::alnum;
What could you use (using +"lit" to decompose the ref-array into const char* ):
stmt = kw(+"if") >> '(' >> expr >> ')' >> block >> -(kw(+"else") >> block) ;
You can make it much more convenient.
template <std::size_t N> static auto kw(char const (&keyword)[N]) -> qi::rule<Iterator> { // qi::lit has problems with char arrays, use pointer instead. return qi::lit(+keyword) >> !qi::alnum; }
So you can
kw_if = kw("if"); kw_then = kw("then"); kw_else = kw("else"); kw_and = kw("and"); kw_or = kw("or"); kw_not = kw("not");
2. Use the distinct directive from the Spirit repository
In addition to the βmanualβ approach suggested by Mike, you can use the distinct parser directive from the Spirit repository:
int main() { using namespace spirit_test; using namespace boost::spirit; { using namespace boost::spirit::ascii; qi::rule<char const*, space_type> r; r = distinct::keyword["description"] >> -lit(':') >> distinct::keyword["ident"]; BOOST_TEST(test("description ident", r, space)); BOOST_TEST(test("description:ident", r, space)); BOOST_TEST(test("description: ident", r, space)); BOOST_TEST(!test("descriptionident", r, space)); } return boost::report_errors(); }
source share