2012-04-26 31 views
6

Đoạn mã sau là phiên bản sắp xếp hợp lý của những gì tôi đang cố gắng làm. Về cơ bản, tôi có cấu trúc (int_holder trong mã đồ chơi), với một thành viên dữ liệu container. Tôi muốn chèn một đối tượng (int trong trường hợp này) và trở về qi cha mẹ :: quy tắc một con trỏ đến đối tượng mới được chèn vào.tinh thần :: qi: chuyển tham chiếu thuộc tính được thừa kế đến phoenix :: function

Tôi chuyển int_holder vào ngữ pháp bằng cách tham chiếu, để điền nó với các giá trị trong khi phân tích cú pháp, do đó, int_holder sẽ là một thuộc tính kế thừa của ngữ pháp. Mã số:

#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); 
} 

Các mã không biên dịch, với thông báo lỗi sau:

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*' 

Có rõ ràng là một vấn đề khi đi qua _r1 chức năng phượng ::, nhưng tôi không có ý tưởng làm thế nào để giải quyết nó. Cảm ơn trước.

+0

vui lòng đăng tìm kiếm của bạn dưới dạng câu trả lời cho câu hỏi của riêng bạn trong hộp văn bản bên dưới, thay vì cập nhật. Điều này giúp cho các googlers dễ dàng tìm thấy câu trả lời này hơn. Hoặc, bỏ phiếu để đóng câu hỏi này. – vidstige

+0

@vidstige Bạn nói đúng! Xong rồi cảm ơn – Giuliano

Trả lời

3

Xin lỗi, tôi vừa phát hiện ra lỗi, các dòng mã

start = +next(_val) [_val = _1]; 

cần phải được thay đổi để

start = +next(_r1) [_val = _1]; 

và sau đó nó hoạt động. Xin lỗi vì đã lãng phí thời gian! Tạm biệt!

Các vấn đề liên quan