c++ - boost spirit on_error not triggered -
^ no not. part of problem, if review code right now, pointed out question/answer shows ... , errors still not triggered.
i have boost spirit parser string literal. works. start handle errors when fail. copied on_error handle 1-1 mini xml example , compiles, never triggered (no errors outputted).
this parser:
#define boost_spirit_use_phoenix_v3 #define boost_spirit_debug #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix.hpp> #include <boost/spirit/home/support/iterators/line_pos_iterator.hpp> #include <boost/spirit/include/phoenix_fusion.hpp> #include <boost/spirit/include/phoenix_stl.hpp> #include <boost/fusion/include/adapt_struct.hpp> namespace qi = boost::spirit::qi; struct my_handler_f { template <typename...> struct result { typedef void type; }; template <typename... t> void operator()(t&&...) const { std::cout << "\nmy_handler_f() invoked " << sizeof...(t) << " arguments\n"; } }; struct append_utf8_f { template <typename, typename> struct result { typedef void type; }; template <typename int> void operator()(int in, std::string& to) const { auto out = std::back_inserter(to); boost::utf8_output_iterator<decltype(out)> convert(out); *convert++ = in; } }; struct get_line_f { template <typename> struct result { typedef size_t type; }; template <typename it> size_t operator()(it const& pos_iter) const { return get_line(pos_iter); } }; struct rangeposition { size_t beginline, endline; }; struct string : public rangeposition { string() : rangeposition() , value() , source() { } std::string value; std::string source; }; boost_fusion_adapt_struct(string, (std::string, value) (std::string, source) (size_t, beginline) (size_t, endline) ) template <typename iterator> struct source_string : qi::grammar<iterator, string(), qi::space_type> { struct escape_symbols : qi::symbols<char, char> { escape_symbols() { add ("\'" , '\'') ("\"" , '\"') ("\?" , '\?') ("\\" , '\\') ("0" , '\0') ("a" , '\a') ("b" , '\b') ("f" , '\f') ("n" , '\n') ("r" , '\r') ("t" , '\t') ("v" , '\v') ; } } escape_symbol; source_string() : source_string::base_type(start) { using qi::raw; using qi::_val; using qi::_1; using qi::_2; using qi::_3; using qi::_4; using qi::space; using qi::omit; using qi::no_case; using qi::print; using qi::eps; using qi::on_error; using qi::fail; using qi::lit; namespace phx = boost::phoenix; using phx::at_c; using phx::begin; using phx::end; using phx::construct; using phx::ref; using phx::val; escape %= escape_symbol; character %= (no_case["\\x"] > hex12) | ("\\" > (oct123 | escape)) | (print - (lit('"') | '\\')); unicode = ("\\u" > hex4[append_utf8(_1, _val)]) | ("\\u" > hex8[append_utf8(_1, _val)]); string_section %= '"' > *(unicode | character) > '"'; string %= string_section % omit[*space]; main = raw [ string[at_c<0>(_val) = _1] ] [ at_c<1>(_val) = construct<std::string>(begin(_1), end(_1)), at_c<2>(_val) = get_line_(begin(_1)), at_c<3>(_val) = get_line_(end(_1)) ]; start %= eps > main; on_error<fail>(start, my_handler); } boost::phoenix::function<my_handler_f> my_handler; qi::rule<iterator, std::string()> escape; qi::uint_parser<char, 16, 1, 2> hex12; qi::uint_parser<char, 8, 1, 3> oct123; qi::rule<iterator, std::string()> character; qi::uint_parser<uint16_t, 16, 4, 4> hex4; qi::uint_parser<uint32_t, 16, 8, 8> hex8; boost::phoenix::function<append_utf8_f> append_utf8; qi::rule<iterator, std::string()> unicode; qi::rule<iterator, std::string()> string_section; qi::rule<iterator, std::string()> string; boost::phoenix::function<get_line_f> get_line_; qi::rule<iterator, string(), qi::space_type> main; qi::rule<iterator, string(), qi::space_type> start; };
and test code
int main() { std::string str[] = { "\"\\u1234\\u0002345\"", //"\"te\"\"st\"", //"\"te\" \"st\"", //"\"te\" \n \"st\"", //"\"\"", //"\"\\\"\"", //"\"test\"", //"\"test\" something", //"\"\\\'\\\"\\\?\\\\\\a\\b\\f\\n\\r\\t\\v\"", //"\"\\x61cd\\x3012\\x7z\"", //"\"\\141cd\\06012\\78\\778\"", "\"te", //"\"te\nst\"", //"\"test\\\"", //"\"te\\st\"", // }; typedef boost::spirit::line_pos_iterator<std::string::const_iterator> iterator; (size_t = 0; < sizeof(str) / sizeof(str[0]); ++i) { source_string<iterator> g; iterator iter(str[i].begin()); iterator end(str[i].end()); string string; bool r = phrase_parse(iter, end, g, qi::space, string); if (r) std::cout << string.beginline << "-" << string.endline << ": " << string.value << " === " << string.source << "\n"; else std::cout << "parsing failed\n"; } }
Comments
Post a Comment