Boost logo

Boost Users :

From: Hartmut Kaiser (hartmut.kaiser_at_[hidden])
Date: 2008-05-16 10:05:47


Hi,

> I have a problem with a sematic action when I use int_p.
>
> I have the following declaration:
>
> array_declaration =
> confix_p(LEFT_BRACKET, int_p[new_int] ,RIGHT_BRACKET);
>
> and new_int is defined in the following way:
>
> typedef function< void( int ) > Int_action;
> Int_action new_int ( bind( &SemanticActions::new_int,
> &self.actions_, _1 ) );
>
> in this case I get allways (VS2005) the error message:
> Error 1 error C2064: term does not evaluate to a function taking 2
> arguments
> C:\Programme\boost\boost_1_34_1\boost\spirit\core\scanner\scanner.hpp
> 146
>
> if I use instead of the Int_action a action
>
> typedef function< void( const char*, const char* ) > Str_action;
>
> I have no errors during compiling.
>
> What I make wrong?

The answer is quite tricky.
The confix_p parser does a internal refactoring of the wrapped parser
expression, i.e.

    confix_p(l, int_p[f], r)

get's refactored to

    l >> (int_p - r)[f] >> r

This is done to make the confix_p parser do what's expected even in the
general case.
Here is the corresponding comment from the confix.hpp file:

// If the body parser is an action_parser_category type parser (a
parser
// with an attached semantic action) we have to do something special.
This
// happens, if the user wrote something like:
//
// confix_p(open, body[f], close)
//
// where 'body' is the parser matching the body of the confix sequence
// and 'f' is a functor to be called after matching the body. If we
would
// do nothing, the resulting code would parse the sequence as follows:
//
// start >> (body[f] - close) >> close
//
// what in most cases is not what the user expects.
// (If this _is_ what you've expected, then please use the confix_p
// generator function 'direct()', which will inhibit
// re-attaching the actor to the body parser).
//
// To make the confix parser behave as expected:
//
// start >> (body - close)[f] >> close
//
// the actor attached to the 'body' parser has to be re-attached to the
// (body - close) parser construct, which will make the resulting
confix
// parser 'do the right thing'. This refactoring is done by the help of
// the refactoring parsers (see the files refactoring.[hi]pp).

Well, in your case it's not exactly what you've been expecting and this
refactoring isn't needed (because RIGHT_BRACKET is not a possible subset of
any of the possible int_p matches).

As the comment says, you can prevent this refactoring by just writing:

    confix_p.direct(LEFT_BRACKET, int_p[new_int], RIGHT_BRACKET)

instead.

HTH
Regards Hartmut

PS: Please direct future inquiries wrt Spirit to the Spirit mailing list.


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