Boost logo

Proto :

Subject: Re: [proto] vararg + fold
From: Eric Niebler (eric_at_[hidden])
Date: 2010-07-21 08:29:57


On 7/21/2010 7:43 AM, Christophe Henry wrote:
> Hi,
>
> I want a grammar B which parses a comma-separated list of expressions
> matching another grammar A and returning a mpl::vector of expressions
> transformed using A. Something like:
> (AExpr, AExpr, ...).
>
> I managed to do it this way:
>
> struct A...
>
> template <class T>
> struct make_vector
> {
> typedef boost::mpl::vector<T> type;
> };
>
> struct B
> : proto::or_<
> proto::when <
> A,
> make_vector<A(proto::_)>()

You could simply use mpl::vector1<A(proto::_)>() and not bother with
make_vector.

> >,
> proto::when <
> proto::comma<B,A>,
> boost::mpl::push_back<
> B(proto::_left),
> A(proto::_right) >()
> >
> >
> {};
>
> This seems to work but shouts for a fold so I tried:
>
> struct B
> : proto::when <
> proto::comma< A,proto::vararg<A> >, // => probably wrong

Wrong, but harmless. Comma is a binary operator, so comma<A, A> has you
covered, unless some perverted person does: make_expr<tag::comma>(w,x,y,z)

> proto::fold_tree<
> proto::_
> , ::boost::mpl::vector<>()
> , ::boost::mpl::push_back<proto::_state, A(proto::_) >()
> >
> >
> {};

If A is a grammar as implied above, you can simplify the function to:

  mpl::push_back<proto::_state, A>()

The current element in the sequence will be operated on by default.

> This seems to work in most cases (I suppose by sheer luck) but doesn't
> parse correctly if no comma at all: (AExpr)

Whoops! Your grammar doesn't handle expressions that aren't comma
expressions. Before passing an expr to a grammar, first try asserting
that it matches the grammar. If it doesn't evaluating the grammar's
transform with the expr is a precondition violation. In this case, the
grammar check is ignored and the fold_tree is executed against whatever
expression you passed in. That will fold the tree on the top-most node
type; e.g. if it's tag::plus, you'll fold on plus.

> So I suppose that at least the first part of when is wrong.
> Any idea how to make it work?

Depends on what you're trying to do. What should happen when you pass
something that isn't a comma expression?

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

Proto list run by eric at boostpro.com