I have a SPIRIT grammar containing:
small %= char_("a-z");
large %= char_("A-Z");
digit %= char_("0-9");
symbol %= char_("!#$%&*+./<=>?@\\^|~:") | char_('-');
special %= char_("(),;[]`{}");
graphic %= small | large | symbol | digit | special | char_('"') | char_('\'');
dashes %= lit("--")>>*lit("-");
varsym %= ((symbol-lit(':'))>>*symbol)-reservedop-dashes;
reservedop %= string("..") | string(":") | string("::") | string("=") | string("\\") | string("|") | string("<-") | string("->") | string("@") | string("~") | string("=>");
Spirit doesn't require a separate lexer and parser (See What are the Benefits of Using a Lexer?), and I've followed this practice by defining the first six rules as qi::rule<Iterator, char()>
, and the last three rules as qi::rule<Iterator, std::string()>
. Note that these rules therefore have no whitespace skipper.
Also, note that I'm trying to parse things as varsym
, and not as reservedop
. I'm only using reservedop
to exclude things in the varsym rule.
The exclusion of reserved words in varsym doesn't work though. ==
should be a valid varsym
but its ignored because it begins with =
which is a reservedop
.
The answer to another question suggested defining something like
reservedop_ %= reservedop >> !symbol
and then using that. I'm not sure this works, though, and it certainly doesn't seem very elegant.
What is the right way to do this in BOOST Spirit?