Hello everybody. With my current project I'm unfortunately still using
Spirit 1.8.x and Phoenix. Having a bit of trouble figuring out the
correct way to do something, hoping somebody can help! It actually
compiles with the exception of some warnings from MSVC - the whole "A
non-const reference may only be bound to an lvalue" warning I'm
thinking it should be an easy fix probably just adding ref() or var() in
the right places, I just can't figure out where.
Here's some source code. The idea is to parse out an expression, and
while doing so, store the operation type for later use at the end of the
parsing, to avoid verbosity in having to do this every time I parse a
different type of expression.
/* Some notes:
* - The closure variable 'oper_function' for assignment_statement is a Boost.Function specifying a function that returns expression_value, and takes two arguments of type expression_value.
* - expression_value is a Boost.Variant.
* - The form of variant's apply_visitor used is "delayed visitation", which returns just a functor with operator() which will do the actual visitation later. This works fine.
* - assign_variable and lookup_variable are Phoenix functions.
* - lhs and rhs closure variables are both expression_value's.
* - I've tried using combinations of var(), val(), and ref() in as many different places as I could think of.
* - The problem is with each of the oper function assignment lines, as well as the "assignment_statement.rhs)," line, which is line 671 in the warnings.
* - Warnings from MSVC are below the code.
*/
assignment_statement
=
(as_lower_d[str_p("set") | str_p("define")]
>> +white_space
>> (name[assignment_statement.name = arg1])
>> longest_d[
// Allow just the assignment of an expression by itself without an operator.
(+white_space>> expression[assignment_statement.rhs = arg1])[assignment_statement.oper_function = actors::deferred_binary_visitcwb::wtl::detail::binary_operations::right_assign >()]
|
// Allow all different types of assignment operators.
(*white_space
>> ( str_p("=") [assignment_statement.oper_function = boost::apply_visitor(actors::binary_opcwb::wtl::detail::binary_operations::right_assign())]
| str_p("+=")[assignment_statement.oper_function = boost::apply_visitor(actors::binary_opcwb::wtl::detail::binary_operations::add())]
| str_p("-=")[assignment_statement.oper_function = boost::apply_visitor(actors::binary_opcwb::wtl::detail::binary_operations::subtract())]
| str_p("/=")[assignment_statement.oper_function = boost::apply_visitor(actors::binary_opcwb::wtl::detail::binary_operations::divide())]
| str_p("*=")[assignment_statement.oper_function = boost::apply_visitor(actors::binary_opcwb::wtl::detail::binary_operations::multiply())]
| str_p("%=")[assignment_statement.oper_function = boost::apply_visitor(actors::binary_opcwb::wtl::detail::binary_operations::modulus())]
)
>> *white_space
>> expression[assignment_statement.rhs = arg1])
])[assign_variable(assignment_statement.name,
assignment_statement.oper_function(
lookup_variable(assignment_statement.name, self._TemplatePtr),
assignment_statement.rhs),
self._TemplatePtr)]
;
/*******************************************************************************
1>------ Build started: Project: spirit_web_template, Configuration: Debug x64 ------
1>Compiling...
1>web_template.cpp
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(659) : error C2220: warning treated as error - no 'object' file generated
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(659) : warning C4239: nonstandard extension used : 'argument' : conversion from 'cwb::wtl::detail::actors::binary_op<_OpType>' to 'cwb::wtl::detail::actors::binary_op<_OpType> &'
1> with
1> [
1> _OpType=cwb::wtl::detail::binary_operations::right_assign
1> ]
1> A non-const reference may only be bound to an lvalue
1> c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(123) : while compiling class template member function 'cwb::wtl::detail::wt_grammar::definition<ScannerT>::definition(const cwb::wtl::detail::wt_grammar&)'
1> with
1> [
1> ScannerT=boost::spirit::scanner,boost::spirit::scanner_policies<>>
1> ]
1> c:\devel\repositories\codexterous\dependencies\boost\boost-1_37\include\boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp(279) : see reference to class template instantiation 'cwb::wtl::detail::wt_grammar::definition<ScannerT>' being compiled
1> with
1> [
1> ScannerT=boost::spirit::scanner,boost::spirit::scanner_policies<>>
1> ]
1> c:\devel\repositories\codexterous\dependencies\boost\boost-1_37\include\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_(RT&,DefinitionT&,const ScannerT&)' being compiled
1> with
1> [
1> ScannerT=boost::spirit::scanner,boost::spirit::scanner_policies<>>,
1> RT=result_t,
1> DefinitionT=definition_t
1> ]
1> c:\devel\repositories\codexterous\dependencies\boost\boost-1_37\include\boost/spirit/home/classic/core/non_terminal/grammar.hpp(55) : see reference to function template instantiation 'boost::spirit::matchboost::spirit::nil_t boost::spirit::impl::grammar_parser_parse<0,cwb::wtl::detail::wt_grammar,boost::spirit::parser_context<>,ScannerT>(const boost::spirit::grammar<DerivedT> *,const ScannerT&)' being compiled
1> with
1> [
1> ScannerT=boost::spirit::scanner,boost::spirit::scanner_policies<>>,
1> DerivedT=cwb::wtl::detail::wt_grammar
1> ]
1> c:\devel\repositories\codexterous\dependencies\boost\boost-1_37\include\boost/spirit/home/classic/core/non_terminal/grammar.hpp(65) : see reference to function template instantiation 'boost::spirit::matchboost::spirit::nil_t boost::spirit::grammar<DerivedT>::parse_main<ScannerT>(const ScannerT&) const' being compiled
1> with
1> [
1> DerivedT=cwb::wtl::detail::wt_grammar,
1> ScannerT=boost::spirit::scanner,boost::spirit::scanner_policies<>>
1> ]
1> c:\devel\repositories\codexterous\dependencies\boost\boost-1_37\include\boost/spirit/home/classic/core/impl/parser.ipp(30) : see reference to function template instantiation 'boost::spirit::matchboost::spirit::nil_t boost::spirit::grammar<DerivedT>::parse>(const ScannerT&) const' being compiled
1> with
1> [
1> DerivedT=cwb::wtl::detail::wt_grammar,
1> IteratorT=std::_String_const_iterator,
1> PoliciesT=boost::spirit::scanner_policies<>,
1> ScannerT=boost::spirit::scanner,boost::spirit::scanner_policies<>>
1> ]
1> .\source\web_template.cpp(98) : see reference to function template instantiation 'boost::spirit::parse_info<IteratorT> boost::spirit::parse<_IterType,DerivedT>(const IteratorT&,const IteratorT&,const boost::spirit::parser<DerivedT> &)' being compiled
1> with
1> [
1> IteratorT=std::_String_const_iterator,
1> _IterType=std::_String_const_iterator,
1> DerivedT=cwb::wtl::detail::wt_grammar
1> ]
1> .\source\web_template.cpp(63) : see reference to function template instantiation 'void cwb::wtl::web_template::_Parse>(_IterType,_IterType)' being compiled
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Alloc=std::allocator<char>,
1> _IterType=std::_String_const_iterator
1> ]
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(660) : warning C4239: nonstandard extension used : 'argument' : conversion from 'cwb::wtl::detail::actors::binary_op<_OpType>' to 'cwb::wtl::detail::actors::binary_op<_OpType> &'
1> with
1> [
1> _OpType=cwb::wtl::detail::binary_operations::add
1> ]
1> A non-const reference may only be bound to an lvalue
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(661) : warning C4239: nonstandard extension used : 'argument' : conversion from 'cwb::wtl::detail::actors::binary_op<_OpType>' to 'cwb::wtl::detail::actors::binary_op<_OpType> &'
1> with
1> [
1> _OpType=cwb::wtl::detail::binary_operations::subtract
1> ]
1> A non-const reference may only be bound to an lvalue
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(662) : warning C4239: nonstandard extension used : 'argument' : conversion from 'cwb::wtl::detail::actors::binary_op<_OpType>' to 'cwb::wtl::detail::actors::binary_op<_OpType> &'
1> with
1> [
1> _OpType=cwb::wtl::detail::binary_operations::divide
1> ]
1> A non-const reference may only be bound to an lvalue
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(663) : warning C4239: nonstandard extension used : 'argument' : conversion from 'cwb::wtl::detail::actors::binary_op<_OpType>' to 'cwb::wtl::detail::actors::binary_op<_OpType> &'
1> with
1> [
1> _OpType=cwb::wtl::detail::binary_operations::multiply
1> ]
1> A non-const reference may only be bound to an lvalue
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(664) : warning C4239: nonstandard extension used : 'argument' : conversion from 'cwb::wtl::detail::actors::binary_op<_OpType>' to 'cwb::wtl::detail::actors::binary_op<_OpType> &'
1> with
1> [
1> _OpType=cwb::wtl::detail::binary_operations::modulus
1> ]
1> A non-const reference may only be bound to an lvalue
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(671) : warning C4239: nonstandard extension used : 'argument' : conversion from 'phoenix::actor<BaseT>' to 'phoenix::actor<BaseT> &'
1> with
1> [
1> BaseT=phoenix::composite,cwb::wtl::expression_value>>>,phoenix::actor>,phoenix::as_actorphoenix::nil_t::type>
1> ]
1> A non-const reference may only be bound to an lvalue
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(659) : warning C4239: nonstandard extension used : 'argument' : conversion from 'cwb::wtl::detail::actors::binary_op<_OpType>' to 'cwb::wtl::detail::actors::binary_op<_OpType> &'
1> with
1> [
1> _OpType=cwb::wtl::detail::binary_operations::right_assign
1> ]
1> A non-const reference may only be bound to an lvalue
1> c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(123) : while compiling class template member function 'cwb::wtl::detail::wt_grammar::definition<ScannerT>::definition(const cwb::wtl::detail::wt_grammar&)'
1> with
1> [
1> ScannerT=boost::spirit::scanner<>
1> ]
1> c:\devel\repositories\codexterous\dependencies\boost\boost-1_37\include\boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp(279) : see reference to class template instantiation 'cwb::wtl::detail::wt_grammar::definition<ScannerT>' being compiled
1> with
1> [
1> ScannerT=boost::spirit::scanner<>
1> ]
1> c:\devel\repositories\codexterous\dependencies\boost\boost-1_37\include\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_(RT&,DefinitionT&,const ScannerT&)' being compiled
1> with
1> [
1> ScannerT=boost::spirit::scanner<>,
1> RT=result_t,
1> DefinitionT=definition_t
1> ]
1> c:\devel\repositories\codexterous\dependencies\boost\boost-1_37\include\boost/spirit/home/classic/core/non_terminal/grammar.hpp(55) : see reference to function template instantiation 'boost::spirit::matchboost::spirit::nil_t boost::spirit::impl::grammar_parser_parse<0,cwb::wtl::detail::wt_grammar,boost::spirit::parser_context<>,ScannerT>(const boost::spirit::grammar<DerivedT> *,const ScannerT&)' being compiled
1> with
1> [
1> ScannerT=boost::spirit::scanner<>,
1> DerivedT=cwb::wtl::detail::wt_grammar
1> ]
1> c:\devel\repositories\codexterous\dependencies\boost\boost-1_37\include\boost/spirit/home/classic/core/non_terminal/grammar.hpp(65) : see reference to function template instantiation 'boost::spirit::matchboost::spirit::nil_t boost::spirit::grammar<DerivedT>::parse_main<ScannerT>(const ScannerT&) const' being compiled
1> with
1> [
1> DerivedT=cwb::wtl::detail::wt_grammar,
1> ScannerT=boost::spirit::scanner<>
1> ]
1> c:\devel\repositories\codexterous\dependencies\boost\boost-1_37\include\boost/spirit/home/classic/core/impl/parser.ipp(30) : see reference to function template instantiation 'boost::spirit::matchboost::spirit::nil_t boost::spirit::grammar<DerivedT>::parse>(const ScannerT&) const' being compiled
1> with
1> [
1> DerivedT=cwb::wtl::detail::wt_grammar,
1> ScannerT=boost::spirit::scanner<>
1> ]
1> .\source\web_template.cpp(98) : see reference to function template instantiation 'boost::spirit::parse_info<IteratorT> boost::spirit::parse<_IterType,DerivedT>(const IteratorT&,const IteratorT&,const boost::spirit::parser<DerivedT> &)' being compiled
1> with
1> [
1> IteratorT=const char *,
1> _IterType=const char *,
1> DerivedT=cwb::wtl::detail::wt_grammar
1> ]
1> .\source\web_template.cpp(84) : see reference to function template instantiation 'void cwb::wtl::web_template::_Parse(_IterType,_IterType)' being compiled
1> with
1> [
1> _IterType=const char *
1> ]
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(660) : warning C4239: nonstandard extension used : 'argument' : conversion from 'cwb::wtl::detail::actors::binary_op<_OpType>' to 'cwb::wtl::detail::actors::binary_op<_OpType> &'
1> with
1> [
1> _OpType=cwb::wtl::detail::binary_operations::add
1> ]
1> A non-const reference may only be bound to an lvalue
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(661) : warning C4239: nonstandard extension used : 'argument' : conversion from 'cwb::wtl::detail::actors::binary_op<_OpType>' to 'cwb::wtl::detail::actors::binary_op<_OpType> &'
1> with
1> [
1> _OpType=cwb::wtl::detail::binary_operations::subtract
1> ]
1> A non-const reference may only be bound to an lvalue
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(662) : warning C4239: nonstandard extension used : 'argument' : conversion from 'cwb::wtl::detail::actors::binary_op<_OpType>' to 'cwb::wtl::detail::actors::binary_op<_OpType> &'
1> with
1> [
1> _OpType=cwb::wtl::detail::binary_operations::divide
1> ]
1> A non-const reference may only be bound to an lvalue
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(663) : warning C4239: nonstandard extension used : 'argument' : conversion from 'cwb::wtl::detail::actors::binary_op<_OpType>' to 'cwb::wtl::detail::actors::binary_op<_OpType> &'
1> with
1> [
1> _OpType=cwb::wtl::detail::binary_operations::multiply
1> ]
1> A non-const reference may only be bound to an lvalue
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(664) : warning C4239: nonstandard extension used : 'argument' : conversion from 'cwb::wtl::detail::actors::binary_op<_OpType>' to 'cwb::wtl::detail::actors::binary_op<_OpType> &'
1> with
1> [
1> _OpType=cwb::wtl::detail::binary_operations::modulus
1> ]
1> A non-const reference may only be bound to an lvalue
1>c:\devel\repositories\codexterous\spirit_web_template\trunk\source\../include/web_template/detail/grammar.hpp(671) : warning C4239: nonstandard extension used : 'argument' : conversion from 'phoenix::actor<BaseT>' to 'phoenix::actor<BaseT> &'
1> with
1> [
1> BaseT=phoenix::composite,cwb::wtl::expression_value>>>,phoenix::actor>,phoenix::as_actorphoenix::nil_t::type>
1> ]
1> A non-const reference may only be bound to an lvalue
*******************************************************************************/