Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2008-03-02 21:19:03


Larry Evans wrote:
> On 03/02/08 19:39, Eric Niebler wrote:
> [snip]
>> Your problem distills down to:
>>
>> typedef terminal<x> GX; // grammar for x
>> typedef GX::type EX; // expression for x
>>
>> typedef shift_right<GX, GX> SRGX; // grammar for x>>x
>> typedef SRGX::type SREX; // OOPS!
>>
>> You then try to use SREX as a valid expression type, and it is not. It
>> should be:
>>
>> typedef shift_right<EX, EX>::type SREX;
>>
>> The difference is that in the first case, you're creating the type of a
>> right shift expression where the operands are grammars. You really want
>> the operands to be expression types.
>>
>> HTH,
>>
> Yes, thanks. I had actually concluded that, but then thought,
> in that case, the shift_right template arguments can be either
> grammar types or expression types and, depending on which they
> are, the nested type may or may not make sense.

That's not the case. In binary_expr<A,B,C>::type, if B and C are
expressions, ::type is an expression. If they are grammars, ::type is a
grammar. It is merely a matter of convenience that you can leave off the
::type when you want to use binary_expr<> as a grammar.

> That kinda
> bothered me because it was confusing. Someone reading the
> code would have to realize this to avoid confusion.
>
> Here's actually part of what I had written before sent my post:
>
>
>
> b) operator expressions
>
> For each operator grammar instance (see above), O_inst, there's
> the corresponding type of expressions which match that grammar.
> For example, if:
>
> typedef
> O
> < T0
> , T1
> , ...
> , Tn
> >
> O_inst;
> typedef
> O
> < T0::type
> , T1::type
> , ...
> , Tn::type
> >::type
> O_expr;
>
> then:
>
> matches<O_expr,O_inst>
>
> OOPS. This doesn't make sense either because in one instance
> the the template args are grammar types and in the 2nd they're
> expressiont types. Looking at traits.hpp shows:

There's lots of reasons why this generalization is untrue. You can't, in
general, construct an expression type from a grammar type. First of all,
these are recursive data structures. There is no operation you can apply
at the root of such a type that achieves the effect you're after. But
more importantly, most grammar elements (e.g., and_, or_, not_, if_,
switch_, etc.) don't even have a nested ::type.

>
> template<typename Tag, typename T, typename U>
> struct binary_expr : pass_through<binary_expr<Tag, T, U> >
> {
> BOOST_PROTO_NOT_CALLABLE()
> typedef proto::expr<Tag, args2<T, U> > type;
> typedef type proto_base_expr;
> typedef Tag proto_tag;
> typedef T proto_arg0;
> typedef U proto_arg1;
> };
>
> so the subexpression types are grammar types?

Grammars or expressions, whichever. (Note: in the latest download,
binary_expr looks different but behaves the same.)

> I'd be more comfortable if the validity of the nested type
> didn't depend on particular type of the template parameter.

It doesn't.

-- 
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