[Spirit Devel] ADAPT_ADT causes recursive grammars to not compile

Robert Nelson <[email protected]> Thu, 18 Nov 2010 19:55:24 -0700
Newsgroups gmane.comp.parsers.spirit.devel
Message-ID <[email protected]>
Why does the following fail to compile?

struct y
{
  const std::vector<y>& get() const;
  void set(const std::vector<y>&);
};

BOOST_FUSION_ADAPT_ADT(y,(std::vector<y>,std::vector<y>,obj.get(),obj.set(val)))

int main()
{
  using namespace boost::spirit::qi;
  using namespace boost::phoenix;
  boost::spirit::qi::rule<std::string::const_iterator,y()> b;
  b = (*b)[at_c<0>(_val) = _1]; //ERROR is here
}

It seems to be a result of fusion loop unrolling or something.  The
libraries don't like the fact we are parsing a vector of y's and storing
them in y.  The above code works with seemingly slight modification, but I
need the above implementation in my application or a workaround.  Attached
is main.cpp, a file with only the offending code and three_main.cpp which
has 2 other similar grammars, both of which will compile.  I think the error
is the result of a bug/feature in the fusion and/or spirit::qi library.
 Please help.

Thanks
--Robert Nelson

------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
Spend less time writing and  rewriting code and more time creating great
experiences on the web. Be a part of the beta today
http://p.sf.net/sfu/msIE9-sfdev2dev

_______________________________________________
Spirit-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-devel
main.cpp (text/x-c++src, 678 B)
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/adt/adapt_adt.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <string>


struct y
{
  const std::vector<y>& get() const;
  void set(const std::vector<y>&); 
};

BOOST_FUSION_ADAPT_ADT(y,(std::vector<y>,std::vector<y>,obj.get(),obj.set(val)))

int main()
{
  using namespace boost::spirit::qi;
  using namespace boost::phoenix;
  boost::spirit::qi::rule<std::string::const_iterator,y()> b;
  b = (*b)[at_c<0>(_val) = _1]; //ERROR is here
}
three_main.cpp (text/x-c++src, 1.2 KB)
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/adt/adapt_adt.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <string>


struct x
{
  std::vector<x> vec;
};

BOOST_FUSION_ADAPT_STRUCT(x,(std::vector<x>,vec))

struct y
{
  const std::vector<y>& get() const;
  void set(const std::vector<y>&); 
};

BOOST_FUSION_ADAPT_ADT(y,(std::vector<y>,std::vector<y>,obj.get(),obj.set(val)))

struct z
{
  const std::vector<x>& get() const;
  void set(const std::vector<x>&); 
};

BOOST_FUSION_ADAPT_ADT(z,(std::vector<x>,std::vector<x>,obj.get(),obj.set(val)))

int main()
{
  using namespace boost::spirit::qi;
  using namespace boost::phoenix;
  boost::spirit::qi::rule<std::string::const_iterator,x()> a;
  boost::spirit::qi::rule<std::string::const_iterator,y()> b;
  boost::spirit::qi::rule<std::string::const_iterator,z()> c;
  a = (*a)[at_c<0>(_val) = _1]; //this version is ok
  b = (*b)[at_c<0>(_val) = _1]; //ERROR is here
  c = (*a)[at_c<0>(_val) = _1]; //this version is ok too
}