
Joel Falcou wrote:
How can I write a transform that matches expression like
a0+a1+a2+ ... +an (with N +)
You write a grammar.
and turn into a custom node like
sum(a0,a1,...,an)
You use proto::functional::flatten to turn the binary + expression tree into a flat Fusion sequence, and then you use proto::functional::unpack_expr to turn the Fusion sequence into an expression node with any tag you want. See below: #include <iostream> #include <boost/fusion/include/vector.hpp> #include <boost/fusion/include/as_vector.hpp> #include <boost/proto/proto.hpp> namespace mpl = boost::mpl; namespace proto = boost::proto; namespace fusion = boost::fusion; using proto::_; struct Plus : proto::or_< proto::terminal<_> , proto::plus<Plus, Plus> > {}; struct as_vector : proto::callable { template<typename Sig> struct result; template<typename This, typename Seq> struct result<This(Seq)> : fusion::result_of::as_vector< typename boost::remove_reference<Seq>::type > {}; template<typename Seq> typename fusion::result_of::as_vector<Seq const>::type const operator()(Seq const &seq) const { return fusion::as_vector(seq); } }; struct FlattenPlus : proto::when< proto::plus<Plus, Plus> , proto::functional::unpack_expr<proto::tag::plus>( as_vector(proto::functional::flatten(_)) ) > {}; int main() { proto::literal<int> i(0), j(1), k(2), l(3), m(4); proto::display_expr(FlattenPlus()(i+j+k+l+m)); return 0; } This displays: plus( terminal(0) , terminal(1) , terminal(2) , terminal(3) , terminal(4) ) The only reason I need as_vector above is because currently unpack_expr requires a RandomAccessSequence, and a flattened expression is a ForwardSequence. Fixing unpack_expr to handle ForwardSequences is on my TODO list. HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com