У меня проблемы с настройкой обработчика ошибок на буст-спирит x3
.Я просматривал документацию (https://www.boost.org/doc/libs/1_70_0/libs/spirit/doc/x3/html/spirit_x3/tutorials/error_handling.html), но я не понимаю части: «Обратите внимание, что мы подклассифицируем employee_class из нашего обработчика error_handler. Таким образом, мы сообщаем X3, что мы хотим вызывать наш error_handler всякий раз, когдаИсключение выдается где-то внутри правила работника и того, что он вызывает (т. е. правила person и quoted_string). "
Что имеет тип <ruleID>_class
для выполнения с регистрацией?
Я начал сфункциональная композиция описана в ответе Spirit X3: анализатор с внутренним состоянием . Но я не могу зарегистрировать обработчик ошибок. Вот мой пример:
#include <iostream>
#include <iomanip>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/position_tagged.hpp>
#include <boost/spirit/home/x3/support/utility/error_reporting.hpp>
#include <boost/spirit/home/x3/support/utility/annotate_on_success.hpp>
namespace Parser {
namespace x3 = boost::spirit::x3;
namespace ascii = boost::spirit::x3::ascii;
struct error_handler {
template<typename Iterator, typename Exception, typename Context>
x3::error_handler_result on_error(
Iterator &first, Iterator const &last, Exception const &x, Context const &context) {
auto &error_handler = x3::get<x3::error_handler_tag>(context).get();
std::string message = "Error! Expecting: " + x.which() + " here:";
error_handler(x.where(), message);
return x3::error_handler_result::fail;
}
};
struct CSVLine;
static inline auto line_parser() {
auto delim = ',' | &(x3::eoi | x3::eol);
return x3::rule<CSVLine>{"line"} = (as_parser(x3::int_) > delim > as_parser(x3::int_) > x3::eps);
}
struct CSVLine_class : error_handler, x3::annotate_on_success {};
}
void parse(std::string const &input) {
using iterator_type = std::string::const_iterator;
iterator_type iter = input.begin();
iterator_type const end = input.end();
using boost::spirit::x3::with;
using boost::spirit::x3::error_handler_tag;
using error_handler_type = boost::spirit::x3::error_handler<iterator_type>;
// Our error handler
error_handler_type error_handler(iter, end, std::cout);
// Our parser
const auto p = Parser::line_parser();
auto const parser =
// we pass our error handler to the parser so we can access
// it later in our on_error and on_sucess handlers
with<error_handler_tag>(std::ref(error_handler))
[
p
];
if (parse(iter, end, parser))
std::cout << "Parsed" << std::endl;
else
std::cout << "Failed" << std::endl;
if (iter!=end)
std::cout << "Remaining: " << std::quoted(std::string(iter,end)) << std::endl;
}
int main() {
parse("1,x2.6");
return 0;
}
Поскольку обработчик ошибок непризнал это дает:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::spirit::x3::expectation_failure<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >'
what(): boost::spirit::x3::expectation_failure