fix(frontends/lean/parser): parser aborted if the scanner throws an exception in the first call to scan(); position information was being shown twice for scanner exceptions

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-01-07 15:04:28 -08:00
parent f12a76a5cd
commit fb73514913
3 changed files with 32 additions and 53 deletions

View file

@ -97,6 +97,14 @@ void parser_imp::display_error(tactic_cmd_error const & ex) {
display_proof_state(ex.m_state); display_proof_state(ex.m_state);
} }
#define CATCH_CORE(ShowError, ThrowError) \
m_found_errors = true; \
if (m_show_errors) { ShowError ; } \
sync(); \
if (m_use_exceptions) { ThrowError ; }
#define CATCH(ShowError) CATCH_CORE(ShowError, throw;)
/** /**
\brief Execute the given function \c f, and handle exceptions occurring \brief Execute the given function \c f, and handle exceptions occurring
when executing \c f. when executing \c f.
@ -106,63 +114,29 @@ void parser_imp::protected_call(std::function<void()> && f, std::function<void()
try { try {
f(); f();
} catch (tactic_cmd_error & ex) { } catch (tactic_cmd_error & ex) {
m_found_errors = true; CATCH(display_error(ex));
if (m_show_errors) } catch (parser_exception & ex) {
display_error(ex); CATCH(regular(m_io_state) << "Error " << ex.what() << endl;);
sync();
if (m_use_exceptions)
throw;
} catch (parser_error & ex) { } catch (parser_error & ex) {
m_found_errors = true; CATCH_CORE(display_error(ex.what(), ex.m_pos.first, ex.m_pos.second), throw parser_exception(ex.what(), ex.m_pos.first, ex.m_pos.second));
if (m_show_errors)
display_error(ex.what(), ex.m_pos.first, ex.m_pos.second);
sync();
if (m_use_exceptions) {
throw parser_exception(ex.what(), ex.m_pos.first, ex.m_pos.second);
}
} catch (kernel_exception & ex) { } catch (kernel_exception & ex) {
m_found_errors = true; CATCH(display_error(ex));
if (m_show_errors)
display_error(ex);
sync();
if (m_use_exceptions)
throw;
} catch (elaborator_exception & ex) { } catch (elaborator_exception & ex) {
m_found_errors = true; CATCH(display_error(ex));
if (m_show_errors)
display_error(ex);
sync();
if (m_use_exceptions)
throw;
} catch (metavar_not_synthesized_exception & ex) { } catch (metavar_not_synthesized_exception & ex) {
m_found_errors = true; CATCH(display_error(ex));
if (m_show_errors)
display_error(ex);
sync();
if (m_use_exceptions)
throw;
} catch (script_exception & ex) { } catch (script_exception & ex) {
m_found_errors = true;
reset_interrupt(); reset_interrupt();
if (m_show_errors) CATCH(display_error(ex));
display_error(ex);
sync();
if (m_use_exceptions)
throw;
} catch (interrupted & ex) { } catch (interrupted & ex) {
reset_interrupt();
if (m_verbose) if (m_verbose)
regular(m_io_state) << "!!!Interrupted!!!" << endl; regular(m_io_state) << "!!!Interrupted!!!" << endl;
reset_interrupt();
sync(); sync();
if (m_use_exceptions) if (m_use_exceptions)
throw; throw;
} catch (exception & ex) { } catch (exception & ex) {
m_found_errors = true; CATCH(display_error(ex.what()););
if (m_show_errors)
display_error(ex.what());
sync();
if (m_use_exceptions)
throw;
} }
} }
} }

View file

@ -132,6 +132,15 @@ void parser_imp::parse_script(bool as_expr) {
void parser_imp::parse_script_expr() { return parse_script(true); } void parser_imp::parse_script_expr() { return parse_script(true); }
void parser_imp::sync_command() {
// Keep consuming tokens until we find a Command or End-of-file
show_prompt();
while (curr() != scanner::token::CommandId && curr() != scanner::token::Eof && curr() != scanner::token::Period)
next();
if (curr_is_period())
next();
}
parser_imp::parser_imp(environment const & env, io_state const & st, std::istream & in, parser_imp::parser_imp(environment const & env, io_state const & st, std::istream & in,
script_state * S, bool use_exceptions, bool interactive): script_state * S, bool use_exceptions, bool interactive):
m_env(env), m_env(env),
@ -162,7 +171,8 @@ parser_imp::parser_imp(environment const & env, io_state const & st, std::istrea
m_tactic_macros = nullptr; m_tactic_macros = nullptr;
m_cmd_macros = nullptr; m_cmd_macros = nullptr;
} }
scan(); protected_call([&]() { scan(); },
[&]() { sync_command(); });
} }
parser_imp::~parser_imp() {} parser_imp::~parser_imp() {}
@ -199,14 +209,8 @@ bool parser_imp::parse_commands() {
default: default:
throw parser_error("Command expected", pos()); throw parser_error("Command expected", pos());
} }
}, [&]() { },
// Keep consuming tokens until we find a Command or End-of-file [&]() { sync_command(); });
show_prompt();
while (curr() != scanner::token::CommandId && curr() != scanner::token::Eof && curr() != scanner::token::Period)
next();
if (curr_is_period())
next();
});
} }
return !m_found_errors; return !m_found_errors;
} }

View file

@ -421,6 +421,7 @@ private:
void parse_end(); void parse_end();
void parse_using(); void parse_using();
bool parse_command(); bool parse_command();
void sync_command();
/*@}*/ /*@}*/
public: public: