Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2007-04-06 10:28:38


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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk