|
Boost Users : |
Subject: Re: [Boost-users] [Proto] implementing an computer algebra systemwith proto
From: Dave Jenkins (david_at_[hidden])
Date: 2009-01-28 10:38:07
"Kim Kuen Tang" <kuentang_at_[hidden]> wrote in message
news:497F760C.1030408_at_vodafone.de...
> this version of Solve
> has the feature of calling itsel recursively. So writing "Solve()( var_ +
> 1 + 3 = 2 )" is enough to produce "var_ = 2-1-3".
> It takes me about 1 to 2 hour to figure this out. So i would say that
> proto is not difficult to learn and you really will gain more.
Thanks, Kim Tang. I see that your example works.
However, when I tried playing with it I found one mystery.
It seems that any placeholder will match, not just the one you specify in
the grammar.
Below is an example program showing what I mean.
I would expect that only placeholder1 would match,
but both placeholder1 and placeholder2 match and produce the same output.
I even tried using proto::exact to get the program to reject placeholder2,
but that made no difference.
#include <iostream>
#include <boost/proto/proto.hpp>
namespace mpl = boost::mpl;
namespace proto = boost::proto;
namespace fusion = boost::fusion;
using proto::_;
// Work around annoyng msvc compiler bugs ...
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
#define _left(x) call<proto::_left(x)>
#define _right(x) call<proto::_right(x)>
#define _make_minus(x,y) call<proto::_make_minus(x,y)>
#define _make_plus(x,y) call<proto::_make_plus(x,y)>
#define _make_assign(x,y) call<proto::_make_assign(x,y)>
#endif
struct placeholder1
{
friend std::ostream &operator <<(std::ostream &sout, placeholder1)
{
return sout << "var1_";
}
};
struct placeholder2
{
friend std::ostream &operator <<(std::ostream &sout, placeholder2)
{
return sout << "var2_";
}
};
proto::terminal<placeholder1>::type const var1_ = {{}};
proto::terminal<placeholder2>::type const var2_ = {{}};
struct Solve
: proto::when<
// Match "var1_ + x = y"
proto::assign<
proto::plus<
proto::terminal<proto::exact<placeholder1>>
, _>
, _ >
// Rewrite as "var1_ = y - x"
, proto::_make_assign(
proto::_left(proto::_left) ,
proto::_make_minus(
proto::_right,
proto::_right(proto::_left)
)
)
>
{};
int main()
{
proto::display_expr( var1_ + 1 = 2 );
proto::display_expr( Solve()( var1_ + 1 = 2 ) );
proto::display_expr( var2_ + 1 = 2 );
proto::display_expr( Solve()( var2_ + 1 = 2 ) );
}
>
> The next step will be to extend the grammar with the feature of
> transforming such expression "1+2+var_+3=4" into
> this "var_=4-1-2-3".
I would be interested in your solution to this also.
Thanks,
Dave Jenkins
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