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 mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto

Reply via email to