Re: [Spirit Development][Phoenix]Assignment of fusion tuples fails in semantic actions.

Christopher Schmidt <[email protected]> Thu, 30 Dec 2010 15:21:03 +0100
Newsgroups gmane.comp.parsers.spirit.devel
Message-ID <[email protected]>
Robert Nelson schrieb:
> I am trying to assign a fusion tuple to a fusion adapted struct in a
> semantic action, but it fails to compile.  It says that there is no
> equals operator defined.  I did include the phoenix_operator header
> this time ;)
> I could of course write the = operator in the struct, but wouldn't
> that kind of defeat the purpose of adapting it as a fusion sequence in
> the first place?  They are both proper fusion sequences; I really
> think that assignment should be taken care of automatically.
> 
> This rule looks like it should work out of the box, but it doesn't.
> rule<std::string::iterator,point()> value_rule = (int_ >> int_)[_val = _0];
> 
> Is this a bug, or do I need to write a custom = operator that takes a
> fusion struct as a parameter?
> 
> Here is the full program.
> 
> 
> #include <boost/spirit/include/qi.hpp>
> #include <boost/fusion/adapted/struct/adapt_struct.hpp>
> #include <boost/spirit/include/phoenix_fusion.hpp>
> #include <boost/spirit/include/phoenix_operator.hpp>
> #include <boost/spirit/include/phoenix_core.hpp>
> #include <string>
> 
> struct point
> {
>  int x;
>  int y;
>  //point(const boost::fusion::vector2<int, int>& right); //why would I
> need to manually write this?
> };
> 
> BOOST_FUSION_ADAPT_STRUCT(point,(int, x) (int, y))
> 
> int main()
> {
>   using namespace boost::spirit::qi;
>   rule<std::string::iterator,point()> value_rule = (int_ >> int_)[_val = _0];
> }

This does not look like a bug to me. '[_val = _0]' is nothing but an
assignment operator invocation, and this should fail as there is no
suitable operator= in point.

You could use BOOST_FUSION_DEFINE_STRUCT to define point. This macro
implicitly generates a nice operator= that works with any fusion sequence

#include <boost/fusion/adapted/struct/define_struct.hpp>
#include <boost/preprocessor/empty.hpp>
BOOST_FUSION_DEFINE_STRUCT(BOOST_PP_EMPTY(),point,(int, x) (int, y))

Other than that, you can refine your semantic actions using direct
access to the fusion elements via phoenix's at_c & friends.

-Christopher


------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and, 
should the need arise, upgrade to a full multi-node Oracle RAC database 
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl