![]() |
Home | Libraries | People | FAQ | More |
We've already seen how to use expression generators like proto::terminal<>
and proto::shift_right<>
as grammars. We've also seen proto::or_<>
,
which we can use to express a set of alternate grammars. There are a
few others of interest; in particular, proto::if_<>
,
proto::and_<>
and proto::not_<>
.
The proto::not_<>
template is the simplest.
It takes a grammar as a template parameter and logically negates it;
not_<Grammar>
will match any expression that Grammar
does not match.
The proto::if_<>
template is used
together with a Proto transform that is evaluated against expression
types to find matches. (Proto transforms will be described later.)
The proto::and_<>
template is like
proto::or_<>
, except that each
argument of the proto::and_<>
must match in order
for the proto::and_<>
to match. As an example,
consider the definition of CharString
above that uses proto::exact<>
. It could have been
written without proto::exact<>
as follows:
struct CharString : proto::and_< proto::terminal< proto::_ > , proto::if_< boost::is_same< proto::_value, char const * >() > > {};
This says that a CharString
must be a terminal, and its value type must be the
same as char const
*
. Notice the template argument
of proto::if_<>
: boost::is_same< proto::_value, char const * >()
. This is Proto transform that compares
the value type of a terminal to char
const *
.
The proto::if_<>
template has a couple
of variants. In addition to if_<Condition>
you can also say if_<Condition, ThenGrammar>
and if_<Condition, ThenGrammar, ElseGrammar>
. These let you select one sub-grammar
or another based on the Condition
.