feat(frontends/lean/parse_table): add get_head_index auxiliary function for indexing notation declarations
This commit is contained in:
parent
f76c5bbde9
commit
f17e67efcb
2 changed files with 87 additions and 0 deletions
|
@ -9,6 +9,7 @@ Author: Leonardo de Moura
|
||||||
#include "util/rb_map.h"
|
#include "util/rb_map.h"
|
||||||
#include "util/sstream.h"
|
#include "util/sstream.h"
|
||||||
#include "kernel/free_vars.h"
|
#include "kernel/free_vars.h"
|
||||||
|
#include "kernel/replace_fn.h"
|
||||||
#include "library/kernel_bindings.h"
|
#include "library/kernel_bindings.h"
|
||||||
#include "frontends/lean/parse_table.h"
|
#include "frontends/lean/parse_table.h"
|
||||||
#include "frontends/lean/no_info.h"
|
#include "frontends/lean/no_info.h"
|
||||||
|
@ -201,6 +202,9 @@ void action::display(std::ostream & out) const {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool action::is_simple() const {
|
||||||
|
return kind() != action_kind::Ext && kind() != action_kind::LuaExt;
|
||||||
|
}
|
||||||
|
|
||||||
void action_cell::dealloc() {
|
void action_cell::dealloc() {
|
||||||
switch (m_kind) {
|
switch (m_kind) {
|
||||||
|
@ -351,6 +355,72 @@ parse_table parse_table::add_core(unsigned num, transition const * ts, expr cons
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_simple(unsigned num, transition const * ts) {
|
||||||
|
return std::all_of(ts, ts+num, [](transition const & t) { return t.is_simple(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_safe_ascii(unsigned num, transition const * ts) {
|
||||||
|
return std::all_of(ts, ts+num, [](transition const & t) { return t.is_safe_ascii(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief Given \c a, an expression that is the denotation of an expression, if \c a is a variable,
|
||||||
|
then use the actions in the transitions \c ts to expand \c a. The idea is to produce a head symbol
|
||||||
|
we can use to decide whether the notation should be considered during pretty printing.
|
||||||
|
|
||||||
|
\see get_head_index
|
||||||
|
*/
|
||||||
|
static expr expand_pp_pattern(unsigned num, transition const * ts, expr const & a) {
|
||||||
|
lean_assert(is_simple(num, ts));
|
||||||
|
if (!is_var(a))
|
||||||
|
return a;
|
||||||
|
return replace(a, [&](expr const & e) {
|
||||||
|
if (is_var(e)) {
|
||||||
|
unsigned vidx = var_idx(e);
|
||||||
|
unsigned i = num;
|
||||||
|
unsigned offset = 0;
|
||||||
|
while (i > 0) {
|
||||||
|
--i;
|
||||||
|
action const & act = ts[i].get_action();
|
||||||
|
switch (act.kind()) {
|
||||||
|
case action_kind::Binder: case action_kind::Binders: case action_kind::Skip:
|
||||||
|
break;
|
||||||
|
case action_kind::Ext: case action_kind::LuaExt:
|
||||||
|
lean_unreachable();
|
||||||
|
case action_kind::Expr:
|
||||||
|
if (vidx == 0) return none_expr();
|
||||||
|
offset++;
|
||||||
|
vidx--;
|
||||||
|
break;
|
||||||
|
case action_kind::Exprs:
|
||||||
|
if (vidx == 0)
|
||||||
|
return some_expr(lift_free_vars(act.get_rec(), offset));
|
||||||
|
offset++;
|
||||||
|
vidx--;
|
||||||
|
break;
|
||||||
|
case action_kind::ScopedExpr:
|
||||||
|
if (vidx == 0)
|
||||||
|
return some_expr(lift_free_vars(act.get_rec(), offset));
|
||||||
|
offset++;
|
||||||
|
vidx--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return none_expr();
|
||||||
|
} else {
|
||||||
|
return none_expr();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
optional<head_index> get_head_index(unsigned num, transition const * ts, expr const & a) {
|
||||||
|
if (is_simple(num, ts)) {
|
||||||
|
expr n = expand_pp_pattern(num, ts, a);
|
||||||
|
if (!is_var(n))
|
||||||
|
return some(head_index(n));
|
||||||
|
}
|
||||||
|
return optional<head_index>();
|
||||||
|
}
|
||||||
|
|
||||||
parse_table parse_table::add(unsigned num, transition const * ts, expr const & a, bool overload) const {
|
parse_table parse_table::add(unsigned num, transition const * ts, expr const & a, bool overload) const {
|
||||||
expr new_a = annotate_macro_subterms(a);
|
expr new_a = annotate_macro_subterms(a);
|
||||||
validate_transitions(is_nud(), num, ts, new_a);
|
validate_transitions(is_nud(), num, ts, new_a);
|
||||||
|
|
|
@ -10,6 +10,7 @@ Author: Leonardo de Moura
|
||||||
#include "util/buffer.h"
|
#include "util/buffer.h"
|
||||||
#include "util/lua.h"
|
#include "util/lua.h"
|
||||||
#include "kernel/expr.h"
|
#include "kernel/expr.h"
|
||||||
|
#include "library/head_map.h"
|
||||||
#include "frontends/lean/token_table.h"
|
#include "frontends/lean/token_table.h"
|
||||||
#include "frontends/lean/parser_pos_provider.h"
|
#include "frontends/lean/parser_pos_provider.h"
|
||||||
|
|
||||||
|
@ -78,6 +79,9 @@ public:
|
||||||
|
|
||||||
bool is_equal(action const & a) const;
|
bool is_equal(action const & a) const;
|
||||||
void display(std::ostream & out) const;
|
void display(std::ostream & out) const;
|
||||||
|
|
||||||
|
/** \brief Return true iff the action is not Ext or LuaExt */
|
||||||
|
bool is_simple() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
action mk_skip_action();
|
action mk_skip_action();
|
||||||
|
@ -101,8 +105,12 @@ public:
|
||||||
m_token(t), m_action(a) {}
|
m_token(t), m_action(a) {}
|
||||||
name const & get_token() const { return m_token; }
|
name const & get_token() const { return m_token; }
|
||||||
action const & get_action() const { return m_action; }
|
action const & get_action() const { return m_action; }
|
||||||
|
bool is_simple() const { return m_action.is_simple(); }
|
||||||
|
bool is_safe_ascii() const { return m_token.is_safe_ascii(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool is_safe_ascii(unsigned num, transition const * ts);
|
||||||
|
|
||||||
/** \brief Apply \c f to expressions embedded in the given transition */
|
/** \brief Apply \c f to expressions embedded in the given transition */
|
||||||
transition replace(transition const & t, std::function<expr(expr const &)> const & f);
|
transition replace(transition const & t, std::function<expr(expr const &)> const & f);
|
||||||
|
|
||||||
|
@ -136,6 +144,15 @@ public:
|
||||||
|
|
||||||
void display(std::ostream & out) const;
|
void display(std::ostream & out) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \brief Given a notation definition, return the "head symbol" of
|
||||||
|
every instance of the given notation.
|
||||||
|
|
||||||
|
\remark The result is none if the notation uses actions implemented in C++ or Lua.
|
||||||
|
The result is none if the denotation is a variable.
|
||||||
|
*/
|
||||||
|
optional<head_index> get_head_index(unsigned num, transition const * ts, expr const & a);
|
||||||
|
|
||||||
void initialize_parse_table();
|
void initialize_parse_table();
|
||||||
void finalize_parse_table();
|
void finalize_parse_table();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue