
Hey Hartmut, Hartmut Kaiser wrote:
What problem have you hit?
Here's the error: gfilt -o example4 example4.cpp -I ../boost/trunk -lstdc++ (where example4.cpp is: BD Software STL Message Decryptor v3.10 for gcc 2/3/4 ../boost/trunk/boost/spirit/home/qi/detail/assign_to.hpp: In function 'void boost::spirit::qi::detail::construct_::construct( unsigned int &, const __normal_iterator<char *, string> & , const __normal_iterator<char *, string> & )': ../boost/trunk/boost/spirit/home/qi/detail/assign_to.hpp:70: instantiated from 'void boost::spirit::qi::detail::assign_to( const __normal_iterator<char *, string> & , const __normal_iterator<char *, string> &, unsigned int & )' ../boost/trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_token.hpp:348: instantiated from 'void boost::spirit::lex::construct( unsigned int & , boost::spirit::lex::lexertl_token< __normal_iterator<char *, string> , boost::mpl::vector<unsigned int, string>, mpl_::bool_<true> > & )' ../boost/trunk/boost/spirit/home/qi/detail/assign_to.hpp:92: instantiated from 'void boost::spirit::qi::detail::assign_to( boost::spirit::lex::lexertl_token< __normal_iterator<char *, string> , boost::mpl::vector<unsigned int, string>, mpl_::bool_<true> > &, unsigned int & )' ../boost/trunk/boost/spirit/home/lex/lexer/token_def.hpp:125: instantiated from 'bool boost::spirit::lex::token_def<unsigned int, char, unsigned int> ::parse( boost::spirit::lex::lexertl_iterator< boost::spirit::lex::lexertl_functor< boost::spirit::lex::lexertl_token< __normal_iterator<char *, string> , boost::mpl::vector<unsigned int, string> , mpl_::bool_<true> >, __normal_iterator<char *, string>, mpl_::bool_<false> , mpl_::bool_<true> > > & (skip to bottom of stack) example4.cpp:239: instantiated from here ../boost/trunk/boost/spirit/home/qi/detail/assign_to.hpp:27: error: functional cast expression list treated as compound expression ../boost/trunk/boost/spirit/home/qi/detail/assign_to.hpp:27: error: invalid cast from type 'const __normal_iterator<char *, string>' to type 'unsigned int' example4.cpp:239 is just 'return 0;' from main(). Foo. I discovered that I could toggle the error by removing 'tok.constant[_val = _1]' from this part of example4's : expression = tok.identifier [ _val = _1 ] | tok.constant [ _val = _1 ] // problem here ; The 'tok.constant [_val = _1 ]' ends up here, in the first construct() in assign_to.hpp: /////////////////////////////////////////////////////////////////////// // This is used to allow to overload of the attribute creation for // arbitrary types /////////////////////////////////////////////////////////////////////// template <typename Attribute, typename Iterator> inline void construct(Attribute& attr, Iterator const& first, Iterator const& last) { attr = Attribute(first, last); } so you get attr = unsigned int(first, last); and boom. In the (working) case of tok.identifier, attr is a string, and it gets constructed directly from the two iterators, no problem.
It's supposed to work as follows:
- Any parser uses one of the assign_to() overloads to assign it's attribute value to the specified destination. - The assign_to() functions use construct overloads to do the conversion from an iterator range to the requested type (if appropriate). This distinction has been made decouple Spirit specifics from the conversion itself and to allow the user to provide his/her own construct() overloads for custom parsers (to be found via ADL). - Some of the (predefined) construct() functions use Spirit parsers themselves to do the conversion. But here we use only parser primitives which provide their attributes as (already converted) values, not as iterator ranges.
I still have a hard time to see your problem. The construct() functions use qi::parse only for the conversion of iterator ranges to the attribute type, so there shouldn't be any cyclic dependencies.
Thanks for the explanation, I'm digging round again with those points in mind, seeing more than I did last time. Note that the namespace boost::spirit::qi::detail::construct_ appears in *two* different places: one in construct.hpp (where I see a sensible-looking wall of overloads for primitive type, some of which call parse(), as you say), and also at the top of assign_to.hpp, which looks to my untrained eye like it might be a placeholder. http://svn.boost.org/trac/boost/browser/trunk/boost/spirit/home/qi/detail/co... http://svn.boost.org/trac/boost/browser/trunk/boost/spirit/home/qi/detail/as... It was when I tried to redirect the calls into the assign_to.hpp version of ...::construct_ over to the construct.hpp version of ...::construct_ that this unsightly tailspin began. Looking back at the other error that had been posted that I thought was the same... maybe not. I was up all night, sorry. I hope that's clear. Thanks for looking at this. -t
HTH Regards Hartmut
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost