Boost logo

Boost Users :

Subject: Re: [Boost-users] [Proto] Detecting series of operator in grammar
From: Eric Niebler (eric_at_[hidden])
Date: 2008-12-03 13:28:40


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

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net