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