// using [class] id (id ...) (renaming id->id id->id) (hiding id ... id) environment using_cmd(parser & p) { environment env = p.env(); while (true) { name cls = parse_class(p); bool decls = cls.is_anonymous() || cls == g_decls || cls == g_declarations; auto pos = p.pos(); name ns = p.check_id_next("invalid 'using' command, identifier expected"); optional<name> real_ns = to_valid_namespace_name(env, ns); if (!real_ns) throw parser_error(sstream() << "invalid namespace name '" << ns << "'", pos); ns = *real_ns; env = using_namespace(env, p.ios(), ns, cls); if (decls) { // Remark: we currently to not allow renaming and hiding of universe levels buffer<name> exceptions; bool found_explicit = false; while (p.curr_is_token(g_lparen)) { p.next(); if (p.curr_is_token_or_id(g_renaming)) { p.next(); while (p.curr_is_identifier()) { name from_id = p.get_name_val(); p.next(); p.check_token_next(g_arrow, "invalid 'using' command renaming, '->' expected"); name to_id = p.check_id_next("invalid 'using' command renaming, identifier expected"); check_identifier(p, env, ns, from_id); exceptions.push_back(from_id); env = add_expr_alias(env, to_id, ns+from_id); } } else if (p.curr_is_token_or_id(g_hiding)) { p.next(); while (p.curr_is_identifier()) { name id = p.get_name_val(); p.next(); check_identifier(p, env, ns, id); exceptions.push_back(id); } } else if (p.curr_is_identifier()) { found_explicit = true; while (p.curr_is_identifier()) { name id = p.get_name_val(); p.next(); check_identifier(p, env, ns, id); env = add_expr_alias(env, id, ns+id); } } else { throw parser_error("invalid 'using' command option, identifier, 'hiding' or 'renaming' expected", p.pos()); } if (found_explicit && !exceptions.empty()) throw parser_error("invalid 'using' command option, mixing explicit and implicit 'using' options", p.pos()); p.check_token_next(g_rparen, "invalid 'using' command option, ')' expected"); } if (!found_explicit) env = add_aliases(env, ns, name(), exceptions.size(), exceptions.data()); } if (!p.curr_is_token(g_lbracket) && !p.curr_is_identifier()) break; } return env; }
static transition parse_transition(parser & p, optional<parse_table> const & pt, name const & tk, buffer<expr> & locals, buffer<token_entry> & new_tokens, notation_entry_group grp, name const & pp_tk) { if (p.curr_is_token_or_id(get_binder_tk())) { p.next(); unsigned rbp = parse_binders_rbp(p); return transition(tk, mk_binder_action(rbp), pp_tk); } else if (p.curr_is_token_or_id(get_binders_tk())) { p.next(); unsigned rbp = parse_binders_rbp(p); return transition(tk, mk_binders_action(rbp), pp_tk); } else if (p.curr_is_identifier()) { unsigned default_prec = get_default_prec(pt, tk); name n = p.get_name_val(); p.next(); action a = parse_action(p, tk, default_prec, locals, new_tokens, grp); expr local_type = mk_Prop(); // type used in notation local declarations, it is irrelevant expr l = mk_local(n, local_type); p.add_local(l); locals.push_back(l); return transition(tk, a, pp_tk); } else if (p.curr_is_quoted_symbol() || p.curr_is_keyword() || p.curr_is_token(get_assign_tk()) || p.curr_is_command() || p.curr_is_eof()) { return transition(tk, mk_skip_action(), pp_tk); } else { throw parser_error("invalid notation declaration, quoted-symbol, identifier, " "'binder', 'binders' expected", p.pos()); } }
static name parse_quoted_symbol_or_token(parser & p, buffer<token_entry> & new_tokens, bool & used_default, notation_entry_group grp) { used_default = false; if (p.curr_is_quoted_symbol()) { environment const & env = p.env(); auto pp_tk = p.get_name_val(); auto tks = utf8_trim(pp_tk.to_string()); auto tkcs = tks.c_str(); check_not_forbidden(tkcs); p.next(); if (p.curr_is_token(get_colon_tk())) { p.next(); unsigned prec = parse_precedence(p); new_tokens.push_back(mk_token_entry(tkcs, prec, grp)); } else if (!get_precedence(env, tkcs, grp)) { new_tokens.push_back(mk_token_entry(tkcs, LEAN_DEFAULT_PRECEDENCE, grp)); used_default = true; } return pp_tk; } else if (p.curr_is_keyword()) { auto tk = p.get_token_info().token(); check_not_forbidden(tk.to_string().c_str()); p.next(); return tk; } else { throw parser_error("invalid notation declaration, symbol expected", p.pos()); } }
static void parse_notation_local(parser & p, buffer<expr> & locals) { if (p.curr_is_identifier()) { name n = p.get_name_val(); p.next(); expr local_type = mk_Prop(); // type used in notation local declarations, it is irrelevant expr l = mk_local(n, local_type); // remark: the type doesn't matter p.add_local(l); locals.push_back(l); } else { throw parser_error("invalid notation declaration, identifier expected", p.pos()); } }
static name parse_class(parser & p) { if (p.curr_is_token(g_lbracket)) { p.next(); name n; if (p.curr_is_identifier()) n = p.get_name_val(); else if (p.curr_is_keyword() || p.curr_is_command()) n = p.get_token_info().value(); else throw parser_error("invalid 'using' command, identifier or symbol expected", p.pos()); p.next(); p.check_token_next(g_rbracket, "invalid 'using' command, ']' expected"); return n; } else { return name(); } }