Boost logo

Boost Users :

Subject: [Boost-users] [proto] need explanation in implementing distributive law
From: Kim Kuen Tang (kuentang_at_[hidden])
Date: 2010-03-22 16:11:45


Hi all,

i would like to implement a grammar that transform a*(b+c) to a*b+a*c
where a,b and c are terminals. The implementation of this grammar is
straightforward and should compile. However i got errors that i dont
understand.
Below is the code that reproduces the errors.

Thanks for any help,
Kim

# include <boost/cstdlib.hpp>
# include <boost/proto/proto.hpp>
# include <boost/fusion/container/list/cons.hpp>

# include <boost/proto/tags.hpp>
# include <boost/proto/make_expr.hpp>

# define PRECISION_MAKE_tag(name)
        \
struct name
                                   \
{
                                       \
    friend std::ostream& operator<< (std::ostream& s, name const&)
       \
    {
                                       \
    return s<< #name;
                             \
    }
                                       \
};

# define PRECISION_MAKE_terminal(name)
            \
proto::terminal< tag::name >::type const name = {{}}

namespace proto = boost::proto;

namespace tag{
    PRECISION_MAKE_tag(a);
    PRECISION_MAKE_tag(b);
    PRECISION_MAKE_tag(c);
}

namespace mpl = boost::mpl;
namespace fusion = boost::fusion;
using proto::_;

struct DistributiveLaw
    : proto::or_<
        proto::when<
              proto::multiplies< proto::terminal< _ > , proto::plus< _,
_ > >
            , proto::plus<
                  
proto::multiplies<proto::_left,proto::_left(proto::_right)>
                ,
proto::multiplies<proto::_left,proto::_right(proto::_right)>
                //, proto::_right(proto::_right)
>(
                  
proto::multiplies<proto::_left,proto::_left(proto::_right)>
                  (proto::_left,proto::_left(proto::_right))
                ,
proto::multiplies<proto::_left,proto::_right(proto::_right)>
                  (proto::_left,proto::_right(proto::_right))
                //, proto::_right(proto::_right)
              )
>
        , proto::otherwise<proto::nary_expr<_,
proto::vararg<DistributiveLaw> > >
>
{};
   

PRECISION_MAKE_terminal(a);
PRECISION_MAKE_terminal(b);
PRECISION_MAKE_terminal(c);

# undef PRECISION_MAKE_tag
# undef PRECISION_MAKE_terminal

int main()
{
    proto::display_expr(a*(b+c));
   
    proto::display_expr(DistributiveLaw()( a*(b+c) ));
    return boost::exit_success;
}


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