2014-06-11 00:02:06 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
|
|
|
Author: Leonardo de Moura
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <string>
|
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
2014-10-26 16:47:11 +00:00
|
|
|
#include "util/flet.h"
|
2014-06-11 00:02:06 +00:00
|
|
|
#include "util/script_state.h"
|
|
|
|
#include "util/name_map.h"
|
|
|
|
#include "util/exception.h"
|
2014-06-18 04:38:10 +00:00
|
|
|
#include "util/thread_script_state.h"
|
2014-06-18 15:03:17 +00:00
|
|
|
#include "util/script_exception.h"
|
2014-07-12 21:50:57 +00:00
|
|
|
#include "util/worker_queue.h"
|
2014-06-21 00:17:39 +00:00
|
|
|
#include "util/name_generator.h"
|
2014-06-11 00:02:06 +00:00
|
|
|
#include "kernel/environment.h"
|
|
|
|
#include "kernel/expr_maps.h"
|
|
|
|
#include "library/io_state.h"
|
2014-06-12 03:56:10 +00:00
|
|
|
#include "library/io_state_stream.h"
|
2014-06-11 18:26:17 +00:00
|
|
|
#include "library/kernel_bindings.h"
|
2014-08-15 01:12:12 +00:00
|
|
|
#include "library/definition_cache.h"
|
2014-08-15 00:44:07 +00:00
|
|
|
#include "library/declaration_index.h"
|
2014-06-11 00:02:06 +00:00
|
|
|
#include "frontends/lean/scanner.h"
|
2014-10-03 23:10:36 +00:00
|
|
|
#include "frontends/lean/elaborator_context.h"
|
2014-06-14 16:56:05 +00:00
|
|
|
#include "frontends/lean/local_decls.h"
|
2014-06-11 18:26:17 +00:00
|
|
|
#include "frontends/lean/parser_config.h"
|
2014-06-11 00:02:06 +00:00
|
|
|
#include "frontends/lean/parser_pos_provider.h"
|
2014-07-26 21:26:34 +00:00
|
|
|
#include "frontends/lean/theorem_queue.h"
|
2014-08-07 01:07:04 +00:00
|
|
|
#include "frontends/lean/info_manager.h"
|
2014-06-11 00:02:06 +00:00
|
|
|
|
|
|
|
namespace lean {
|
|
|
|
/** \brief Exception used to track parsing erros, it does not leak outside of this class. */
|
|
|
|
struct parser_error : public exception {
|
|
|
|
pos_info m_pos;
|
|
|
|
parser_error(char const * msg, pos_info const & p):exception(msg), m_pos(p) {}
|
|
|
|
parser_error(sstream const & msg, pos_info const & p):exception(msg), m_pos(p) {}
|
2015-01-15 23:05:47 +00:00
|
|
|
virtual throwable * clone() const { return new parser_error(m_msg.c_str(), m_pos); }
|
2014-06-11 00:02:06 +00:00
|
|
|
virtual void rethrow() const { throw *this; }
|
|
|
|
};
|
|
|
|
|
2014-06-11 18:26:17 +00:00
|
|
|
struct interrupt_parser {};
|
2014-09-10 15:39:39 +00:00
|
|
|
typedef local_decls<expr> local_expr_decls;
|
|
|
|
typedef local_decls<level> local_level_decls;
|
|
|
|
typedef environment local_environment;
|
2014-06-11 18:26:17 +00:00
|
|
|
|
2014-10-03 15:52:35 +00:00
|
|
|
/** \brief Extra data needed to be saved when we execute parser::push_local_scope */
|
|
|
|
struct parser_scope_stack_elem {
|
|
|
|
optional<options> m_options;
|
2014-10-04 14:13:19 +00:00
|
|
|
name_set m_level_variables;
|
2014-10-03 15:52:35 +00:00
|
|
|
name_set m_variables;
|
|
|
|
name_set m_include_vars;
|
2014-12-11 06:25:40 +00:00
|
|
|
unsigned m_num_undef_ids;
|
2015-01-24 01:42:19 +00:00
|
|
|
bool m_has_params;
|
2014-12-11 06:25:40 +00:00
|
|
|
parser_scope_stack_elem(optional<options> const & o, name_set const & lvs, name_set const & vs, name_set const & ivs,
|
2015-01-24 01:42:19 +00:00
|
|
|
unsigned num_undef_ids, bool has_params):
|
|
|
|
m_options(o), m_level_variables(lvs), m_variables(vs), m_include_vars(ivs),
|
|
|
|
m_num_undef_ids(num_undef_ids), m_has_params(has_params) {}
|
2014-10-03 15:52:35 +00:00
|
|
|
};
|
|
|
|
typedef list<parser_scope_stack_elem> parser_scope_stack;
|
|
|
|
|
2014-08-07 01:07:04 +00:00
|
|
|
/** \brief Snapshot of the state of the Lean parser */
|
|
|
|
struct snapshot {
|
2014-10-03 15:52:35 +00:00
|
|
|
environment m_env;
|
|
|
|
local_level_decls m_lds;
|
|
|
|
local_expr_decls m_eds;
|
2014-10-11 17:25:02 +00:00
|
|
|
name_set m_lvars; // subset of m_lds that is tagged as level variable
|
|
|
|
name_set m_vars; // subset of m_eds that is tagged as variable
|
2014-10-04 14:13:19 +00:00
|
|
|
name_set m_include_vars; // subset of m_eds that must be included
|
2014-10-03 15:52:35 +00:00
|
|
|
options m_options;
|
|
|
|
parser_scope_stack m_parser_scope_stack;
|
|
|
|
unsigned m_line;
|
2014-08-07 01:07:04 +00:00
|
|
|
snapshot():m_line(0) {}
|
|
|
|
snapshot(environment const & env, options const & o):m_env(env), m_options(o), m_line(1) {}
|
2014-09-10 15:39:39 +00:00
|
|
|
snapshot(environment const & env, local_level_decls const & lds, local_expr_decls const & eds,
|
2014-10-04 14:13:19 +00:00
|
|
|
name_set const & lvars, name_set const & vars, name_set const & includes, options const & opts,
|
2014-10-03 15:52:35 +00:00
|
|
|
parser_scope_stack const & pss, unsigned line):
|
2014-10-04 14:13:19 +00:00
|
|
|
m_env(env), m_lds(lds), m_eds(eds), m_lvars(lvars), m_vars(vars), m_include_vars(includes),
|
2014-10-03 15:52:35 +00:00
|
|
|
m_options(opts), m_parser_scope_stack(pss), m_line(line) {}
|
2014-08-07 01:07:04 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef std::vector<snapshot> snapshot_vector;
|
|
|
|
|
2014-10-13 17:05:38 +00:00
|
|
|
enum class keep_theorem_mode { All, DiscardImported, DiscardAll };
|
|
|
|
|
2014-10-26 16:47:11 +00:00
|
|
|
enum class undef_id_behavior { Error, AssumeConstant, AssumeLocal };
|
|
|
|
|
2014-06-11 00:02:06 +00:00
|
|
|
class parser {
|
|
|
|
environment m_env;
|
|
|
|
io_state m_ios;
|
2014-06-21 00:17:39 +00:00
|
|
|
name_generator m_ngen;
|
2014-06-11 00:02:06 +00:00
|
|
|
bool m_verbose;
|
|
|
|
bool m_use_exceptions;
|
|
|
|
bool m_show_errors;
|
2014-06-16 23:37:46 +00:00
|
|
|
unsigned m_num_threads;
|
2014-06-11 00:02:06 +00:00
|
|
|
scanner m_scanner;
|
|
|
|
scanner::token_kind m_curr;
|
2014-06-12 16:08:38 +00:00
|
|
|
local_level_decls m_local_level_decls;
|
2014-06-14 16:56:05 +00:00
|
|
|
local_expr_decls m_local_decls;
|
2015-01-24 01:42:19 +00:00
|
|
|
bool m_has_params; // true context context contains parameters
|
2014-10-04 14:13:19 +00:00
|
|
|
name_set m_level_variables;
|
2014-10-03 00:29:22 +00:00
|
|
|
name_set m_variables; // subset of m_local_decls that is marked as variables
|
2014-10-03 14:23:24 +00:00
|
|
|
name_set m_include_vars; // subset of m_local_decls that is marked as include
|
2014-10-03 15:52:35 +00:00
|
|
|
parser_scope_stack m_parser_scope_stack;
|
2014-06-11 00:02:06 +00:00
|
|
|
pos_info m_last_cmd_pos;
|
|
|
|
pos_info m_last_script_pos;
|
|
|
|
unsigned m_next_tag_idx;
|
|
|
|
bool m_found_errors;
|
2014-08-01 01:35:57 +00:00
|
|
|
bool m_used_sorry;
|
2014-08-13 01:43:56 +00:00
|
|
|
pos_info_table m_pos_table;
|
2014-06-17 17:30:03 +00:00
|
|
|
// 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.
|
2014-10-26 16:47:11 +00:00
|
|
|
undef_id_behavior m_undef_id_behavior;
|
2014-07-02 15:08:35 +00:00
|
|
|
optional<bool> m_has_num;
|
2014-07-02 17:00:55 +00:00
|
|
|
optional<bool> m_has_string;
|
2014-07-03 15:33:29 +00:00
|
|
|
optional<bool> m_has_tactic_decls;
|
2014-07-12 21:50:57 +00:00
|
|
|
// We process theorems in parallel
|
2014-07-26 21:26:34 +00:00
|
|
|
theorem_queue m_theorem_queue;
|
2014-06-11 00:02:06 +00:00
|
|
|
|
2014-08-07 01:07:04 +00:00
|
|
|
// info support
|
|
|
|
snapshot_vector * m_snapshot_vector;
|
|
|
|
info_manager * m_info_manager;
|
2014-08-17 19:14:42 +00:00
|
|
|
info_manager m_pre_info_manager; // type information before elaboration
|
2014-08-07 01:07:04 +00:00
|
|
|
|
2014-08-10 18:04:16 +00:00
|
|
|
// cache support
|
2014-08-15 01:12:12 +00:00
|
|
|
definition_cache * m_cache;
|
2014-08-15 00:44:07 +00:00
|
|
|
// index support
|
2014-08-16 00:24:37 +00:00
|
|
|
declaration_index * m_index;
|
2014-08-10 18:04:16 +00:00
|
|
|
|
2014-10-13 17:05:38 +00:00
|
|
|
keep_theorem_mode m_keep_theorem_mode;
|
2014-10-09 20:07:21 +00:00
|
|
|
|
2014-08-23 19:39:59 +00:00
|
|
|
// curr command token
|
|
|
|
name m_cmd_token;
|
|
|
|
|
2014-12-11 06:25:40 +00:00
|
|
|
buffer<expr> m_undef_ids;
|
|
|
|
|
2014-08-02 06:21:55 +00:00
|
|
|
void display_warning_pos(unsigned line, unsigned pos);
|
|
|
|
void display_warning_pos(pos_info p);
|
2014-06-11 00:02:06 +00:00
|
|
|
void display_error_pos(unsigned line, unsigned pos);
|
|
|
|
void display_error_pos(pos_info p);
|
|
|
|
void display_error(char const * msg, unsigned line, unsigned pos);
|
|
|
|
void display_error(char const * msg, pos_info p);
|
2015-01-15 23:05:47 +00:00
|
|
|
void display_error(throwable const & ex);
|
2014-09-15 03:39:41 +00:00
|
|
|
void display_error(script_exception const & ex);
|
2014-06-11 00:02:06 +00:00
|
|
|
void throw_parser_exception(char const * msg, pos_info p);
|
2015-01-15 23:05:47 +00:00
|
|
|
void throw_nested_exception(throwable & ex, pos_info p);
|
2014-06-11 00:02:06 +00:00
|
|
|
|
|
|
|
void sync_command();
|
|
|
|
void protected_call(std::function<void()> && f, std::function<void()> && sync);
|
2014-06-11 18:26:17 +00:00
|
|
|
template<typename F>
|
|
|
|
typename std::result_of<F(lua_State * L)>::type using_script(F && f) {
|
2014-06-18 15:03:17 +00:00
|
|
|
try {
|
|
|
|
script_state S = get_thread_script_state();
|
|
|
|
set_io_state set1(S, m_ios);
|
|
|
|
set_environment set2(S, m_env);
|
|
|
|
return f(S.get_state());
|
|
|
|
} catch (script_nested_exception & ex) {
|
|
|
|
ex.get_exception().rethrow();
|
|
|
|
}
|
2014-06-11 18:26:17 +00:00
|
|
|
}
|
2014-06-11 00:02:06 +00:00
|
|
|
|
|
|
|
tag get_tag(expr e);
|
2014-06-11 22:07:20 +00:00
|
|
|
expr copy_with_new_pos(expr const & e, pos_info p);
|
2014-06-14 01:00:52 +00:00
|
|
|
expr propagate_levels(expr const & e, levels const & ls);
|
2014-06-11 00:02:06 +00:00
|
|
|
|
2014-06-15 05:13:25 +00:00
|
|
|
cmd_table const & cmds() const { return get_cmd_table(env()); }
|
|
|
|
parse_table const & nud() const { return get_nud_table(env()); }
|
|
|
|
parse_table const & led() const { return get_led_table(env()); }
|
2014-06-11 18:26:17 +00:00
|
|
|
|
2014-06-12 16:08:38 +00:00
|
|
|
unsigned curr_level_lbp() const;
|
|
|
|
level parse_max_imax(bool is_max);
|
|
|
|
level parse_level_id();
|
|
|
|
level parse_level_nud();
|
|
|
|
level parse_level_led(level left);
|
|
|
|
|
2014-06-16 23:37:46 +00:00
|
|
|
void parse_imports();
|
2014-06-11 18:26:17 +00:00
|
|
|
void parse_command();
|
|
|
|
void parse_script(bool as_expr = false);
|
|
|
|
bool parse_commands();
|
2014-06-11 22:07:20 +00:00
|
|
|
unsigned curr_lbp() const;
|
2014-06-12 03:56:10 +00:00
|
|
|
expr parse_notation(parse_table t, expr * left);
|
|
|
|
expr parse_nud_notation();
|
|
|
|
expr parse_led_notation(expr left);
|
2014-06-11 22:07:20 +00:00
|
|
|
expr parse_nud();
|
|
|
|
expr parse_id();
|
|
|
|
expr parse_numeral_expr();
|
|
|
|
expr parse_decimal_expr();
|
|
|
|
expr parse_string_expr();
|
2014-11-24 00:42:53 +00:00
|
|
|
expr parse_binder_core(binder_info const & bi, unsigned rbp);
|
|
|
|
void parse_binder_block(buffer<expr> & r, binder_info const & bi, unsigned rbp);
|
|
|
|
void parse_binders_core(buffer<expr> & r, buffer<notation_entry> * nentries, bool & last_block_delimited, unsigned rbp);
|
|
|
|
local_environment parse_binders(buffer<expr> & r, buffer<notation_entry> * nentries, bool & last_block_delimited,
|
|
|
|
bool allow_empty, unsigned rbp);
|
2014-07-29 02:04:57 +00:00
|
|
|
bool parse_local_notation_decl(buffer<notation_entry> * entries);
|
2014-06-11 18:26:17 +00:00
|
|
|
|
2015-01-17 17:38:10 +00:00
|
|
|
pair<optional<name>, expr> parse_id_tk_expr(name const & tk, unsigned rbp);
|
|
|
|
|
2014-06-16 16:24:41 +00:00
|
|
|
friend environment section_cmd(parser & p);
|
2014-08-23 22:44:28 +00:00
|
|
|
friend environment context_cmd(parser & p);
|
2014-10-10 23:21:30 +00:00
|
|
|
friend environment namespace_cmd(parser & p);
|
2014-06-16 16:24:41 +00:00
|
|
|
friend environment end_scoped_cmd(parser & p);
|
|
|
|
|
2014-09-09 18:02:01 +00:00
|
|
|
void push_local_scope(bool save_options = false);
|
2014-06-16 16:24:41 +00:00
|
|
|
void pop_local_scope();
|
2014-08-07 02:13:09 +00:00
|
|
|
|
2014-08-07 01:31:53 +00:00
|
|
|
void save_snapshot();
|
2014-08-07 02:13:09 +00:00
|
|
|
void save_overload(expr const & e);
|
2014-09-10 00:44:19 +00:00
|
|
|
void save_overload_notation(list<expr> const & as, pos_info const & p);
|
2014-08-07 04:56:57 +00:00
|
|
|
void save_type_info(expr const & e);
|
2014-08-07 06:15:05 +00:00
|
|
|
void save_pre_info_data();
|
2014-08-17 22:06:46 +00:00
|
|
|
void save_identifier_info(pos_info const & p, name const & full_id);
|
2014-08-27 01:06:37 +00:00
|
|
|
void commit_info(unsigned line);
|
2014-06-16 16:24:41 +00:00
|
|
|
|
2014-08-13 19:45:57 +00:00
|
|
|
elaborator_context mk_elaborator_context(pos_info_provider const & pp, bool check_unassigned = true);
|
|
|
|
elaborator_context mk_elaborator_context(environment const & env, pos_info_provider const & pp);
|
|
|
|
elaborator_context mk_elaborator_context(environment const & env, local_level_decls const & lls, pos_info_provider const & pp);
|
2014-08-13 01:43:56 +00:00
|
|
|
|
2014-06-11 00:02:06 +00:00
|
|
|
public:
|
|
|
|
parser(environment const & env, io_state const & ios,
|
|
|
|
std::istream & strm, char const * str_name,
|
2014-06-18 04:38:10 +00:00
|
|
|
bool use_exceptions = false, unsigned num_threads = 1,
|
2014-09-10 15:39:39 +00:00
|
|
|
snapshot const * s = nullptr, snapshot_vector * sv = nullptr,
|
2014-10-13 17:05:38 +00:00
|
|
|
info_manager * im = nullptr, keep_theorem_mode tmode = keep_theorem_mode::All);
|
2014-07-12 21:50:57 +00:00
|
|
|
~parser();
|
2014-06-11 00:02:06 +00:00
|
|
|
|
2014-08-15 01:12:12 +00:00
|
|
|
void set_cache(definition_cache * c) { m_cache = c; }
|
2014-08-10 18:04:16 +00:00
|
|
|
void cache_definition(name const & n, expr const & pre_type, expr const & pre_value,
|
|
|
|
level_param_names const & ls, expr const & type, expr const & value);
|
|
|
|
/** \brief Try to find an elaborated definition for (n, pre_type, pre_value) in the cache */
|
2014-10-08 15:26:39 +00:00
|
|
|
optional<std::tuple<level_param_names, expr, expr>>
|
|
|
|
find_cached_definition(name const & n, expr const & pre_type, expr const & pre_value);
|
2014-08-11 20:55:29 +00:00
|
|
|
void erase_cached_definition(name const & n) { if (m_cache) m_cache->erase(n); }
|
2014-08-10 18:04:16 +00:00
|
|
|
|
2014-08-17 19:14:42 +00:00
|
|
|
bool are_info_lines_valid(unsigned start_line, unsigned end_line) const;
|
|
|
|
bool collecting_info() const { return m_info_manager; }
|
2014-10-30 00:28:35 +00:00
|
|
|
void remove_proof_state_info(pos_info const & start, pos_info const & end);
|
2014-08-17 19:14:42 +00:00
|
|
|
|
2014-08-15 00:44:07 +00:00
|
|
|
void set_index(declaration_index * i) { m_index = i; }
|
2014-08-23 19:39:59 +00:00
|
|
|
void add_decl_index(name const & n, pos_info const & pos, name const & k, expr const & t);
|
2014-08-15 00:44:07 +00:00
|
|
|
void add_ref_index(name const & n, pos_info const & pos);
|
2014-09-04 16:30:25 +00:00
|
|
|
void add_abbrev_index(name const & a, name const & d);
|
2014-08-15 00:44:07 +00:00
|
|
|
|
2014-06-11 00:02:06 +00:00
|
|
|
environment const & env() const { return m_env; }
|
|
|
|
io_state const & ios() const { return m_ios; }
|
2014-06-14 16:56:05 +00:00
|
|
|
local_level_decls const & get_local_level_decls() const { return m_local_level_decls; }
|
|
|
|
local_expr_decls const & get_local_expr_decls() const { return m_local_decls; }
|
2014-06-11 00:02:06 +00:00
|
|
|
|
2014-07-03 15:33:29 +00:00
|
|
|
bool has_tactic_decls();
|
|
|
|
expr mk_by(expr const & t, pos_info const & pos);
|
|
|
|
|
2014-10-13 17:05:38 +00:00
|
|
|
bool keep_new_thms() const { return m_keep_theorem_mode != keep_theorem_mode::DiscardAll; }
|
|
|
|
|
2014-06-17 00:27:43 +00:00
|
|
|
void updt_options();
|
2014-10-30 21:45:35 +00:00
|
|
|
options get_options() const { return m_ios.get_options(); }
|
2014-06-17 00:27:43 +00:00
|
|
|
template<typename T> void set_option(name const & n, T const & v) { m_ios.set_option(n, v); }
|
|
|
|
|
2014-06-21 00:17:39 +00:00
|
|
|
name mk_fresh_name() { return m_ngen.next(); }
|
2014-07-06 00:39:49 +00:00
|
|
|
name_generator mk_ngen() { return m_ngen.mk_child(); }
|
2014-06-21 00:17:39 +00:00
|
|
|
|
2014-06-13 22:13:32 +00:00
|
|
|
/** \brief Return the current position information */
|
|
|
|
pos_info pos() const { return pos_info(m_scanner.get_line(), m_scanner.get_pos()); }
|
|
|
|
expr save_pos(expr e, pos_info p);
|
|
|
|
expr rec_save_pos(expr const & e, pos_info p);
|
2014-12-11 06:25:40 +00:00
|
|
|
pos_info pos_of(expr const & e, pos_info default_pos) const;
|
|
|
|
pos_info pos_of(expr const & e) const { return pos_of(e, pos()); }
|
2014-06-13 22:13:32 +00:00
|
|
|
pos_info cmd_pos() const { return m_last_cmd_pos; }
|
2014-08-23 19:39:59 +00:00
|
|
|
name const & get_cmd_token() const { return m_cmd_token; }
|
2014-06-14 14:28:56 +00:00
|
|
|
void set_line(unsigned p) { return m_scanner.set_line(p); }
|
2014-06-13 22:13:32 +00:00
|
|
|
|
2014-06-18 00:15:38 +00:00
|
|
|
expr mk_app(expr fn, expr arg, pos_info const & p);
|
|
|
|
expr mk_app(std::initializer_list<expr> const & args, pos_info const & p);
|
|
|
|
|
2014-07-12 21:50:57 +00:00
|
|
|
unsigned num_threads() const { return m_num_threads; }
|
2014-07-26 21:01:20 +00:00
|
|
|
void add_delayed_theorem(environment const & env, name const & n, level_param_names const & ls, expr const & t, expr const & v);
|
2014-07-12 21:50:57 +00:00
|
|
|
|
2014-06-13 22:13:32 +00:00
|
|
|
/** \brief Read the next token. */
|
|
|
|
void scan() { m_curr = m_scanner.scan(m_env); }
|
|
|
|
/** \brief Return the current token */
|
|
|
|
scanner::token_kind curr() const { return m_curr; }
|
|
|
|
/** \brief Return true iff the current token is an identifier */
|
|
|
|
bool curr_is_identifier() const { return curr() == scanner::token_kind::Identifier; }
|
|
|
|
/** \brief Return true iff the current token is a numeral */
|
|
|
|
bool curr_is_numeral() const { return curr() == scanner::token_kind::Numeral; }
|
2014-06-15 05:13:25 +00:00
|
|
|
/** \brief Return true iff the current token is a string */
|
|
|
|
bool curr_is_string() const { return curr() == scanner::token_kind::String; }
|
|
|
|
/** \brief Return true iff the current token is a keyword */
|
|
|
|
bool curr_is_keyword() const { return curr() == scanner::token_kind::Keyword; }
|
|
|
|
/** \brief Return true iff the current token is a keyword */
|
2014-06-17 01:42:39 +00:00
|
|
|
bool curr_is_command() const { return curr() == scanner::token_kind::CommandKeyword; }
|
2014-10-21 20:30:40 +00:00
|
|
|
/** \brief Return true iff the current token is EOF */
|
|
|
|
bool curr_is_eof() const { return curr() == scanner::token_kind::Eof; }
|
2014-06-17 01:42:39 +00:00
|
|
|
/** \brief Return true iff the current token is a keyword */
|
2014-06-15 05:13:25 +00:00
|
|
|
bool curr_is_quoted_symbol() const { return curr() == scanner::token_kind::QuotedSymbol; }
|
2014-08-18 00:03:54 +00:00
|
|
|
/** \brief Return true iff the current token is a keyword named \c tk or an identifier named \c tk */
|
2014-06-15 05:13:25 +00:00
|
|
|
bool curr_is_token_or_id(name const & tk) const;
|
2014-08-18 00:03:54 +00:00
|
|
|
/** \brief Return true iff the current token is a command, EOF, period or script block */
|
|
|
|
bool curr_is_command_like() const;
|
2014-06-13 22:13:32 +00:00
|
|
|
/** \brief Read the next token if the current one is not End-of-file. */
|
|
|
|
void next() { if (m_curr != scanner::token_kind::Eof) scan(); }
|
|
|
|
/** \brief Return true iff the current token is a keyword (or command keyword) named \c tk */
|
|
|
|
bool curr_is_token(name const & tk) const;
|
|
|
|
/** \brief Check current token, and move to next characther, throw exception if current token is not \c tk. */
|
|
|
|
void check_token_next(name const & tk, char const * msg);
|
2014-10-21 20:30:40 +00:00
|
|
|
void check_token_or_id_next(name const & tk, char const * msg);
|
2014-10-08 15:26:39 +00:00
|
|
|
/** \brief Check if the current token is an identifier, if it is return it and move to next token,
|
|
|
|
otherwise throw an exception. */
|
2014-06-13 22:13:32 +00:00
|
|
|
name check_id_next(char const * msg);
|
2014-10-08 15:26:39 +00:00
|
|
|
/** \brief Check if the current token is an atomic identifier, if it is, return it and move to next token,
|
|
|
|
otherwise throw an exception. */
|
2014-07-08 01:56:51 +00:00
|
|
|
name check_atomic_id_next(char const * msg);
|
2014-07-15 00:19:47 +00:00
|
|
|
/** \brief Check if the current token is a constant, if it is, return it and move to next token, otherwise throw an exception. */
|
|
|
|
name check_constant_next(char const * msg);
|
2014-06-13 22:13:32 +00:00
|
|
|
|
|
|
|
mpq const & get_num_val() const { return m_scanner.get_num_val(); }
|
|
|
|
name const & get_name_val() const { return m_scanner.get_name_val(); }
|
|
|
|
std::string const & get_str_val() const { return m_scanner.get_str_val(); }
|
|
|
|
token_info const & get_token_info() const { return m_scanner.get_token_info(); }
|
|
|
|
std::string const & get_stream_name() const { return m_scanner.get_stream_name(); }
|
|
|
|
|
2014-07-10 17:32:00 +00:00
|
|
|
io_state_stream regular_stream() const { return regular(env(), ios()); }
|
|
|
|
io_state_stream diagnostic_stream() const { return diagnostic(env(), ios()); }
|
2014-06-13 22:13:32 +00:00
|
|
|
|
2014-06-14 14:28:56 +00:00
|
|
|
unsigned get_small_nat();
|
2014-06-12 16:08:38 +00:00
|
|
|
unsigned parse_small_nat();
|
2014-06-17 00:27:43 +00:00
|
|
|
double parse_double();
|
2014-06-12 16:08:38 +00:00
|
|
|
|
2014-07-29 02:04:57 +00:00
|
|
|
bool parse_local_notation_decl() { return parse_local_notation_decl(nullptr); }
|
2014-06-16 16:24:41 +00:00
|
|
|
|
2014-06-12 16:08:38 +00:00
|
|
|
level parse_level(unsigned rbp = 0);
|
2014-06-12 01:51:12 +00:00
|
|
|
|
2014-11-24 00:42:53 +00:00
|
|
|
expr parse_binder(unsigned rbp);
|
2014-10-11 01:08:03 +00:00
|
|
|
local_environment parse_binders(buffer<expr> & r, bool & last_block_delimited) {
|
2014-11-24 00:42:53 +00:00
|
|
|
unsigned rbp = 0; bool allow_empty = false;
|
|
|
|
return parse_binders(r, nullptr, last_block_delimited, allow_empty, rbp);
|
2014-10-11 01:08:03 +00:00
|
|
|
}
|
2014-11-24 00:42:53 +00:00
|
|
|
local_environment parse_binders(buffer<expr> & r, unsigned rbp) {
|
|
|
|
bool tmp; bool allow_empty = false;
|
|
|
|
return parse_binders(r, nullptr, tmp, allow_empty, rbp);
|
2014-10-11 01:08:03 +00:00
|
|
|
}
|
2014-11-04 06:55:51 +00:00
|
|
|
local_environment parse_optional_binders(buffer<expr> & r) {
|
2014-11-24 00:42:53 +00:00
|
|
|
bool tmp; bool allow_empty = true; unsigned rbp = 0;
|
|
|
|
return parse_binders(r, nullptr, tmp, allow_empty, rbp);
|
2014-11-04 06:55:51 +00:00
|
|
|
}
|
2014-10-11 01:08:03 +00:00
|
|
|
local_environment parse_binders(buffer<expr> & r, buffer<notation_entry> & nentries) {
|
2014-11-24 00:42:53 +00:00
|
|
|
bool tmp; bool allow_empty = false; unsigned rbp = 0;
|
|
|
|
return parse_binders(r, &nentries, tmp, allow_empty, rbp);
|
2014-10-11 01:08:03 +00:00
|
|
|
}
|
2014-06-30 23:52:20 +00:00
|
|
|
optional<binder_info> parse_optional_binder_info();
|
|
|
|
binder_info parse_binder_info();
|
|
|
|
void parse_close_binder_info(optional<binder_info> const & bi);
|
|
|
|
void parse_close_binder_info(binder_info const & bi) { return parse_close_binder_info(optional<binder_info>(bi)); }
|
2014-06-11 00:02:06 +00:00
|
|
|
|
2014-06-21 00:17:39 +00:00
|
|
|
/** \brief Convert an identifier into an expression (constant or local constant) based on the current scope */
|
|
|
|
expr id_to_expr(name const & id, pos_info const & p);
|
|
|
|
|
2014-06-11 00:02:06 +00:00
|
|
|
expr parse_expr(unsigned rbp = 0);
|
2015-01-17 17:38:10 +00:00
|
|
|
/** \brief Parse an (optionally) qualified expression.
|
|
|
|
If the input is of the form <id> : <expr>, then return the pair (some(id), expr).
|
|
|
|
Otherwise, parse the next expression and return (none, expr).
|
2015-01-16 20:42:42 +00:00
|
|
|
*/
|
|
|
|
pair<optional<name>, expr> parse_qualified_expr(unsigned rbp = 0);
|
2015-01-17 17:38:10 +00:00
|
|
|
/** \brief If the input is of the form <id> := <expr>, then return the pair (some(id), expr).
|
|
|
|
Otherwise, parse the next expression and return (none, expr).
|
|
|
|
*/
|
|
|
|
pair<optional<name>, expr> parse_optional_assignment(unsigned rbp = 0);
|
2015-01-16 20:42:42 +00:00
|
|
|
|
2014-06-17 20:35:31 +00:00
|
|
|
expr parse_led(expr left);
|
2014-06-30 16:14:55 +00:00
|
|
|
expr parse_scoped_expr(unsigned num_params, expr const * ps, local_environment const & lenv, unsigned rbp = 0);
|
2014-10-13 20:07:42 +00:00
|
|
|
expr parse_scoped_expr(buffer<expr> const & ps, local_environment const & lenv, unsigned rbp = 0) {
|
2014-06-15 18:30:52 +00:00
|
|
|
return parse_scoped_expr(ps.size(), ps.data(), lenv, rbp);
|
|
|
|
}
|
2014-06-30 16:14:55 +00:00
|
|
|
expr parse_scoped_expr(unsigned num_params, expr const * ps, unsigned rbp = 0) {
|
2014-06-15 18:30:52 +00:00
|
|
|
return parse_scoped_expr(num_params, ps, local_environment(m_env), rbp);
|
|
|
|
}
|
2014-10-13 20:07:42 +00:00
|
|
|
expr parse_scoped_expr(buffer<expr> const & ps, unsigned rbp = 0) { return parse_scoped_expr(ps.size(), ps.data(), rbp); }
|
2014-06-11 00:02:06 +00:00
|
|
|
|
2014-10-26 22:47:29 +00:00
|
|
|
struct local_scope { parser & m_p; environment m_env;
|
2014-12-11 06:25:40 +00:00
|
|
|
local_scope(parser & p, bool save_options = false);
|
|
|
|
local_scope(parser & p, environment const & env);
|
|
|
|
local_scope(parser & p, optional<environment> const & env);
|
|
|
|
~local_scope();
|
2014-10-26 22:47:29 +00:00
|
|
|
};
|
2014-10-10 03:48:20 +00:00
|
|
|
bool has_locals() const { return !m_local_decls.empty() || !m_local_level_decls.empty(); }
|
2014-10-04 14:13:19 +00:00
|
|
|
void add_local_level(name const & n, level const & l, bool is_variable = false);
|
2014-10-03 00:29:22 +00:00
|
|
|
void add_local_expr(name const & n, expr const & p, bool is_variable = false);
|
2015-01-24 01:42:19 +00:00
|
|
|
void add_parameter(name const & n, expr const & p);
|
2014-06-30 16:14:55 +00:00
|
|
|
void add_local(expr const & p) { return add_local_expr(local_pp_name(p), p); }
|
2015-01-24 01:42:19 +00:00
|
|
|
bool has_params() const { return m_has_params; }
|
2014-11-09 22:43:22 +00:00
|
|
|
bool is_local_decl(expr const & l) const { return is_local(l) && m_local_decls.contains(local_pp_name(l)); }
|
2014-10-11 17:25:02 +00:00
|
|
|
bool is_local_level_variable(name const & n) const { return m_level_variables.contains(n); }
|
|
|
|
bool is_local_variable(name const & n) const { return m_variables.contains(n); }
|
|
|
|
bool is_local_variable(expr const & e) const { return is_local_variable(local_pp_name(e)); }
|
2014-10-03 14:23:24 +00:00
|
|
|
void include_variable(name const & n) { m_include_vars.insert(n); }
|
|
|
|
void omit_variable(name const & n) { m_include_vars.erase(n); }
|
|
|
|
bool is_include_variable(name const & n) const { return m_include_vars.contains(n); }
|
|
|
|
void get_include_variables(buffer<expr> & vars) const;
|
2014-06-13 22:13:32 +00:00
|
|
|
/** \brief Position of the local level declaration named \c n in the sequence of local level decls. */
|
2014-06-14 16:56:05 +00:00
|
|
|
unsigned get_local_level_index(name const & n) const;
|
2014-06-13 22:13:32 +00:00
|
|
|
/** \brief Position of the local declaration named \c n in the sequence of local decls. */
|
2014-06-14 16:56:05 +00:00
|
|
|
unsigned get_local_index(name const & n) const;
|
2014-10-03 00:42:33 +00:00
|
|
|
unsigned get_local_index(expr const & e) const { return get_local_index(local_pp_name(e)); }
|
2014-06-14 00:30:35 +00:00
|
|
|
/** \brief Return the local parameter named \c n */
|
2014-06-30 16:14:55 +00:00
|
|
|
expr const * get_local(name const & n) const { return m_local_decls.find(n); }
|
2014-10-08 15:26:39 +00:00
|
|
|
/** \brief Return local declarations as a list of local constants. */
|
|
|
|
list<expr> locals_to_context() const;
|
2014-10-09 05:21:29 +00:00
|
|
|
/** \brief Return all local declarations and aliases */
|
|
|
|
list<pair<name, expr>> const & get_local_entries() const { return m_local_decls.get_entries(); }
|
|
|
|
/** \brief Return all local level declarations */
|
|
|
|
list<pair<name, level>> const & get_local_level_entries() const { return m_local_level_decls.get_entries(); }
|
|
|
|
/** \brief By default, when the parser finds a unknown identifier, it signs an error.
|
2014-10-26 16:47:11 +00:00
|
|
|
These scope objects temporarily change this behavior. In any scope where this object
|
|
|
|
is declared, the parse creates a constant/local even when the identifier is unknown.
|
|
|
|
This behavior is useful when we are trying to parse mutually recursive declarations and
|
|
|
|
tactics.
|
2014-06-17 17:30:03 +00:00
|
|
|
*/
|
2014-10-26 16:47:11 +00:00
|
|
|
struct undef_id_to_const_scope : public flet<undef_id_behavior> { undef_id_to_const_scope(parser & p); };
|
|
|
|
struct undef_id_to_local_scope : public flet<undef_id_behavior> { undef_id_to_local_scope(parser &); };
|
2014-06-17 17:30:03 +00:00
|
|
|
|
2014-12-11 06:25:40 +00:00
|
|
|
/** \brief Return the size of the stack of undefined local constants */
|
|
|
|
unsigned get_num_undef_ids() const { return m_undef_ids.size(); }
|
|
|
|
/** \brief Return the i-th undefined local constants */
|
|
|
|
expr const & get_undef_id(unsigned i) const { return m_undef_ids[i]; }
|
|
|
|
|
2014-07-07 04:54:16 +00:00
|
|
|
/** \brief Elaborate \c e, and tolerate metavariables in the result. */
|
2014-07-14 04:04:01 +00:00
|
|
|
std::tuple<expr, level_param_names> elaborate_relaxed(expr const & e, list<expr> const & ctx = list<expr>());
|
2014-07-07 04:54:16 +00:00
|
|
|
/** \brief Elaborate \c e, and ensure it is a type. */
|
2014-10-08 15:26:39 +00:00
|
|
|
std::tuple<expr, level_param_names> elaborate_type(expr const & e, list<expr> const & ctx = list<expr>(),
|
|
|
|
bool clear_pre_info = true);
|
2014-07-07 04:54:16 +00:00
|
|
|
/** \brief Elaborate \c e in the given environment. */
|
|
|
|
std::tuple<expr, level_param_names> elaborate_at(environment const & env, expr const & e);
|
2014-07-08 21:28:33 +00:00
|
|
|
/** \brief Elaborate \c e (making sure the result does not have metavariables). */
|
|
|
|
std::tuple<expr, level_param_names> elaborate(expr const & e) { return elaborate_at(m_env, e); }
|
2014-07-07 04:54:16 +00:00
|
|
|
/** \brief Elaborate the definition n : t := v */
|
2014-07-27 19:01:06 +00:00
|
|
|
std::tuple<expr, expr, level_param_names> elaborate_definition(name const & n, expr const & t, expr const & v, bool is_opaque);
|
2014-07-12 21:50:57 +00:00
|
|
|
/** \brief Elaborate the definition n : t := v in the given environment*/
|
2014-07-27 19:01:06 +00:00
|
|
|
std::tuple<expr, expr, level_param_names> elaborate_definition_at(environment const & env, local_level_decls const & lls,
|
|
|
|
name const & n, expr const & t, expr const & v, bool is_opaque);
|
2014-06-12 03:56:10 +00:00
|
|
|
|
2014-08-01 01:35:57 +00:00
|
|
|
expr mk_sorry(pos_info const & p);
|
|
|
|
bool used_sorry() const { return m_used_sorry; }
|
|
|
|
void declare_sorry();
|
|
|
|
|
2014-07-08 21:28:33 +00:00
|
|
|
parser_pos_provider get_pos_provider() const { return parser_pos_provider(m_pos_table, get_stream_name(), m_last_cmd_pos); }
|
2014-11-24 16:35:49 +00:00
|
|
|
void display_information_pos(pos_info p);
|
2014-07-08 21:28:33 +00:00
|
|
|
|
2014-06-11 00:02:06 +00:00
|
|
|
/** parse all commands in the input stream */
|
2014-06-11 18:26:17 +00:00
|
|
|
bool operator()() { return parse_commands(); }
|
2014-06-11 00:02:06 +00:00
|
|
|
};
|
2014-06-11 18:26:17 +00:00
|
|
|
|
2014-08-15 00:44:07 +00:00
|
|
|
bool parse_commands(environment & env, io_state & ios, std::istream & in, char const * strm_name,
|
2014-08-15 01:12:12 +00:00
|
|
|
bool use_exceptions, unsigned num_threads, definition_cache * cache = nullptr,
|
2014-10-13 17:05:38 +00:00
|
|
|
declaration_index * index = nullptr, keep_theorem_mode tmode = keep_theorem_mode::All);
|
2014-08-10 18:04:16 +00:00
|
|
|
bool parse_commands(environment & env, io_state & ios, char const * fname, bool use_exceptions, unsigned num_threads,
|
2014-10-13 17:05:38 +00:00
|
|
|
definition_cache * cache = nullptr, declaration_index * index = nullptr,
|
|
|
|
keep_theorem_mode tmode = keep_theorem_mode::All);
|
2014-09-22 17:27:48 +00:00
|
|
|
|
|
|
|
void initialize_parser();
|
|
|
|
void finalize_parser();
|
2014-06-11 00:02:06 +00:00
|
|
|
}
|