Opened 12 years ago

Closed 12 years ago

#4425 closed Feature Requests (wontfix)

qi::action ignores phoenix actor return value

Reported by: anonymous Owned by: Joel de Guzman
Milestone: Boost 1.44.0 Component: spirit
Version: Boost 1.44.0 Severity: Optimization
Keywords: Cc:

Description

Hello,

this is not really a feature request but rather a design issue: It seems to me there is a discrepancy between the behavior of phoenix actors in comparison to functors called from qi actions. In a functor, you can fail an otherwise successful parser by changing the "pass" argument. Intuitively, I would have thought that a phoenix actor such as eps [phoenix::val(true) == phoenix::val(false)] should also fail the parser. However, action_dispatch ignores the return value from the actor and returns the pass argument, which the phoenix actor does not modify. I'm not that well-versed in the insides of phoenix, but I can imagine that the actors know nothing about the pass argument. Should it not rather be action_dispatch, which in that case should perhaps AND the actor return value with the pass argument, so as to catch such cases?

Just a thought from an otherwise contended spirit user:-)

Attachments (1)

action_dispatch.hpp (3.6 KB ) - added by anonymous 12 years ago.

Download all attachments as: .zip

Change History (4)

by anonymous, 12 years ago

Attachment: action_dispatch.hpp added

in reply to:  description comment:1 by anonymous, 12 years ago

Hello again,

I've added a step in action_dispatch that checks the return type of phoenix actors: If it is a boolean, the return value is &&ed with the pass argument value. Here is the function:

template <typename Eval, typename Attribute, typename Context> bool operator()(

phoenix::actor<Eval> const& f, Attribute& attr, Context& context)

{

bool pass = true; typename pass_attribute<Component, Attribute>::type attr_wrap(attr);

typedef typename remove_reference<

typename Eval::template result<

phoenix::basic_environment<

typename remove_reference<Attribute>::type, typename remove_reference<Context>::type, typename remove_reference<bool>::type> >::type >::type

return_type;

return_type* ret = 0;

return call(f, attr_wrap, context, pass, ret);

}

template<typename Eval, typename Attribute, typename Context, typename Return> inline bool call(

phoenix::actor<Eval> const& f, Attribute& attr, Context& context, bool& pass, Return)

const {

f(attr, context, pass); return pass;

}

template<typename Eval, typename Attribute, typename Context> inline bool call(

phoenix::actor<Eval> const& f, Attribute& attr, Context& context, bool& pass, bool*)

const {

bool ret = f(attr, context, pass); return pass = pass && ret;

}

comment:2 by Joel de Guzman, 12 years ago

This is not necessary. If you want an actor to be able to fail a parse, just give it the pass argument by using the placeholder _pass. See http://tinyurl.com/3xrfcsd. Example: p[_pass = false] will always fail parsing.

comment:3 by Hartmut Kaiser, 12 years ago

Resolution: wontfix
Status: newclosed
Note: See TracTickets for help on using tickets.