Boost logo

Boost Users :

Subject: Re: [Boost-users] [phoenix][v3] Evaluating a terminal expression in the custom actions class.
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2011-03-03 01:38:58


On Thu, Mar 3, 2011 at 2:42 AM, Eric Niebler <eric_at_[hidden]> wrote:
> On 3/3/2011 7:46 AM, Alexander Ospin wrote:
>> 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
>>
>> 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.

There is a different between phoenix::call and proto::call:
phoenix::call expects just a callable type that can be called with the
Context and the children.
proto::call expects a function type which specifies exactly how that
Callable should be called.

>> 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.
>
> Agree that there should be some default behavior for call with
> terminals, and that passing the whole terminal rather than the value is
> probably the best default.

Alright ... I just wasn't sure about that ... I added the
specialization that just forwards the whole terminal.

> --
> Eric Niebler
> BoostPro Computing
> http://www.boostpro.com
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users


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