Error message in Boost Spirit

I have the following error handler at the bottom of my parser grammar:

qi::on_error<qi::fail>( launch, std::cerr << phoenix::val("Paring error in ") << spirit::_4 << std::endl << phoenix::construct<std::string>(spirit::_3, spirit::_2) << std::endl ); 

The problem is that the parser input is not broken into new lines in advance, so the final error statement will be all in the source code from the point of error to the end. Is there a simple alternative

 phoenix::construct<std::string>(spirit::_3, spirit::_2) 

to print only one line on which an error occurs? Phoenix semantics gives me problems if I try to just search for '\n' .

+4
source share
1 answer

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) ); 
+7
source

Source: https://habr.com/ru/post/1496639/


All Articles