Fix bug in parser.

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-08-18 15:23:01 -07:00
parent afd62ced87
commit 4d5b65fe87
2 changed files with 27 additions and 6 deletions

8
examples/ex5.lean Normal file
View file

@ -0,0 +1,8 @@
Show fun x : Bool, (fun x : Bool, x).
Show let x := true,
y := true
in (let z := x /\ y,
f := (fun x y : Bool, x /\ y <=>
y /\ x <=>
x \/ y \/ y)
in (f x y) \/ z)

View file

@ -55,6 +55,7 @@ struct parser_fn {
bool m_use_exceptions;
bool m_found_errors;
local_decls m_local_decls;
unsigned m_num_local_decls;
builtins m_builtins;
/** \brief Exception used to track parsing erros, it does not leak outside of this class. */
@ -62,6 +63,14 @@ struct parser_fn {
parser_error(char const * msg):exception(msg) {}
};
struct mk_scope {
parser_fn & m_fn;
local_decls::mk_scope m_scope;
unsigned m_old_num_local_decls;
mk_scope(parser_fn & fn):m_fn(fn), m_scope(fn.m_local_decls), m_old_num_local_decls(fn.m_num_local_decls) {}
~mk_scope() { m_fn.m_num_local_decls = m_old_num_local_decls; }
};
void scan() { m_curr = m_scanner.scan(); }
scanner::token curr() const { return m_curr; }
void next() { if (m_curr != scanner::token::Eof) scan(); }
@ -112,6 +121,7 @@ struct parser_fn {
m_err(err),
m_use_exceptions(use_exceptions) {
m_found_errors = false;
m_num_local_decls = 0;
m_scanner.set_command_keywords(g_command_keywords);
init_builtins();
scan();
@ -226,7 +236,7 @@ struct parser_fn {
next();
auto it = m_local_decls.find(id);
if (it != m_local_decls.end()) {
return mk_var(m_local_decls.size() - it->second - 1);
return mk_var(m_num_local_decls - it->second - 1);
} else {
operator_info op = m_frontend.find_nud(id);
if (op) {
@ -247,7 +257,7 @@ struct parser_fn {
next();
auto it = m_local_decls.find(id);
if (it != m_local_decls.end()) {
return mk_app(left, mk_var(m_local_decls.size() - it->second - 1));
return mk_app(left, mk_var(m_num_local_decls - it->second - 1));
} else {
operator_info op = m_frontend.find_led(id);
if (op) {
@ -285,7 +295,10 @@ struct parser_fn {
}
void register_binding(name const & n) {
m_local_decls.insert(n, m_local_decls.size());
unsigned lvl = m_num_local_decls;
m_local_decls.insert(n, lvl);
m_num_local_decls++;
lean_assert(m_local_decls.find(n)->second == lvl);
}
void parse_simple_bindings(buffer<std::pair<name, expr>> & result) {
@ -335,7 +348,7 @@ struct parser_fn {
expr parse_abstraction(bool is_lambda) {
next();
local_decls::mk_scope scope(m_local_decls);
mk_scope scope(*this);
buffer<std::pair<name, expr>> bindings;
parse_bindings(bindings);
check_comma_next("invalid abstraction, ',' expected");
@ -353,7 +366,7 @@ struct parser_fn {
expr parse_let() {
next();
local_decls::mk_scope scope(m_local_decls);
mk_scope scope(*this);
buffer<std::pair<name, expr>> bindings;
while (true) {
name id = check_identifier_next("invalid let expression, identifier expected");
@ -472,7 +485,7 @@ struct parser_fn {
check_assign_next("invalid definition, ':=' expected");
val = elaborate(parse_expr());
} else {
local_decls::mk_scope scope(m_local_decls);
mk_scope scope(*this);
buffer<std::pair<name, expr>> bindings;
parse_bindings(bindings);
check_colon_next("invalid definition, ':' expected");