Getting result from boost spirit grammar (phoenix push_back causes a compile error) -


i have following spirit grammar. trying create vector of ast node in struct myresult using standard push_back(at_c<0>(qi::_val), qi::_1) getting compile errors (see below).

typedef vector<zls::astnode*> vector_astnode_t;  struct myresult { vector_astnode_t turtle_commands; };  boost_fusion_adapt_struct (  myresult,  (vector_astnode_t, turtle_commands) );     namespace spirit = boost::spirit; namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; namespace phoenix = boost::phoenix;   struct debugprint {     string _name;     debugprint( string n ) : _name(n) {}      void operator()(int const& i, qi::unused_type, qi::unused_type) const {         cout << _name << std::endl;     }     void operator()(qi::unused_type, qi::unused_type, qi::unused_type) const {         cout << _name << std::endl;     }             // todo: more of these each type  };   template <typename iterator> struct lsystem_parser :  qi::grammar<iterator, myresult() > {     lsystem_parser( zls::context* ctx )     :   lsystem_parser::base_type(start)      ,   _ctx( ctx )     {         using qi::char_;         using qi::float_;         using qi::eps;         using qi::lit;         using qi::_1;         using qi::_val;         using phoenix::ref;         using phoenix::push_back;         using phoenix::at_c;          float_parameters = '(' >> (float_ >> *(',' >> float_)) >> ')';          /// turtle grammar ///         draw_forward = ( char_('f') [ _val = new zls::astdrawforward(_ctx,0)] )                                     [debugprint("draw_forward")];          move_forward = ( char_('f') [ _val = new zls::astmoveforward(_ctx,0)] )                                     [debugprint("move_forward")];          turn_left = ( char_('+')    [ _val = new zls::astturnleft(_ctx,0)] )                                     [debugprint("turn_left")];          turn_right = ( char_('-')   [ _val = new zls::astturnright(_ctx,0)] )                                     [debugprint("turn_right")];          push_state = ( char_('[')   [ _val = new zls::astpushstate(_ctx)] )                                     [debugprint("push_state")];          pop_state = ( char_(']')    [ _val = new zls::astpopstate(_ctx) ] )                                     [debugprint("pop_state")];          turtle_commands = (draw_forward                          | move_forward                           | turn_left                              | turn_right                             | push_state                             | pop_state);                 // >>>> causing error <<<<<         start = *turtle_commands[ push_back(at_c<0>(qi::_val), qi::_1) ];     }     qi::rule< iterator, myresult() > start;     qi::rule< iterator, vector<float> > float_parameters;      qi::rule< iterator, zls::astnode* > draw_forward;     qi::rule< iterator, zls::astnode* > move_forward;     qi::rule< iterator, zls::astnode* > turn_left;     qi::rule< iterator, zls::astnode* > turn_right;     qi::rule< iterator, zls::astnode* > push_state;     qi::rule< iterator, zls::astnode* > pop_state;     qi::rule< iterator, zls::astnode* > turtle_commands;      zls::context*   _ctx;  }; 

the following actual errors returned xcode:

container.hpp:492: error: no matching function call 'std::vector<zls::astnode*,    std::allocator<zls::astnode*> >::push_back(const boost::fusion::unused_type&)' stl_vector.h:600: note: candidates are: void std::vector<_tp, _alloc>::push_back(const _tp&) [with _tp = zls::astnode*, _alloc = std::allocator<zls::astnode*>] container.hpp:492: error: return-statement value, in function returning 'void' 

edit: following revised spirit grammar compiles , works. there few subtle changes note including using phoenix new_ operator , adding following semantic action turtle_commands = ... [_val = _1]

template <typename iterator> struct lsystem_parser :  qi::grammar<iterator, vector_astnode_t() > {     lsystem_parser( zls::context* ctx )     :   lsystem_parser::base_type(start)      ,   _ctx( ctx )     {         using qi::char_;         using qi::float_;         using qi::eps;         using qi::lit;         using qi::_1;         using qi::_val;         using phoenix::ref;         using phoenix::push_back;         using phoenix::at_c;         using phoenix::new_;          float_parameters = '(' >> (float_ >> *(',' >> float_)) >> ')';          /// turtle grammar ///         draw_forward    = ( char_('f')  [ _val = new_<zls::astdrawforward>(_ctx, (zls::astnode*)0)] )                                         [debugprint("draw_forward")];          move_forward    = ( char_('f')  [ _val = new_<zls::astmoveforward>(_ctx, (zls::astnode*)0)] )                                         [debugprint("move_forward")];          turn_left       = ( char_('+')  [ _val = new_<zls::astturnleft>(_ctx, (zls::astnode*)0)] )                                         [debugprint("turn_left")];          turn_right      = ( char_('-')  [ _val = new_<zls::astturnright>(_ctx, (zls::astnode*)0)] )                                         [debugprint("turn_right")];          push_state      = ( char_('[')  [ _val = new_<zls::astpushstate>(_ctx)] )                                         [debugprint("push_state")];          pop_state       = ( char_(']')  [ _val = new_<zls::astpopstate>(_ctx) ] )                                         [debugprint("pop_state")];          turtle_commands = (draw_forward                         | move_forward                           | turn_left                              | turn_right                             | push_state                             | pop_state)[_val = _1];                   start = *turtle_commands >> qi::eps;     }     qi::rule< iterator, vector_astnode_t() > start;     qi::rule< iterator, vector<float> > float_parameters;      qi::rule< iterator, zls::astnode*() > draw_forward;     qi::rule< iterator, zls::astnode*() > move_forward;     qi::rule< iterator, zls::astnode*() > turn_left;     qi::rule< iterator, zls::astnode*() > turn_right;     qi::rule< iterator, zls::astnode*() > push_state;     qi::rule< iterator, zls::astnode*() > pop_state;     qi::rule< iterator, zls::astnode*() > turtle_commands;      zls::context*   _ctx;  }; 

you can't directly use operator new inside of semantic actions, use phoenix::new_<> instead.

moreover, attributes rules specified using function notation syntax. therefore, you'll need change rule declarations to:

qi::rule< iterator, zls::astnode*()> draw_forward; 

here additional tip. if change start rule to:

start = *turtle_commands >> qi::eps; 

you can avoid semantic action alltogether. converting rule (parser) sequence can leverage attribute propagation rules sequences, allowing directly map first element of fusion sequence (the vector_astnode_t turtle_commands) onto first element of parser sequence (the *turtle_commands).

i'm not able compile example incomplete, more problems might hidden.


Comments

Popular posts from this blog

asp.net - repeatedly call AddImageUrl(url) to assemble pdf document -

java - Android recognize cell phone with keyboard or not? -

iphone - How would you achieve a LED Scrolling effect? -