From 4d6ce93ae359cae1986c8164a41f6369e6b4ed54 Mon Sep 17 00:00:00 2001 From: TopchetoEU <36534413+TopchetoEU@users.noreply.github.com> Date: Sun, 9 Oct 2022 16:34:02 +0300 Subject: [PATCH] chore --- include/compiler/treeifier/ast.hh | 26 +++++-- include/compiler/treeifier/ast/helper.hh | 16 ++-- include/compiler/treeifier/tokenizer.hh | 21 ++--- include/utils/location.hh | 11 +-- src/compiler/treeifier/ast.cc | 25 ++++-- src/compiler/treeifier/ast/conv.cc | 17 +++-- src/compiler/treeifier/ast/parsers/glob.cc | 18 +++-- src/compiler/treeifier/ast/parsers/group.cc | 5 +- .../treeifier/ast/parsers/identifier.cc | 2 +- src/compiler/treeifier/ast/parsers/nmsp.cc | 6 +- src/main/main.cc | 19 +++-- src/utils/location.cc | 76 +++++-------------- 12 files changed, 115 insertions(+), 127 deletions(-) diff --git a/include/compiler/treeifier/ast.hh b/include/compiler/treeifier/ast.hh index 4eccdf1..ec079b5 100644 --- a/include/compiler/treeifier/ast.hh +++ b/include/compiler/treeifier/ast.hh @@ -17,9 +17,13 @@ namespace ppc::comp::tree::ast { class parser_t; class group_parser_t; - extern const parser_t &glob_parser; - extern const parser_t &identifier_parser; - extern const parser_t &nmsp_parser; + using parser_factory_t = parser_t *(*)(); + using group_parser_factory_t = group_parser_t *(*)(); + + extern parser_factory_t glob_parser; + extern parser_factory_t identifier_parser; + extern parser_factory_t nmsp_parser; + extern group_parser_factory_t def_parser; struct ast_ctx_t { private: @@ -42,25 +46,34 @@ namespace ppc::comp::tree::ast { std::unordered_map parsers; std::set groups; + void add_parser(const parser_t *parser); + void add_parser(const group_parser_t *parser); public: msg_stack_t &messages; std::vector &tokens; std::set imports; loc_namespace_name_t nmsp; - void add_parser(const parser_t &parser); - void add_parser(const group_parser_t &parser); + void add_parser(parser_factory_t factory) { add_parser(factory()); } + void add_parser(group_parser_factory_t factory) { add_parser(factory()); } + + ast_ctx_t &operator=(const ast_ctx_t &other) = delete; const parser_proxy_t parser; const group_proxy_t group; ast_ctx_t &init() { add_parser(glob_parser); + add_parser(identifier_parser); + add_parser(nmsp_parser); + add_parser(def_parser); return *this; } + bool parse(std::string parser, size_t &pi, data::map_t &out); static bool parse(msg_stack_t &messages, std::vector &tokens, data::map_t &out); + ~ast_ctx_t(); ast_ctx_t(msg_stack_t &messages, std::vector &tokens): messages(messages), tokens(tokens), @@ -81,6 +94,7 @@ namespace ppc::comp::tree::ast { return parse(ctx, i, out); } + virtual ~parser_t() = default; parser_t(const std::string &name): _name(name) { } }; @@ -93,6 +107,8 @@ namespace ppc::comp::tree::ast { group_parser_t &add(parser_t &parser, const lang::namespace_name_t &name); bool parse(ast_ctx_t &ctx, size_t &i, data::map_t &out) const; + + group_parser_t(const std::string &name): parser_t(name) { } }; namespace conv { diff --git a/include/compiler/treeifier/ast/helper.hh b/include/compiler/treeifier/ast/helper.hh index 08defde..affa012 100644 --- a/include/compiler/treeifier/ast/helper.hh +++ b/include/compiler/treeifier/ast/helper.hh @@ -82,25 +82,25 @@ namespace ppc::comp::tree::ast { throw_ended(reason); } - bool push_parse(const parser_t &parser, data::array_t &out) { + bool push_parse(const std::string &name, data::array_t &out) { data::map_t res; - if (parser(ctx, i, res)) { + if (parse(name, res)) { out.push(res); return true; } else return false; } - bool parse(const parser_t &parser, data::map_t &out) { - return parser(ctx, i, out); + bool parse(const std::string &name, data::map_t &out) { + return ctx.parse(name, i, out); } - void force_push_parse(const parser_t &parser, std::string message, data::array_t &out) { + void force_push_parse(const std::string &name, std::string message, data::array_t &out) { advance(message); bool success; try { - success = push_parse(parser, out); + success = push_parse(name, out); } catch (const message_t &msg) { ctx.messages.push(msg); @@ -109,12 +109,12 @@ namespace ppc::comp::tree::ast { if (!success) err(message); } - void force_parse(const parser_t &parser, std::string message, data::map_t &out) { + void force_parse(const std::string &name, std::string message, data::map_t &out) { advance(message); bool success; try { - success = parse(parser, out); + success = parse(name, out); } catch (const message_t &msg) { ctx.messages.push(msg); diff --git a/include/compiler/treeifier/tokenizer.hh b/include/compiler/treeifier/tokenizer.hh index f252f6d..feff58d 100644 --- a/include/compiler/treeifier/tokenizer.hh +++ b/include/compiler/treeifier/tokenizer.hh @@ -129,37 +129,31 @@ namespace ppc::comp::tree { bool is_identifier(std::string &&val) { return is_identifier() && identifier() == val; } token_t() { kind = NONE; } - token_t(const std::string &identifier, location_t loc = location_t::NONE) { + token_t(const std::string &identifier, location_t loc = location_t::NONE): location(loc) { kind = IDENTIFIER; data.identifier = new std::string { identifier }; - location = loc; } - token_t(operator_t op, location_t loc = location_t::NONE) { + token_t(operator_t op, location_t loc = location_t::NONE): location(loc) { kind = OPERATOR; data._operator = op; - location = loc; } - token_t(std::uint64_t val, location_t loc = location_t::NONE) { + token_t(std::uint64_t val, location_t loc = location_t::NONE): location(loc) { kind = INT; data.int_literal = val; - location = loc; } - token_t(double val, location_t loc = location_t::NONE) { + token_t(double val, location_t loc = location_t::NONE): location(loc) { kind = FLOAT; data.float_literal = val; - location = loc; } - token_t(char c, location_t loc = location_t::NONE) { + token_t(char c, location_t loc = location_t::NONE): location(loc) { kind = CHAR; data.char_literal = c; - location = loc; } - token_t(const std::vector &val, location_t loc = location_t::NONE) { + token_t(const std::vector &val, location_t loc = location_t::NONE): location(loc) { kind = STRING; data.string_literal = new std::vector { val }; - location = loc; } - token_t(const token_t &tok) { + token_t(const token_t &tok): location(tok.location) { kind = tok.kind; switch (kind) { case NONE: break; @@ -170,7 +164,6 @@ namespace ppc::comp::tree { case CHAR: data.char_literal = tok.data.char_literal; break; case STRING: data.string_literal = new std::vector { *tok.data.string_literal }; break; } - location = tok.location; } ~token_t() { diff --git a/include/utils/location.hh b/include/utils/location.hh index 0ab706f..65efeff 100644 --- a/include/utils/location.hh +++ b/include/utils/location.hh @@ -10,19 +10,20 @@ namespace ppc { std::size_t start; std::size_t length; std::size_t code_start; - std::string filename; + const std::string &filename; operator std::string() const { return to_string(); } std::string to_string() const; location_t intersect(location_t other) const; location_t(); - location_t(std::string filename); + location_t(const location_t &other): location_t(other.filename, other.line, other.start, other.code_start, other.length) { } + location_t(const std::string &filename); location_t(std::size_t line, std::size_t start); - location_t(std::string filename, std::size_t line, std::size_t start); + location_t(const std::string &filename, std::size_t line, std::size_t start); location_t(std::size_t line, std::size_t start, std::size_t code_start); - location_t(std::string filename, std::size_t line, std::size_t start, std::size_t code_start); + location_t(const std::string &filename, std::size_t line, std::size_t start, std::size_t code_start); location_t(std::size_t line, std::size_t start, std::size_t code_start, std::size_t length); - location_t(std::string filename, std::size_t line, std::size_t start, std::size_t code_start, std::size_t length); + location_t(const std::string &filename, std::size_t line, std::size_t start, std::size_t code_start, std::size_t length); }; } \ No newline at end of file diff --git a/src/compiler/treeifier/ast.cc b/src/compiler/treeifier/ast.cc index 2b1a552..7a30834 100644 --- a/src/compiler/treeifier/ast.cc +++ b/src/compiler/treeifier/ast.cc @@ -14,14 +14,20 @@ namespace ppc::comp::tree::ast { return *(const group_parser_t*)p; } - void ast_ctx_t::add_parser(const parser_t &parser) { - if (parsers.find(parser.name()) != parsers.end()) throw "The parser '" + parser.name() + "' already exists."; - parsers[parser.name()] = &parser; + ast_ctx_t::~ast_ctx_t() { + for (auto pair : parsers) { + delete pair.second; + } } - void ast_ctx_t::add_parser(const group_parser_t &parser) { - if (parsers.find(parser.name()) != parsers.end()) throw "The parser '" + parser.name() + "' already exists."; - parsers[parser.name()] = &parser; - groups.emplace(&parser); + + void ast_ctx_t::add_parser(const parser_t *parser) { + if (parsers.find(parser->name()) != parsers.end()) throw "The parser '" + parser->name() + "' already exists."; + parsers[parser->name()] = parser; + } + void ast_ctx_t::add_parser(const group_parser_t *parser) { + if (parsers.find(parser->name()) != parsers.end()) throw "The parser '" + parser->name() + "' already exists."; + parsers[parser->name()] = parser; + groups.emplace(parser); } bool ast_ctx_t::parse(msg_stack_t &messages, std::vector &tokens, data::map_t &out) { @@ -30,12 +36,15 @@ namespace ppc::comp::tree::ast { size_t i = 0; try { - return glob_parser(ctx, i, out); + return ctx.parse("$_glob", i, out); } catch (const message_t &msg) { messages.push(msg); return false; } } + bool ast_ctx_t::parse(std::string parser, size_t &pi, data::map_t &out) { + return this->parser[parser] (*this, pi, out); + } } diff --git a/src/compiler/treeifier/ast/conv.cc b/src/compiler/treeifier/ast/conv.cc index f323793..2526922 100644 --- a/src/compiler/treeifier/ast/conv.cc +++ b/src/compiler/treeifier/ast/conv.cc @@ -5,7 +5,7 @@ namespace ppc::comp::tree::ast::conv { return { { "location", conv::loc_to_map(loc.location) }, { "content", loc }, - { "$_name", identifier_parser.name() }, + { "$_name", "$_identifier" }, }; } located_t map_to_identifier(const data::map_t &map) { @@ -17,20 +17,17 @@ namespace ppc::comp::tree::ast::conv { { "$_name", "$_loc" }, }; - if (loc.filename != "") res["filename"] = loc.filename; + res["filename"] = loc.filename; if (loc.start != -1u) res["start"] = (float)loc.start; + if (loc.start != -1u) res["line"] = (float)loc.line; if (loc.code_start != -1u) res["code_start"] = (float)loc.code_start; if (loc.length != -1u) res["length"] = (float)loc.length; return res; } location_t map_to_loc(const data::map_t &map) { - location_t res; + location_t res(map["filename"].string()); - if (map.has("filename")) { - if (map["filename"].is_string()) res.filename = map["filename"].string(); - else throw "Expected key 'filename' to be a string."; - } if (map.has("start")) { if (map["start"].is_number()) res.start = (size_t)map["start"].number(); else throw "Expected key 'start' to be a number."; @@ -43,6 +40,10 @@ namespace ppc::comp::tree::ast::conv { if (map["code_start"].is_number()) res.code_start = (size_t)map["code_start"].number(); else throw "Expected key 'code_start' to be a number."; } + if (map.has("line")) { + if (map["line"].is_number()) res.line = (size_t)map["line"].number(); + else throw "Expected key 'line' to be a number."; + } return res; } @@ -56,7 +57,7 @@ namespace ppc::comp::tree::ast::conv { arr.push({ { "location", loc_to_map(segment.location) }, { "content", segment }, - { "$_name", nmsp_parser.name() }, + { "$_name", "$_nmsp" }, }); } diff --git a/src/compiler/treeifier/ast/parsers/glob.cc b/src/compiler/treeifier/ast/parsers/glob.cc index 332ecea..45f8eb7 100644 --- a/src/compiler/treeifier/ast/parsers/glob.cc +++ b/src/compiler/treeifier/ast/parsers/glob.cc @@ -9,7 +9,7 @@ class nmsp_def_parser_t : public parser_t { if (h.ended()) return false; if (!h.curr().is_identifier("namespace")) return false; - h.force_parse(nmsp_parser, "Expected a namespace.", res); + h.force_parse("$_nmsp", "Expected a namespace.", res); if (!h.curr().is_operator(operator_t::SEMICOLON)) h.err("Expected a semicolon."); return h.submit(true); @@ -23,7 +23,7 @@ class import_parser_t : public parser_t { if (h.ended()) return false; if (!h.curr().is_identifier("import")) return false; - h.force_parse(nmsp_parser, "Expected a namespace.", res); + h.force_parse("$_nmsp", "Expected a namespace.", res); if (!h.curr().is_operator(operator_t::SEMICOLON)) h.err("Expected a semicolon."); return h.submit(true); @@ -32,22 +32,23 @@ class import_parser_t : public parser_t { public: import_parser_t(): parser_t("$_import") { } }; -const parser_t &import_parser = import_parser_t(); -const parser_t &nmsp_def_parser = nmsp_def_parser_t(); +auto import_parser = import_parser_t(); +auto nmsp_def_parser = nmsp_def_parser_t(); class glob_parser_t : public parser_t { bool parse(ast_ctx_t &ctx, size_t &res_i, data::map_t &out) const { tree_helper_t h(ctx, res_i); if (h.ended()) return true; - h.parse(nmsp_def_parser, (out["namespace"] = map_t()).map()); + nmsp_def_parser(ctx, h.i, (out["namespace"] = map_t()).map()); ctx.nmsp = conv::map_to_nmsp(out["namespace"].map()); - auto imports = (out["imports"] = array_t()).array(); + auto &imports = (out["imports"] = array_t()).array(); + auto &contents = (out["content"] = array_t()).array(); while (true) { map_t map; + if (!import_parser(ctx, h.i, map)) break; imports.push(map); - if (!h.parse(import_parser, map)) break; auto nmsp = conv::map_to_nmsp(map); if (!ctx.imports.emplace(nmsp).second) h.err("The namespace '" + nmsp.to_string() + "' is already imported."); @@ -62,4 +63,5 @@ public: glob_parser_t(): parser_t("$_glob") { } }; -const parser_t &ppc::comp::tree::ast::glob_parser = glob_parser_t(); +parser_factory_t ppc::comp::tree::ast::glob_parser = []() { return (parser_t*)new glob_parser_t(); }; +group_parser_factory_t ppc::comp::tree::ast::def_parser = []() { return new group_parser_t("$_def"); }; diff --git a/src/compiler/treeifier/ast/parsers/group.cc b/src/compiler/treeifier/ast/parsers/group.cc index 2c4d17c..01934f2 100644 --- a/src/compiler/treeifier/ast/parsers/group.cc +++ b/src/compiler/treeifier/ast/parsers/group.cc @@ -29,17 +29,18 @@ static bool read_nmsp(ast_ctx_t &ctx, size_t &i, const lang::namespace_name_t &n return equal_i != name.size(); } + bool group_parser_t::parse(ast_ctx_t &ctx, size_t &i, data::map_t &out) const { 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); + return parser(ctx, i, out); } for (auto parser : parsers) { try { - return h.parse(*parser, out); + return (*parser)(ctx, i, out); } catch (const message_t &err) { ctx.messages.push(err); diff --git a/src/compiler/treeifier/ast/parsers/identifier.cc b/src/compiler/treeifier/ast/parsers/identifier.cc index b9b8557..59af7e0 100644 --- a/src/compiler/treeifier/ast/parsers/identifier.cc +++ b/src/compiler/treeifier/ast/parsers/identifier.cc @@ -18,4 +18,4 @@ class identifier_parser_t : public parser_t { public: identifier_parser_t(): parser_t("$_identifier") { } }; -const parser_t &ppc::comp::tree::ast::identifier_parser = identifier_parser_t(); +parser_factory_t ppc::comp::tree::ast::identifier_parser = []() { return (parser_t*)new identifier_parser_t(); }; diff --git a/src/compiler/treeifier/ast/parsers/nmsp.cc b/src/compiler/treeifier/ast/parsers/nmsp.cc index 910ed7e..0ae7bca 100644 --- a/src/compiler/treeifier/ast/parsers/nmsp.cc +++ b/src/compiler/treeifier/ast/parsers/nmsp.cc @@ -8,12 +8,12 @@ class nmsp_parser_t : public parser_t { auto &arr = (out["content"] = array_t()).array(); - if (!h.push_parse(identifier_parser, arr)) return false; + if (!h.push_parse("$_identifier", arr)) return false; while (true) { if (h.ended()) break; if (!h.curr().is_operator(operator_t::DOUBLE_COLON)) break; - h.force_push_parse(identifier_parser, "Expected an identifier.", arr); + h.force_push_parse("$_identifier", "Expected an identifier.", arr); } out["location"] = conv::loc_to_map(h.res_loc()); @@ -23,4 +23,4 @@ class nmsp_parser_t : public parser_t { public: nmsp_parser_t(): parser_t("$_nmsp") { } }; -const parser_t &ppc::comp::tree::ast::nmsp_parser = nmsp_parser_t(); +parser_factory_t ppc::comp::tree::ast::nmsp_parser = []() { return (parser_t*)new nmsp_parser_t(); }; diff --git a/src/main/main.cc b/src/main/main.cc index 2787e8a..d140119 100644 --- a/src/main/main.cc +++ b/src/main/main.cc @@ -153,26 +153,29 @@ int main(int argc, const char *argv[]) { for (const auto &file : files) { std::ifstream f { file, std::ios_base::in }; + std::stringstream res; try { auto tokens = token_t::parse_many(msg_stack, lex::token_t::parse_file(msg_stack, file, f)); data::map_t ast; if (!ast::ast_ctx_t::parse(msg_stack, tokens, ast)) throw msg_stack.peek(); for (auto tok : tokens) { - if (tok.is_identifier()) std::cout << "Identifier: \t" << tok.identifier(); - if (tok.is_operator()) std::cout << "Operator: \t" << operator_stringify(tok._operator()); - if (tok.is_float_lit()) std::cout << "Float: \t" << tok.float_lit(); - if (tok.is_int_lit()) std::cout << "Int: \t" << tok.int_lit(); - if (tok.is_char_lit()) std::cout << "Char: \t" << tok.char_lit(); - if (tok.is_string_lit()) std::cout << "String: \t" << std::string { tok.string_lit().begin(), tok.string_lit().end() }; - std::cout << std::endl; + if (tok.is_identifier()) res << "Identifier: \t" << tok.identifier(); + if (tok.is_operator()) res << "Operator: \t" << operator_stringify(tok._operator()); + if (tok.is_float_lit()) res << "Float: \t" << tok.float_lit(); + if (tok.is_int_lit()) res << "Int: \t" << tok.int_lit(); + if (tok.is_char_lit()) res << "Char: \t" << tok.char_lit(); + if (tok.is_string_lit()) res << "String: \t" << std::string { tok.string_lit().begin(), tok.string_lit().end() }; + res << '\n'; } - std::cout << std::endl << data::json::stringify(ast); + res << '\n' << data::json::stringify(ast); } catch (const messages::message_t &msg) { msg_stack.push(msg); } + + std::cout << res.str() << std::endl; } msg_stack.print(std::cout, messages::message_t::DEBUG, true); diff --git a/src/utils/location.cc b/src/utils/location.cc index be6e344..8f216e1 100644 --- a/src/utils/location.cc +++ b/src/utils/location.cc @@ -40,11 +40,7 @@ location_t location_t::intersect(location_t other) const { if (a.start == -1u || b.start == -1u) return { }; - if (a.start > b.start) { - location_t c = a; - a = b; - b = c; - } + if (a.start > b.start) return other.intersect(*this); fix_location(a); fix_location(b); @@ -59,61 +55,27 @@ location_t location_t::intersect(location_t other) const { return a; } -location_t::location_t() { - this->line = -1; - this->start = -1; - this->length = -1; - this->code_start = -1; - this->filename = ""; -} -location_t::location_t(std::string filename) { - this->line = -1; - this->start = -1; - this->length = -1; - this->code_start = -1; - this->filename = filename; -} -location_t::location_t(std::size_t line, std::size_t start) { - this->line = line; - this->start = start; - this->length = -1; - this->code_start = -1; - this->filename = ""; -} -location_t::location_t(std::string filename, std::size_t line, std::size_t start) { - this->line = line; - this->start = start; - this->length = -1; - this->code_start = -1; - this->filename = filename; -} -location_t::location_t(std::size_t line, std::size_t start, std::size_t code_start) { - this->line = line; - this->start = start; - this->length = -1; +std::string empty = ""; + +location_t::location_t(): + location_t(empty, -1, -1, -1, -1) { } +location_t::location_t(const std::string &filename): + location_t(filename, -1, -1, -1, -1) { } +location_t::location_t(std::size_t line, std::size_t start): + location_t(empty, line, start, -1, -1) { } +location_t::location_t(const std::string &filename, std::size_t line, std::size_t start): + location_t(filename, line, start, -1, -1) { } +location_t::location_t(std::size_t line, std::size_t start, std::size_t code_start): + location_t(empty, line, start, code_start, -1) { } +location_t::location_t(const std::string &filename, std::size_t line, std::size_t start, std::size_t code_start): + location_t(filename, line, start, code_start, -1) { } +location_t::location_t(std::size_t line, std::size_t start, std::size_t code_start, std::size_t length): + location_t(empty, line, start, code_start, length) { } +location_t::location_t(const std::string &filename, std::size_t line, std::size_t start, std::size_t code_start, std::size_t length): filename(filename) { + this->length = length; this->code_start = code_start; - this->filename = ""; -} -location_t::location_t(std::string filename, std::size_t line, std::size_t start, std::size_t code_start) { this->line = line; this->start = start; - this->length = -1; - this->code_start = code_start; - this->filename = filename; -} -location_t::location_t(std::size_t line, std::size_t start, std::size_t code_start, std::size_t length) { - this->line = line; - this->start = start; - this->length = line; - this->code_start = code_start; - this->filename = ""; -} -location_t::location_t(std::string filename, std::size_t line, std::size_t start, std::size_t code_start, std::size_t length) { - this->line = line; - this->start = start; - this->length = line; - this->code_start = code_start; - this->filename = filename; } const location_t location_t::NONE = { };