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

Boost list run by bdawes at, gregod at, cpdaniel at, john at