[Spirit Development] Bug using operator >> and > in same sequence

Robert Nelson <[email protected]> Fri, 31 Dec 2010 16:24:51 -0700
Newsgroups gmane.comp.parsers.spirit.devel
Message-ID <[email protected]>
In the current version of trunk, and probably all recent versions,
tuples are not merged properly when the >> and > operator are mixed.
This has the effect of passing a type [[int,int],int] to phoenix,
instead of the expected [int,int,int]  While I did mention before that
I wanted this, I don't want it in this particular situation :)  This
is clearly a bug.
int_ > int_ int_ is a [int,int,int]
int_ >> int_ >> int_ is a [int,int,int]
int_ >> int_ > int_ is a [[int,int],int]
int_ > int_ >> int_ is a [[int,int],int]

The bug is likely in /spirit/home/qi/operator/expect.hpp and
/spirit/home/qi/operator/sequence.hpp

The problem occurs because proto::flatten_tree only flattens trees
constructed with the same symbol.  So mixing symbols results in a
partially flattened tree which does not fit well with the phoenix
placeholders _1, _2, _3, etc that access a specific element of the
tuple.

Here is a program demonstrating the error.

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/home/phoenix/object/construct.hpp>
#include <string>

struct point
{
  int x;
  int y;
  int z;
 point(const int&,const int&,const int&);
};

BOOST_FUSION_ADAPT_STRUCT(point,(int, x) (int, y) (int, z))

int main()
{
  {
    using namespace boost::spirit::qi;
    using namespace boost::phoenix;
    rule<std::string::const_iterator,point()> rule = (int_ >  int_ >>
int_)[_val = construct<point>(_1,_2,_3)];
  }
}

------------------------------------------------------------------------------
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

_______________________________________________
Spirit-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-devel
main.cpp (text/x-c++src, 848 B)
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/home/phoenix/object/new.hpp>
#include <iterator>
#include <string>

struct point
{
 int x;
 int y;
 point(int new_x,int new_y);
};

BOOST_FUSION_ADAPT_STRUCT(point,(int, x) (int, y))

int main()
{
  {
    using namespace boost::spirit::qi;
    using namespace boost::phoenix;
    rule<std::string::const_iterator,int()> int_rule;
    rule<std::string::const_iterator,point*(),boost::spirit::ascii::space_type> rule = (int_rule >> int_)[_val = new_<point>(_1,_2)];
  }
  {
    using namespace boost::spirit::karma;
    using namespace boost::phoenix;
    rule<std::string::iterator,point*()> rule = (int_ << int_)[_0 = *_val];
  }
}