以下代码是我正在尝试做的简化版本。基本上,我有一个容器数据成员struct(玩具代码中的int_holder)。我想插入一个对象(在本例中为int)并返回父qi :: rule指向新插入对象的指针。
我通过引用将int_holder传递给语法,以便在解析时用值填充它,因此int_holder将是语法的继承属性。代码:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <vector>
namespace qi=boost::spirit::qi;
namespace phoenix=boost::phoenix;
struct int_holder
{
int_holder() {}
std::vector<int> ints;
};
struct insert_impl
{
template<class, class>
struct result { typedef int* type; };
int* operator() (int_holder& holder, int i) const
{
holder.ints.push_back (i);
return &holder.ints.back();
}
};
template<class Iterator>
struct my_grammar : qi::grammar<Iterator, int*(int_holder&)>
{
my_grammar () : my_grammar::base_type (start)
, insert (insert_impl())
{
using qi::_val;
using qi::int_;
using qi::_r1;
using qi::_1;
using phoenix::ref;
start = +next(_val) [_val = _1];
next = int_ [_val = insert(_r1, _1)];
}
qi::rule<Iterator, int*(int_holder&)> start, next;
phoenix::function<insert_impl> insert;
};
int main ()
{
using phoenix::ref;
const char* p="1";
int* last;
int_holder holder;
my_grammar<const char*> g;
qi::parse (p, p+1, g(ref(holder)), last);
}
代码无法编译,并显示以下错误消息:
In file included from
/opt/local/include/boost/fusion/sequence/intrinsic/detail/segmented_begin.hpp:16:0,
from /opt/local/include/boost/fusion/sequence/intrinsic/begin.hpp:17, from
/opt/local/include/boost/fusion/iterator/segmented_iterator.hpp:12, from
/opt/local/include/boost/fusion/sequence/intrinsic/detail/segmented_end.hpp:11, from
/opt/local/include/boost/fusion/sequence/intrinsic/end.hpp:17, from
/opt/local/include/boost/fusion/sequence/intrinsic/back.hpp:11, from
/opt/local/include/boost/fusion/sequence/intrinsic.hpp:11, from
/opt/local/include/boost/fusion/include/intrinsic.hpp:10, from
/opt/local/include/boost/proto/fusion.hpp:22, from
/opt/local/include/boost/proto/core.hpp:21, from
/opt/local/include/boost/proto/proto.hpp:12, from
/opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19, from
/opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14, from
/opt/local/include/boost/spirit/home/qi/action/action.hpp:14, from
/opt/local/include/boost/spirit/home/qi/action.hpp:14, from
/opt/local/include/boost/spirit/home/qi.hpp:14, from
/opt/local/include/boost/spirit/include/qi.hpp:16, from test_qi.cpp:1:
/opt/local/include/boost/fusion/container/list/cons.hpp: In instantiation of
'boost::fusion::cons<Car, Cdr>::cons(const boost::fusion::cons<Car2, Cdr2>&) [with Car2 =
int*&; Cdr2 = boost::fusion::nil; Car = int_holder&; Cdr = boost::fusion::nil]':
/opt/local/include/boost/spirit/home/support/context.hpp:117:20: required from
'boost::spirit::context<Attributes, Locals>::context(typename Attributes::car_type, const
Args&, Context&) [with Args =
boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_>; Context = boost::spirit::context<boost::fusion::cons<int*&,
boost::fusion::cons<int_holder&, boost::fusion::nil> >, boost::fusion::vector0<> >;
Attributes = boost::fusion::cons<int*&, boost::fusion::cons<int_holder&,
boost::fusion::nil> >; Locals = boost::fusion::vector0<>; typename Attributes::car_type =
int*&]' /opt/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:343:67: required
from 'bool boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::parse(Iterator&, const
Iterator&, Context&, const Skipper&, Attribute&, const Params&) const [with Context =
boost::spirit::context<boost::fusion::cons<int*&, boost::fusion::cons<int_holder&,
boost::fusion::nil> >, boost::fusion::vector0<> >; Skipper = boost::spirit::unused_type;
Attribute = int*; Params =
boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_>; Iterator = const char*; T1 = int*(int_holder&); T2 =
boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 =
boost::spirit::unused_type]'
/opt/local/include/boost/spirit/home/qi/nonterminal/detail/parameterized.hpp:48:79:
required from 'bool boost::spirit::qi::parameterized_nonterminal<Subject,
Params>::parse(Iterator&, const Iterator&, Context&, const Skipper&, Attribute&) const
[with Iterator = const char*; Context = boost::spirit::context<boost::fusion::cons<int*&,
boost::fusion::cons<int_holder&, boost::fusion::nil> >, boost::fusion::vector0<> >;
Skipper = boost::spirit::unused_type; Attribute = int*; Subject =
boost::spirit::qi::rule<const char*, int*(int_holder&), boost::spirit::unused_type,
boost::spirit::unused_type, boost::spirit::unused_type>; Params =
boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_>]' /opt/local/include/boost/spirit/home/qi/action/action.hpp:65:13:
required from 'bool boost::spirit::qi::action<Subject, Action>::parse(Iterator&, const
Iterator&, Context&, const Skipper&, Attribute&) const [with Iterator = const char*;
Context = boost::spirit::context<boost::fusion::cons<int*&,
boost::fusion::cons<int_holder&, boost::fusion::nil> >, boost::fusion::vector0<> >;
Skipper = boost::spirit::unused_type; Attribute = boost::spirit::unused_type; Subject =
boost::spirit::qi::parameterized_nonterminal<boost::spirit::qi::rule<const char*,
int*(int_holder&), boost::spirit::unused_type, boost::spirit::unused_type,
boost::spirit::unused_type>,
boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_> >; Action =
boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
>]' /opt/local/include/boost/spirit/home/qi/detail/fail_function.hpp:38:72: required from
'bool boost::spirit::qi::detail::fail_function<Iterator, Context,
Skipper>::operator()(const Component&, Attribute&) const [with Component =
boost::spirit::qi::action<boost::spirit::qi::parameterized_nonterminal<boost::spirit::qi::rule<const
char*, int*(int_holder&), boost::spirit::unused_type, boost::spirit::unused_type,
boost::spirit::unused_type>,
boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_> >,
boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
> >; Attribute = boost::spirit::unused_type; Iterator = const char*; Context =
boost::spirit::context<boost::fusion::cons<int*&, boost::fusion::cons<int_holder&,
boost::fusion::nil> >, boost::fusion::vector0<> >; Skipper = boost::spirit::unused_type]'
/opt/local/include/boost/spirit/home/qi/detail/pass_container.hpp:263:38: [ skipping 10
instantiation contexts ] /opt/local/include/boost/function/function_template.hpp:1042:16:
required from 'boost::function<R(T0, T1, T2, T3)>::function(Functor, typename
boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value,
int>::type) [with Functor =
boost::spirit::qi::detail::parser_binder<boost::spirit::qi::plus<boost::spirit::qi::action<boost::spirit::qi::parameterized_nonterminal<boost::spirit::qi::rule<const
char*, int*(int_holder&), boost::spirit::unused_type, boost::spirit::unused_type,
boost::spirit::unused_type>,
boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_> >,
boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
> > >, mpl_::bool_<false> >; R = bool; T0 = const char*&; T1 = const char* const&; T2 =
boost::spirit::context<boost::fusion::cons<int*&, boost::fusion::cons<int_holder&,
boost::fusion::nil> >, boost::fusion::vector0<> >&; T3 = const
boost::spirit::unused_type&; typename
boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value,
int>::type = int]' /opt/local/include/boost/function/function_template.hpp:1083:5:
required from 'typename
boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value,
boost::function<R(T0, T1, T2, T3)>&>::type boost::function<R(T0, T1, T2,
T3)>::operator=(Functor) [with Functor =
boost::spirit::qi::detail::parser_binder<boost::spirit::qi::plus<boost::spirit::qi::action<boost::spirit::qi::parameterized_nonterminal<boost::spirit::qi::rule<const
char*, int*(int_holder&), boost::spirit::unused_type, boost::spirit::unused_type,
boost::spirit::unused_type>,
boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_> >,
boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
> > >, mpl_::bool_<false> >; R = bool; T0 = const char*&; T1 = const char* const&; T2 =
boost::spirit::context<boost::fusion::cons<int*&, boost::fusion::cons<int_holder&,
boost::fusion::nil> >, boost::fusion::vector0<> >&; T3 = const
boost::spirit::unused_type&; typename
boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value,
boost::function<R(T0, T1, T2, T3)>&>::type = boost::function<bool(const char*&, const
char* const&, boost::spirit::context<boost::fusion::cons<int*&,
boost::fusion::cons<int_holder&, boost::fusion::nil> >, boost::fusion::vector0<> >&,
const boost::spirit::unused_type&)>&]'
/opt/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:182:13: required from
'static void boost::spirit::qi::rule<Iterator, T1, T2, T3,
T4>::define(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, const Expr&, mpl_::true_)
[with Auto = mpl_::bool_<false>; Expr =
boost::proto::exprns_::expr<boost::proto::tagns_::tag::unary_plus,
boost::proto::argsns_::list1<const
boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript,
boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,
boost::proto::argsns_::term<boost::spirit::qi::parameterized_nonterminal<boost::spirit::qi::rule<const
char*, int*(int_holder&), boost::spirit::unused_type, boost::spirit::unused_type,
boost::spirit::unused_type>,
boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_> > >, 0l>&,
boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,
boost::proto::argsns_::term<const
boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
>&>, 0l> >, 2l>&>, 1l>; Iterator = const char*; T1 = int*(int_holder&); T2 =
boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 =
boost::spirit::unused_type; boost::spirit::qi::rule<Iterator, T1, T2, T3, T4> =
boost::spirit::qi::rule<const char*, int*(int_holder&), boost::spirit::unused_type,
boost::spirit::unused_type, boost::spirit::unused_type>; mpl_::true_ =
mpl_::bool_<true>]' /opt/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:220:13:
required from 'boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&
boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::operator=(const Expr&) [with Expr =
boost::proto::exprns_::expr<boost::proto::tagns_::tag::unary_plus,
boost::proto::argsns_::list1<const
boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript,
boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,
boost::proto::argsns_::term<boost::spirit::qi::parameterized_nonterminal<boost::spirit::qi::rule<const
char*, int*(int_holder&), boost::spirit::unused_type, boost::spirit::unused_type,
boost::spirit::unused_type>,
boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_> > >, 0l>&,
boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,
boost::proto::argsns_::term<const
boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
>&>, 0l> >, 2l>&>, 1l>; Iterator = const char*; T1 = int*(int_holder&); T2 =
boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 =
boost::spirit::unused_type; boost::spirit::qi::rule<Iterator, T1, T2, T3, T4> =
boost::spirit::qi::rule<const char*, int*(int_holder&), boost::spirit::unused_type,
boost::spirit::unused_type, boost::spirit::unused_type>]' test_qi.cpp:41:3: required from
'my_grammar<Iterator>::my_grammar() [with Iterator = const char*]' test_qi.cpp:57:26:
required from here /opt/local/include/boost/fusion/container/list/cons.hpp:83:40: error:
invalid initialization of reference of type 'boost::fusion::cons<int_holder&,
boost::fusion::nil>::car_type {aka int_holder&}' from expression of type 'int*'
将_r1传递给phoenix :: function时显然存在问题,但我不知道如何解决它。提前谢谢。
答案 0 :(得分:3)
抱歉,我刚刚发现错误,代码行
start = +next(_val) [_val = _1];
需要更改为
start = +next(_r1) [_val = _1];
然后它的工作原理。抱歉浪费你的时间!再见!