|
Boost Users : |
Subject: Re: [Boost-users] [phoenix][v3] Evaluating a terminal expression in the custom actions class.
From: Alexander Ospin (aospin_at_[hidden])
Date: 2011-03-02 19:46:59
02.03.2011 19:00, Thomas Heller пиÑеÑ:
> On Wed, Mar 2, 2011 at 3:03 PM, Alexander Ospin<aospin_at_[hidden]> wrote:
>> Is it possible to evaluate terminal and custom_terminal expressions in the
>> some custom actions class? For instance how to implement "terminal_eval" to
>> print something in the following code?
>>
>> #include<boost/phoenix/phoenix.hpp>
>> #include<iostream>
>>
>> using namespace boost;
>>
>> struct actions
>> {
>> template<typename Rule, typename Dummy = void> struct when;
>> };
>>
>> template<>
>> struct actions::when<phoenix::rule::terminal> :
>> phoenix::call<terminal_eval> {};
>>
>> int main()
>> {
>> int var = 11;
>> phoenix::eval(phoenix::val(var), phoenix::context(int(), actions()));
>> return 0;
>> }
>>
>>
>> I've tried to use the following form, but encountered some compiler errors:
>> (GCC-4.2.1[FreeBSD], boost and phoenix were taken from SVN, latest versions)
>>
>> struct terminal_eval
>> {
>> typedef void result_type;
>> template<typename Context, typename Expr>
>> result_type operator ()(Context const&ctx, Expr const&expr)
>> {
>> std::cout<< "terminal"<< std::endl;
>> }
>> };
>
> Hi,
>
> phoenix::call does not work with terminals (which have an arity of 0).
> The reason for this is because I didn't want to dictate what should be
> passed to the eval function, the possibilities are: the value of the
> terminal, or the proto::terminal type itself, the reason i couldn't
> decide is because phoenix::call passes along proto expressions to the
> to be called function object, and not the result of the evaluation.
>
> You're code will work by doing the following:
>
> template<>
> struct actions::when<phoenix::rule::terminal> :
> proto::call<terminal_eval(phoenix::_ctx, proto::_)>
> {};
>
> or:
>
> template<>
> struct actions::when<phoenix::rule::terminal> :
> proto::call<terminal_eval(phoenix::_ctx, proto::_value)>
> {};
>
> HTH,
> Thomas
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
Thanks, I understood the problem, but your solution doesn't work (same errors)
because detail::call_impl uses proto::arity_of<Expr>::value for Arity parameter
where Expr is staying the same (terminal or custom_terminal) and there are no
template specialization for Arity = 0 as you pointed. Of course if I specify in
my code boost::phoenix::detail::call_impl for zero arity, I can ever use my code
from the initial post of this thread, but in my opinion it is not the best
option to externally use detail parts of the library.
Can you explain more clearly why it is a problem to select between passing
expression value and expression itself? I didn't understand you last phrase, but
from the usage point of view, I think, passing an expression itself is a good
option, because you can still transform an expression tree like in the inverse
example (same coding style) and in the same time easily get an expression value
by calling inside evaluator the proto::value function instead of phoenix::eval.
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