[Proto] Detecting series of operator in grammar

How can I write a transform that matches expression like a0+a1+a2+ ... +an (with N +) and turn into a custom node like sum(a0,a1,...,an) Thanks in advance -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

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

Eric Niebler a écrit :
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:
I was roaming around flatten so guess I only missed the as_vector trick. I guess this means that this "n-ary" plus expression node can be then latter be matched by another grammar defined like (simple version ofc) : struct some_grammar : nary_expr<plus,vararg<_> > {}; ? -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Joel Falcou wrote:
Eric Niebler a écrit :
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:
I was roaming around flatten so guess I only missed the as_vector trick. I guess this means that this "n-ary" plus expression node can be then latter be matched by another grammar defined like (simple version ofc) :
struct some_grammar : nary_expr<plus,vararg<_> > {};
Yep. I forgot to mention that you need to be aware of BOOST_PROTO_MAX_ARITY when unpacking sequences into expression nodes. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler a écrit :
I forgot to mention that you need to be aware of BOOST_PROTO_MAX_ARITY when unpacking sequences into expression nodes. Is this symbol safely re-definable ? What's its base value ?
-- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Joel Falcou wrote:
Eric Niebler a écrit :
I forgot to mention that you need to be aware of BOOST_PROTO_MAX_ARITY when unpacking sequences into expression nodes. Is this symbol safely re-definable ? What's its base value ?
Yes. Check the docs. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler wrote: <snip>
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.
OK, proto::unpack_expr now works with Fusion Forward Sequences, so the ugly as_vector hack in my earlier mail is no longer necessary. I'll merge to release in a few days. -- Eric Niebler BoostPro Computing http://www.boostpro.com
participants (2)
-
Eric Niebler
-
Joel Falcou