Boost logo

Proto :

Subject: Re: [proto] Manipulating an expression tree
From: Karsten Ahnert (karsten.ahnert_at_[hidden])
Date: 2011-04-15 11:45:26


Bart, your example was great. I think I start to understand Protos
transforms now. Sorry for the late reply, I have two large projects at
the moment. But I try to work on this problems in every free minute.

@All: Are somewhere more examples and docs for proto transforms. They
are quite complicated and maybe a bit underrepresented in the official
users guide.

On 04/10/2011 10:32 AM, Bart Janssens wrote:
> On Sun, Apr 10, 2011 at 10:59 AM, Karsten Ahnert
> <karsten.ahnert_at_[hidden]> wrote:
>> Ok, I think I understand how you replace the nodes, but I don't
>> understand how you parse the tree and how you access the value member.
>> Do you use contexts and eval()? Could you please show a small piece of
>> code? Thanks,
>
> No, I'm not using contexts, I access the value member from a primitive
> transform. My transform to evaluate multiplications looks like this:
>
> /// Primitive transform for evaluating multiplication and store the
> result back in the multiplies node
> template<typename GrammarT>
> struct EigenProductEval :
> boost::proto::transform< EigenProductEval<GrammarT> >
> {
> template<typename ExprT, typename StateT, typename DataT>
> struct impl : boost::proto::transform_impl<ExprT, StateT, DataT>
> {
> // Skipped series of typedefs here, result_type can be defined as
> double for the example below
> result_type operator ()(typename impl::expr_param expr, typename
> impl::state_param state, typename impl::data_param data) const
> {
> expr.value = GrammarT()(boost::proto::left(expr), state, data) *
> GrammarT()(boost::proto::right(expr), state, data);
> return expr.value;
> }
> };
> };
>
> // This grammar matches the multiplications and evaluates them using
> the above primitive transform:
> template<typename GrammarT>
> struct EigenMultiplication :
> boost::proto::when
> <
> boost::proto::multiplies<GrammarT, GrammarT>,
> EigenProductEval<GrammarT>
> >
> {
> };
>
> //To add a concrete example on how to use this to multiply two
> doubles, storing the value in the mult expression (untested):
> struct MultDoubles :
> boost::proto::or_
> <
> boost::proto::when // Double terminals are replaced by their value
> <
> boost::proto::terminal<double>,
> boost::proto::_value
> >,
> EigenMultiplication<MultDoubles> // Evaluates multiplication
>>
> {
> };
>
> // Now evaluate an expression
> MultDoubles()(WrapExpression()(boost::proto::lit(2.) * boost::proto::lit(2.)));
>
> The template parameter GrammarT allows me to embed these into a larger
> grammar, enforcing that the left and right term of the product match
> this grammar (MultDoubles in the example).
>
> I don't see an easy way to do this with contexts, I've started out
> with contexts as well, but I found that my code got very complex and
> unreadable in the end. The grammars are much more powerful, and in the
> end result in much cleaner code. The trick is to read them like they
> use their own special language, not try and interpret them as C++.
> When making the switch, I moved the data that I used to store in the
> contexts to the data argument of the transforms (the 3rd argument of
> operator()).
>
> Cheers,
>

-- 
Dr. Karsten Ahnert
Ambrosys GmbH - Gesellschaft für Management komplexer Systeme
Geschwister-Scholl-Str. 63a
D-14471 Potsdam
Tel: +4917682001688
Fax: +493319791300
Ambrosys GmbH - Gesellschaft für Management komplexer Systems
Gesellschaft mit beschränkter Haftung
Sitz der Gesellschaft: Geschwister-Scholl-Str. 63a, 14471 Potsdam
Registergericht: Amtsgericht Potsdam, HRB 21228 P
Geschäftsführer: Dr. Karsten Ahnert, Dr. Markus Abel

Proto list run by eric at boostpro.com