Boost logo

Boost :

From: troy d. straszheim (troy_at_[hidden])
Date: 2008-05-29 12:15:19


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/construct.hpp
http://svn.boost.org/trac/boost/browser/trunk/boost/spirit/home/qi/detail/assign_to.hpp

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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk