feat(frontends/lean/parser): add 'flag' for disabling 'unknown identifier' errors

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-06-17 10:30:03 -07:00
parent 4be05e1d8c
commit 28c904abea
2 changed files with 22 additions and 1 deletions

View file

@ -53,11 +53,17 @@ parser::local_scope::~local_scope() {
parser::param_universe_scope::param_universe_scope(parser & p):m_p(p), m_old(m_p.m_type_use_placeholder) { parser::param_universe_scope::param_universe_scope(parser & p):m_p(p), m_old(m_p.m_type_use_placeholder) {
m_p.m_type_use_placeholder = false; m_p.m_type_use_placeholder = false;
} }
parser::param_universe_scope::~param_universe_scope() { parser::param_universe_scope::~param_universe_scope() {
m_p.m_type_use_placeholder = m_old; m_p.m_type_use_placeholder = m_old;
} }
parser::no_undef_id_error_scope::no_undef_id_error_scope(parser & p):m_p(p), m_old(m_p.m_no_undef_id_error) {
m_p.m_no_undef_id_error = true;
}
parser::no_undef_id_error_scope::~no_undef_id_error_scope() {
m_p.m_no_undef_id_error = m_old;
}
parser::parser(environment const & env, io_state const & ios, parser::parser(environment const & env, io_state const & ios,
std::istream & strm, char const * strm_name, std::istream & strm, char const * strm_name,
script_state * ss, bool use_exceptions, unsigned num_threads, script_state * ss, bool use_exceptions, unsigned num_threads,
@ -70,6 +76,7 @@ parser::parser(environment const & env, io_state const & ios,
m_scanner.set_line(line); m_scanner.set_line(line);
m_num_threads = num_threads; m_num_threads = num_threads;
m_type_use_placeholder = true; m_type_use_placeholder = true;
m_no_undef_id_error = false;
m_found_errors = false; m_found_errors = false;
updt_options(); updt_options();
m_next_tag_idx = 0; m_next_tag_idx = 0;
@ -740,6 +747,8 @@ expr parser::parse_id() {
} }
r = mk_choice(new_as.size(), new_as.data()); r = mk_choice(new_as.size(), new_as.data());
} }
if (m_no_undef_id_error)
r = mk_constant(id, ls);
if (!r) if (!r)
throw parser_error(sstream() << "unknown identifier '" << id << "'", p); throw parser_error(sstream() << "unknown identifier '" << id << "'", p);
return *r; return *r;

View file

@ -69,6 +69,10 @@ class parser {
// if it is false, then it is parsed as Type.{l} where l is a fresh parameter, // if it is false, then it is parsed as Type.{l} where l is a fresh parameter,
// and is automatically inserted into m_local_level_decls. // and is automatically inserted into m_local_level_decls.
bool m_type_use_placeholder; bool m_type_use_placeholder;
// By default, when the parser finds a unknown identifier, it signs an error.
// When the following flag is true, it creates a constant.
// This flag is when we are trying to parse mutually recursive declarations.
bool m_no_undef_id_error;
void display_error_pos(unsigned line, unsigned pos); void display_error_pos(unsigned line, unsigned pos);
void display_error_pos(pos_info p); void display_error_pos(pos_info p);
@ -245,6 +249,14 @@ public:
/** \brief Use tactic \c t for "synthesizing" the placeholder \c e. */ /** \brief Use tactic \c t for "synthesizing" the placeholder \c e. */
void save_hint(expr const & e, tactic const & t); void save_hint(expr const & e, tactic const & t);
/**
\brief By default, when the parser finds a unknown identifier, it signs an error.
This scope object temporarily changes this behavior. In any scope where this object
is declared, the parse creates a constant even when the identifier is unknown.
This behavior is useful when we are trying to parse mutually recursive declarations.
*/
struct no_undef_id_error_scope { parser & m_p; bool m_old; no_undef_id_error_scope(parser &); ~no_undef_id_error_scope(); };
expr elaborate(expr const & e, level_param_names const &); expr elaborate(expr const & e, level_param_names const &);
std::pair<expr, expr> elaborate(expr const & t, expr const & v, level_param_names const &); std::pair<expr, expr> elaborate(expr const & t, expr const & v, level_param_names const &);