c++ - Boost Spirit Qi: Omit element in Kleene Star parser -


i want parse special constructs , throw rest away. don't want use skipper.

i want vector of these constructs, use kleene star parser main rule. but, everytime gets thrown away, default constructed element inserted vector.

here made example. looks string test , throws rest away, @ least plan. every time rule garbage succeeds adds default constructed item vector in rule all, giving output of 7 insteat of 1. how can tell spirit add vector if rule item succeeds?

#define boost_spirit_use_phoenix_v3  #include <boost/config/warning_disable.hpp> #include <boost/spirit/include/qi.hpp>  #include <boost/fusion/adapted/struct.hpp> #include <boost/spirit/include/phoenix.hpp>  #include <iostream> #include <string> #include <vector>  namespace qi = boost::spirit::qi;  struct container {   std::string name;   bool        dummy; }; boost_fusion_adapt_struct(::container,                           (std::string, name)                           (bool, dummy))  int main() {   typedef std::string::const_iterator iterator;    qi::rule<iterator, std::vector<container>()> all;   qi::rule<iterator, container()> item;   qi::rule<iterator, std::string()> string_rule;   qi::rule<iterator> garbage;    = *(garbage | item);   garbage = qi::char_ - qi::lit("test");   string_rule = qi::string("test");   item = string_rule >> qi::attr(true);    std::vector<container> ast;    std::string input = "blatestbla";    iterator first = input.begin();   iterator last = input.end();    bool result = qi::parse(first, last, all, ast);   if (result) {     result = first == last;   }    if (result) {     std::cout << "parsed " << ast.size() << " element(s)" << std::endl;   } else {     std::cout << "failure" << std::endl;   }  } 

since sehe's answer more or less educational purposes, have several solutions:

*garbage >> -(item % *garbage) >> *garbage  *garbage >> *(item >> *garbage)  = *(garbage | item[phx::push_back(qi::_val,qi::_1)]); 

and solution cv_and_he:

#define boost_spirit_use_phoenix_v3  #include <boost/config/warning_disable.hpp> #include <boost/spirit/include/qi.hpp>  #include <boost/fusion/adapted/struct.hpp> #include <boost/spirit/include/phoenix.hpp>  #include <iostream> #include <string> #include <vector>  namespace qi = boost::spirit::qi;  struct container {   std::string name;   bool        dummy; }; boost_fusion_adapt_struct(::container,                           (std::string, name)                           (bool, dummy))  struct container_vector {   //added     std::vector<container> data; };  namespace boost{ namespace spirit{ namespace traits //added {     template <>     struct is_container<container_vector> : boost::mpl::true_ {};      template <>     struct container_value<container_vector> {         typedef optional<container> type;     };      template <>     struct push_back_container<container_vector,optional<container> > {         static bool call(container_vector& cont, const optional<container>& val) {             if(val)                 cont.data.push_back(*val);             return true;         }     }; }}}  int main() {   typedef std::string::const_iterator iterator;    qi::rule<iterator, container_vector()> all; //changed   qi::rule<iterator, container()> item;   qi::rule<iterator, std::string()> string_rule;   qi::rule<iterator> garbage;    = *(garbage | item);   garbage = qi::char_ - qi::lit("test");   string_rule = qi::string("test");   item = string_rule >> qi::attr(true);    container_vector ast;     //changed    std::string input = "blatestbla";    iterator first = input.begin();   iterator last = input.end();    bool result = qi::parse(first, last, all, ast);   if (result) {     result = first == last;   }    if (result) {     std::cout << "parsed " << ast.data.size() << " element(s)" << std::endl;   //changed    } else {     std::cout << "failure" << std::endl;   }  } 

although didn't want use skipper ended with:

start = qi::skip(garbage.alias())[*item]; 

this last solution fastest (by 1-2%) in unscientific tests using c-files of linux kernel production rules.


Comments

Popular posts from this blog

html - Sizing a high-res image (~8MB) to display entirely in a small div (circular, diameter 100px) -

java - IntelliJ - No such instance method -

identifier - Is it possible for an html5 document to have two ids? -