We need to create a Phoenix function that can take Spirit parameters.
// lazy function for error reporting struct ReportError { // the result type must be explicit for Phoenix template<typename, typename, typename, typename> struct result { typedef void type; }; // contract the string to the surrounding new-line characters template<typename Iter> void operator()(Iter first_iter, Iter last_iter, Iter error_iter, const qi::info& what) const { std::string first(first_iter, error_iter); std::string last(error_iter, last_iter); auto first_pos = first.rfind('\n'); auto last_pos = last.find('\n'); auto error_line = ((first_pos == std::string::npos) ? first : std::string(first, first_pos + 1)) + std::string(last, 0, last_pos); auto error_pos = (error_iter - first_iter) + 1; if (first_pos != std::string::npos) { error_pos -= (first_pos + 1); } std::cerr << "Parsing error in " << what << std::endl << error_line << std::endl << std::setw(error_pos) << '^' << std::endl; } }; const phoenix::function<ReportError> report_error = ReportError();
Then we just call this function in the error handler.
qi::on_error<qi::fail>( launch, report_error(spirit::_1, spirit::_2, spirit::_3, spirit::_4) );
source share