diff --git a/include/compiler/treeifier/ast.hh b/include/compiler/treeifier/ast.hh index f589d37..6594c24 100644 --- a/include/compiler/treeifier/ast.hh +++ b/include/compiler/treeifier/ast.hh @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include "compiler/treeifier/tokenizer.hh" @@ -22,6 +23,7 @@ namespace ppc::comp::tree::ast { class group_t { private: std::map named_parsers; + std::set unnamed_parsers; std::map parsers; public: group_t &insert(const std::string &name, parser_t parser, const std::string &relative_to, bool after); @@ -74,6 +76,7 @@ namespace ppc::comp::tree::ast { loc_namespace_name_t map_to_nmsp(const data::map_t &map); } - parser_func_t parse_glob, parse_nmsp, parse_identifier, parse_type, parse_func, parse_field, parse_exp, parse_stat_exp; + parser_func_t parse_glob, parse_nmsp, parse_identifier, parse_type, parse_exp, parse_stat_exp; + parser_func_t parse_func, parse_field, parse_export; parser_func_t parse_exp_var, parse_exp_str_lit, parse_exp_int_lit, parse_exp_float_lit; } \ No newline at end of file diff --git a/src/compiler/treeifier/ast/parsers/group.cc b/src/compiler/treeifier/ast/parsers/group.cc index fa12cc2..4cad173 100644 --- a/src/compiler/treeifier/ast/parsers/group.cc +++ b/src/compiler/treeifier/ast/parsers/group.cc @@ -4,6 +4,7 @@ #include #include #include +#include using namespace ppc::comp::tree; using namespace ppc::comp::tree::ast; @@ -15,7 +16,7 @@ static bool read_nmsp(ast_ctx_t &ctx, size_t &i, lang::loc_namespace_name_t &nam map_t res; if (!h.parse(parse_nmsp, res)) return false; name = conv::map_to_nmsp(res); - return true; + return h.submit(false); } template static bool resolve_nmsp(ast_ctx_t &ctx, const lang::namespace_name_t &name, T begin, T end, lang::namespace_name_t &actual_name) { @@ -45,14 +46,14 @@ group_t &group_t::insert(const std::string &name, parser_t parser, const std::st throw "The parser '" + name + "' is already in the group."; } - auto it = parsers.find(relative_to); - if (it == parsers.end()) { - throw "The parser '" + relative_to + "' isn't in the group."; + auto it = unnamed_parsers.find(relative_to); + if (it == unnamed_parsers.end()) { + throw "The parser '" + relative_to + "' isn't in the group or isn't unnamed."; } if (after) it++; - parsers.insert(it, { name, parser }); + unnamed_parsers.insert(it, name); return *this; } @@ -73,11 +74,18 @@ group_t &group_t::add_last(const std::string &name, parser_t parser) { } parsers.emplace(name, parser); + unnamed_parsers.emplace(name); return *this; } group_t &group_t::add_named(const std::string &name, parser_t parser, const lang::namespace_name_t &identifier) { - add_last(name, parser); + if (parsers.find(name) != parsers.end()) { + throw "The parser '" + name + "' is already in the group."; + } + + parsers.emplace(name, parser); + named_parsers.emplace(identifier, name); + return *this; } @@ -92,16 +100,14 @@ bool group_t::operator()(ast_ctx_t &ctx, size_t &i, data::map_t &out) const { if (resolve_nmsp(ctx, name.strip_location(), named_parsers.begin(), named_parsers.end(), actual)) { auto parser = parsers.find(this->named_parsers.find(actual)->second); out["$_name"] = parser->first; - if (parser->second(ctx, i, out)) return true; + if (h.parse(parser->second, out)) return h.submit(false); else throw message_t::error("Unexpected construct specifier.", h.res_loc()); } } - unordered_map errors; - - for (auto parser : parsers) { - out["$_name"] = parser.first; - if ((*parser.second)(ctx, i, out)) return true; + for (auto name : unnamed_parsers) { + out["$_name"] = name; + if (parsers.at(name)(ctx, i, out)) return true; } stringstream m;