Boost logo

Boost Users :

Subject: [Boost-users] [Spirit] Closure arg2 compiler error
From: Anders Dalvander (boost_at_[hidden])
Date: 2008-10-23 12:41:41


Hi,

I get a compiler error (cannot convert from 'const phoenix::nil_t' to
'int') when using arg2 of a two value closure. arg1 works fine, but not
arg2. I don't understand what I have done wrong.

Visual Studio 2005 SP1
boost 1.36.0

Anyone got any ideas?

Best regards,
Anders Dalvander

Output:

Compiling...
SpiritClosureTest.cpp
d:\prog\boost_1_36_0\boost\spirit\home\classic\phoenix\operators.hpp(446)
: error C2440: '=' : cannot convert from 'const phoenix::nil_t' to 'int'
       No user-defined-conversion operator available that can perform
this conversion, or the operator cannot be called
       
d:\prog\boost_1_36_0\boost\spirit\home\classic\phoenix\operators.hpp(446)
: while compiling class template member function 'int
&phoenix::binary_operator<TagT,T0,T1>::eval(T0 &,const T1 &)'
       with
       [
           TagT=phoenix::assign_op,
           T0=int,
           T1=phoenix::nil_t
       ]
       
d:\prog\boost_1_36_0\boost\spirit\home\classic\phoenix\operators.hpp(1017)
: see reference to class template instantiation
'phoenix::binary_operator<TagT,T0,T1>' being compiled
       with
       [
           TagT=phoenix::assign_op,
           T0=int,
           T1=phoenix::nil_t
       ]
       
d:\prog\boost_1_36_0\boost\spirit\home\classic\phoenix\composite.hpp(237)
: see reference to class template instantiation
'phoenix::assign_op::result<T0,T1>' being compiled
       with
       [
           T0=int,
           T1=phoenix::nil_t
       ]
       
d:\prog\boost_1_36_0\boost\spirit\home\classic\phoenix\composite.hpp(267)
: see reference to class template instantiation
'phoenix::composite2_result<OperationT,TupleT,A,B>' being compiled
       with
       [
           OperationT=phoenix::assign_op,
           TupleT=phoenix::tuple<>,
           
A=phoenix::actor<phoenix::closure_member<0,phoenix::closure<int,int,phoenix::nil_t>>>,

           B=phoenix::actor<phoenix::argument<0>>
       ]
       
d:\prog\boost_1_36_0\boost\spirit\home\classic\phoenix\actor.hpp(122) :
see reference to class template instantiation
'phoenix::composite<OperationT,A,B,C>::result<TupleT>' being compiled
       with
       [
           OperationT=phoenix::assign_op,
           
A=phoenix::actor<phoenix::closure_member<0,phoenix::closure<int,int,phoenix::nil_t>>>,

           B=phoenix::actor<phoenix::argument<0>>,
           C=phoenix::as_actor<phoenix::nil_t>::type,
           TupleT=phoenix::tuple<>
       ]
       
d:\prog\boost_1_36_0\boost\spirit\home\classic\phoenix\actor.hpp(133) :
see reference to class template instantiation
'phoenix::actor_result<ActorT,TupleT>' being compiled
       with
       [
           
ActorT=phoenix::composite<phoenix::assign_op,phoenix::actor<phoenix::closure_member<0,phoenix::closure<int,int,phoenix::nil_t>>>,phoenix::actor<phoenix::argument<0>>,phoenix::as_actor<phoenix::nil_t>::type>,

           TupleT=phoenix::tuple<>
       ]
       c:\documents and settings\anders\my documents\visual studio
2005\projects\spiritclosuretest\spiritclosuretest\spiritclosuretest.cpp(25)
: see reference to class template instantiation 'phoenix::actor<BaseT>'
being compiled
       with
       [
           
BaseT=phoenix::composite<phoenix::assign_op,phoenix::actor<phoenix::closure_member<0,phoenix::closure<int,int,phoenix::nil_t>>>,phoenix::actor<phoenix::argument<0>>,phoenix::as_actor<phoenix::nil_t>::type>

       ]
       c:\documents and settings\anders\my documents\visual studio
2005\projects\spiritclosuretest\spiritclosuretest\spiritclosuretest.cpp(16)
: while compiling class template member function
'my_grammar::definition<ScannerT>::definition(const my_grammar &)'
       with
       [
           ScannerT=boost::spirit::scanner<>
       ]
       
