From 452884a74c2e281412e460da97ea85a6a3988c48 Mon Sep 17 00:00:00 2001 From: TopchetoEU <36534413+TopchetoEU@users.noreply.github.com> Date: Tue, 4 Oct 2022 20:36:30 +0300 Subject: [PATCH] feat: implement group parser --- src/compiler/treeifier/parsers/group.cc | 43 +++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/compiler/treeifier/parsers/group.cc b/src/compiler/treeifier/parsers/group.cc index 0a6e26e..979c49d 100644 --- a/src/compiler/treeifier/parsers/group.cc +++ b/src/compiler/treeifier/parsers/group.cc @@ -1,11 +1,50 @@ #include "compiler/treeifier/ast.hh" +#include "compiler/treeifier/tokenizer.hh" +#include "compiler/treeifier/ast/helper.hh" #include +using namespace ppc::comp::tree; using namespace ppc::comp::tree::ast; using namespace std::string_literals; +static bool read_nmsp(ast_ctx_t &ctx, size_t &i, const lang::namespace_name_t &name) { + tree_helper_t h(ctx, i); + + size_t equal_i = 0; + + while (true) { + if (h.ended()) break; + if (equal_i >= name.size()) return false; + auto &curr = h.curr(); + if (!curr.is_identifier()) return false; + + if (name[equal_i] != curr.identifier()) return false; + + if (h.try_advance() && h.curr().is_operator(operator_t::DOUBLE_COLON)) { + equal_i++; + } + else break; + } + + return equal_i != name.size(); +} + bool group_parser_t::parse(ast_ctx_t &ctx, size_t &i, data::map_t &out) const { - return false; + tree_helper_t h(ctx, i); + + for (auto &pair : named_parsers) { + if (!read_nmsp(ctx, i, pair.first)) continue; + auto &parser = *pair.second; + return h.parse(parser, out); + } + for (auto parser : parsers) { + try { + return h.parse(*parser, out); + } + catch (std::string) { + return false; + } + } } @@ -14,7 +53,7 @@ group_parser_t &group_parser_t::add(parser_t &parser) { return *this; } group_parser_t &group_parser_t::add(parser_t &parser, const lang::namespace_name_t &name) { - if (name.is_empty()) throw "Name can't be empty."s; + if (name.empty()) throw "Name can't be empty."s; if (std::find(parsers.begin(), parsers.end(), &parser) != parsers.end()) { throw "Parser '" + name.to_string() + "' already in group."; }