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