Пример #1
0
static unsigned parse_precedence_core(parser & p) {
    auto pos = p.pos();
    if (p.curr_is_numeral()) {
        return p.parse_small_nat();
    } else {
        environment env = p.env();
        env = open_prec_aliases(env);
        parser::local_scope scope(p, env);
        expr pre_val = p.parse_expr(get_max_prec());
        pre_val  = mk_typed_expr(mk_constant(get_num_name()), pre_val);
        expr val = std::get<0>(p.elaborate(pre_val, list<expr>()));
        val = normalize(p.env(), val);
        if (optional<mpz> mpz_val = to_num_core(val)) {
            if (!mpz_val->is_unsigned_int())
                throw parser_error("invalid 'precedence', argument does not fit in a machine integer", pos);
            return mpz_val->get_unsigned_int();
        } else {
            throw parser_error("invalid 'precedence', argument does not evaluate to a numeral", pos);
        }
    }
}
Пример #2
0
environment set_option_cmd(parser & p) {
    auto id_pos = p.pos();
    name id = p.check_id_next("invalid set option, identifier (i.e., option name) expected");
    auto decl_it = get_option_declarations().find(id);
    if (decl_it == get_option_declarations().end()) {
        // add "lean" prefix
        name lean_id = name("lean") + id;
        decl_it = get_option_declarations().find(lean_id);
        if (decl_it == get_option_declarations().end()) {
            throw parser_error(sstream() << "unknown option '" << id << "', type 'help options.' for list of available options", id_pos);
        } else {
            id = lean_id;
        }
    }
    option_kind k = decl_it->second.kind();
    if (k == BoolOption) {
        if (p.curr_is_token_or_id(g_true))
            p.set_option(id, true);
        else if (p.curr_is_token_or_id(g_false))
            p.set_option(id, false);
        else
            throw parser_error("invalid Boolean option value, 'true' or 'false' expected", p.pos());
        p.next();
    } else if (k == StringOption) {
        if (!p.curr_is_string())
            throw parser_error("invalid option value, given option is not a string", p.pos());
        p.set_option(id, p.get_str_val());
        p.next();
    } else if (k == DoubleOption) {
        p.set_option(id, p.parse_double());
    } else if (k == UnsignedOption || k == IntOption) {
        p.set_option(id, p.parse_small_nat());
    } else {
        throw parser_error("invalid option value, 'true', 'false', string, integer or decimal value expected", p.pos());
    }
    p.updt_options();
    return p.env();
}
Пример #3
0
void decl_attributes::parse(parser & p) {
    buffer<char const *> attr_tokens;
    get_attribute_tokens(attr_tokens);
    while (true) {
        auto pos   = p.pos();
        if (auto it = parse_priority(p)) {
            m_prio = *it;
            bool has_prio_attr = false;
            for (auto const & entry : m_entries) {
                if (get_attribute_kind(entry.m_attr.c_str()) == attribute_kind::Prioritized) {
                    has_prio_attr = true;
                    break;
                }
            }
            if (!has_prio_attr) {
                throw parser_error("invalid '[priority]' attribute, declaration has not been marked with a prioritized attribute", pos);
            }
        } else if (p.curr_is_token(get_parsing_only_tk())) {
            if (!m_is_abbrev)
                throw parser_error("invalid '[parsing_only]' attribute, only abbreviations can be "
                                   "marked as '[parsing_only]'", pos);
            m_parsing_only = true;
            p.next();
        } else {
            bool found = false;
            for (char const * tk : attr_tokens) {
                if (p.curr_is_token(tk)) {
                    p.next();
                    char const * attr = get_attribute_from_token(tk);
                    for (auto const & entry : m_entries) {
                        if (are_incompatible(entry.m_attr.c_str(), attr)) {
                            throw parser_error(sstream() << "invalid attribute [" << attr
                                               << "], declaration was already marked with [" << entry.m_attr << "]", pos);
                        }
                    }
                    switch (get_attribute_kind(attr)) {
                    case attribute_kind::Default:
                    case attribute_kind::Prioritized:
                        m_entries = cons(entry(attr), m_entries);
                        break;
                    case attribute_kind::Parametric: {
                        unsigned v = p.parse_small_nat();
                        if (v == 0)
                            throw parser_error("invalid attribute parameter, value must be positive", pos);
                        p.check_token_next(get_rbracket_tk(), "invalid attribute, ']' expected");
                        m_entries = cons(entry(attr, v-1), m_entries);
                        break;
                    }
                    case attribute_kind::OptParametric:
                        if (!p.curr_is_token(get_rbracket_tk())) {
                            unsigned v = p.parse_small_nat();
                            if (v == 0)
                                throw parser_error("invalid attribute parameter, value must be positive", pos);
                            p.check_token_next(get_rbracket_tk(), "invalid attribute, ']' expected");
                            m_entries = cons(entry(attr, v-1), m_entries);
                        } else {
                            p.check_token_next(get_rbracket_tk(), "invalid attribute, ']' expected");
                            m_entries = cons(entry(attr), m_entries);
                        }
                        break;
                    case attribute_kind::MultiParametric: {
                        buffer<unsigned> vs;
                        while (true) {
                            unsigned v = p.parse_small_nat();
                            if (v == 0)
                                throw parser_error("invalid attribute parameter, value must be positive", pos);
                            vs.push_back(v-1);
                            if (p.curr_is_token(get_rbracket_tk()))
                                break;
                        }
                        p.next();
                        m_entries = cons(entry(attr, to_list(vs)), m_entries);
                        break;
                    }
                    }
                    found = true;
                    break;
                }
            }
            if (!found)
                break;
        }
    }
}