d:\prog\boost_1_36_0\boost\spirit\home\classic\core\non_terminal\impl\grammar.ipp(279)
: see reference to class template instantiation
'my_grammar::definition<ScannerT>' being compiled
       with
       [
           ScannerT=boost::spirit::scanner<>
       ]
       
d:\prog\boost_1_36_0\boost\spirit\home\classic\core\non_terminal\impl\grammar.ipp(298)
: see reference to function template instantiation 'void
boost::spirit::impl::call_helper<0>::do_<result_t,definition_t,ScannerT>(RT
&,DefinitionT &,const ScannerT &)' being compiled
       with
       [
           ScannerT=boost::spirit::scanner<>,
           RT=result_t,
           DefinitionT=definition_t
       ]
       
d:\prog\boost_1_36_0\boost\spirit\home\classic\core\non_terminal\grammar.hpp(55)
: see reference to function template instantiation
'boost::spirit::match<boost::spirit::nil_t>
boost::spirit::impl::grammar_parser_parse<0,my_grammar,boost::spirit::parser_context<>,ScannerT>(const
boost::spirit::grammar<DerivedT> *,const ScannerT &)' being compiled
       with
       [
           ScannerT=boost::spirit::scanner<>,
           DerivedT=my_grammar
       ]
       
d:\prog\boost_1_36_0\boost\spirit\home\classic\core\non_terminal\grammar.hpp(65)
: see reference to function template instantiation
'boost::spirit::match<boost::spirit::nil_t>
boost::spirit::grammar<DerivedT>::parse_main<ScannerT>(const ScannerT &)
const' being compiled
       with
       [
           DerivedT=my_grammar,
           ScannerT=boost::spirit::scanner<>
       ]
       
d:\prog\boost_1_36_0\boost\spirit\home\classic\core\impl\parser.ipp(30)
: see reference to function template instantiation
'boost::spirit::match<boost::spirit::nil_t>
boost::spirit::grammar<DerivedT>::parse<boost::spirit::scanner<>>(const
ScannerT &) const' being compiled
       with
       [
           DerivedT=my_grammar,
           ScannerT=boost::spirit::scanner<>
       ]
       
d:\prog\boost_1_36_0\boost\spirit\home\classic\core\impl\parser.ipp(47)
: see reference to function template instantiation
'boost::spirit::parse_info<IteratorT> boost::spirit::parse<const
CharT*,DerivedT>(const IteratorT &,const IteratorT &,const
boost::spirit::parser<DerivedT> &)' being compiled
       with
       [
           IteratorT=const char *,
           CharT=char,
           DerivedT=my_grammar
       ]
       c:\documents and settings\anders\my documents\visual studio
2005\projects\spiritclosuretest\spiritclosuretest\spiritclosuretest.cpp(54)
: see reference to function template instantiation
'boost::spirit::parse_info<IteratorT>
boost::spirit::parse<char,DerivedT>(const CharT *,const
boost::spirit::parser<DerivedT> &)' being compiled
       with
       [
           IteratorT=const char *,
           DerivedT=my_grammar,
           CharT=char
       ]

Source:

#include <boost/spirit.hpp>
#include <boost/spirit/phoenix/primitives.hpp>
#include <iostream>

struct result_closure : boost::spirit::closure<result_closure, int, int>
{
  member1 res1;
  member2 res2;
};

struct my_grammar : boost::spirit::grammar<my_grammar>
{
  template <typename ScannerT>
  struct definition
  {
     explicit definition(const my_grammar& self)
     {
        using boost::spirit::ch_p;
        using boost::spirit::uint_p;
        using phoenix::var;
        using phoenix::arg1;
        using phoenix::arg2;

        exp
           = uint_p[exp.res1 = arg1] >> ch_p('-') >> uint_p[exp.res2 =
arg1]
           ;

        root
           = exp[var(self.i) = arg2] // compiler error here if using arg2.
           ; // arg1 works fine though.
     }

     boost::spirit::rule<ScannerT, result_closure::context_t> exp;
     boost::spirit::rule<ScannerT> root;

     const boost::spirit::rule<ScannerT>& start() const
     {
        return root;
     }
  };

  my_grammar(int& i_)
   : i(i_)
  {
  }

  int& i;
};

int main()
{
  int i;
  my_grammar g(i);
  if (parse("1-2", g).full)
  {
     std::cout << i << "\n";
  }
}



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net