
Larry Evans wrote:
On 04/04/2007 02:49 PM, Eric Niebler wrote: [snip]
behaviors you want. For this, you write a domain-specific tree transformation by writing out your DSEL's grammar and attaching transforms to your grammar's rules.
This is where proto::or_ and proto::and_ come in. Imagine in your DSEL, only terminals of type int and char* are allowed. Then you might define a Terminal rule in your grammar as follows:
struct Terminal : proto::or_< proto::terminal<int> , proto::terminal<char*> > {};
When you write your tree transform, you might want to attach some transformation to the Terminal rule to, for example, turn char* into spirit::string_parser, or whatever.
I'm still unclear about and_. I've looked at matches.hpp where both or_ and and_ are defined and it looks like, as their names suggest, that they are predicates of some sort. Now I can understand how or_ works as you described above for defining a grammar's terminals; however, I'm unclear about and_. Is an and_ instantiation a possible 2nd arg to matches and, in this case, matches tests it's first argument to see that it satisfies both arguments to the and_?
That's correct. and_ isn't as commonly needed as or_, but it's still handy. There is also if_, which evaluates an mpl lambda. So, for instance, here's a rule in a meta-grammar that matches scalar terminals: struct ScalarTerminal : proto::and_< proto::terminal<proto::_> , proto::if_<is_scalar<proto::result_of::arg<mpl::_> > > > {};
Proto's meta-grammar facilities are good for more than just tree transformations, by the way. You can use them with proto::matches<> to make compile-time decisions based on the structure of an expression.
So matches<Expr,Grammar> tests Expr to see if it matches the meta-grammar, Grammar? IOW, and_<X,Y> and or_<X,Y> are possible values of Grammar in matches<Expr,Grammar>?
Yes. And types that inherit from them, like ScalarTerminal above. -- Eric Niebler Boost Consulting www.boost-consulting.com