c++ - Boost Spirit 2.4.2: Cannot extract a string -
following resolved question boost spirit: error c2664, cannot convert 'const boost::phoenix::actor<eval>' 'char' , have question:
why using code below js_key , js_string, cannot capture print strings in format "str" or 'str'. return blank!
for example:
input: {"a":"aa", b:'c'}
actual output:
{ str: str: str: b str: parsed input json!
expected output:
{ str: str: aa str: b str: c parsed input json!
please kindly advise. thank you!
#include <map> #include <string> #include <vector> #include <iostream> #include <boost/config/warning_disable.hpp> #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_stl.hpp> #include <boost/spirit/include/phoenix_object.hpp> #include <boost/spirit/include/phoenix_container.hpp> #include <boost/spirit/include/phoenix_function.hpp> #include <boost/spirit/include/phoenix_fusion.hpp> #include <boost/spirit/include/phoenix_bind.hpp> #include <boost/fusion/include/adapt_assoc_struct.hpp> #include <boost/fusion/include/io.hpp> #include <boost/bind.hpp> #include <boost/function.hpp> namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; namespace phoenix = boost::phoenix; void print_char(char c) { std::cout << c << std::endl; } void print_str(std::string str) { std::cout << "str: " << str << std::endl; } template <typename iterator> struct json_grammar : qi::grammar<iterator, ascii::space_type> { json_grammar() : json_grammar::base_type(start) { using ascii::alpha; using ascii::alnum; using qi::long_long; using qi::long_double; using qi::lit; using qi::char_; using qi::lexeme; // start = char_('{') [phoenix::bind(&print_char, qi::_1)] >> -(js_member % ',') >> char_('}') ; // js_member = js_key [phoenix::bind(&print_str, qi::_1)] >> ':' >> js_value ; // js_key = (alpha >> *alnum) | js_string ; // js_string = js_single_quoted_str | js_double_quoted_str ; // js_array = lit('[') >> -(js_value % ',') >> lit(']') ; // js_bool = lit("true") | lit("false") ; // js_null = lit("null") ; // js_value = js_string [phoenix::bind(&print_str, qi::_1)] | js_num | js_array | start | js_bool | js_null; // js_single_quoted_str = (lexeme["'" >> *(char_ - "'") >> "'"]); // js_double_quoted_str = (lexeme['"' >> *(char_ - '"') >> '"']); // js_num = long_long | long_double; } qi::rule<iterator, std::string(), ascii::space_type> js_key; qi::rule<iterator, std::string(), ascii::space_type> js_string; qi::rule<iterator, ascii::space_type> start; qi::rule<iterator, ascii::space_type> js_member; qi::rule<iterator, ascii::space_type> js_value; qi::rule<iterator, ascii::space_type> js_single_quoted_str; qi::rule<iterator, ascii::space_type> js_double_quoted_str; qi::rule<iterator, ascii::space_type> js_array; qi::rule<iterator, ascii::space_type> js_num; qi::rule<iterator, ascii::space_type> js_bool; qi::rule<iterator, ascii::space_type> js_null; }; int main() { std::string inputstr; json_grammar<std::string::const_iterator> jsonparser; bool parseok = false; while(std::getline(std::cin, inputstr)) { if(inputstr.empty() || inputstr[0] == 'q' || inputstr[0] == 'q') break; std::string::const_iterator iter = inputstr.begin(); std::string::const_iterator iterend = inputstr.end(); parseok = qi::phrase_parse(iter, iterend, jsonparser, ascii::space); if(parseok && iter == iterend) { std::cout << "successfully parsed input json!" << std::endl; } else { std::cout << "cannot parse input json!" << std::endl; } } return 0; }
the answer simple: 2 structs js_single_quoted_str
, js_double_quoted_str
must redefined following make parser rock:
qi::rule<iterator, std::string(), ascii::space_type> js_single_quoted_str; qi::rule<iterator, std::string(), ascii::space_type> js_double_quoted_str;
Comments
Post a Comment