|
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