feat: added struct parsing

This commit is contained in:
TopchetoEU 2023-01-18 10:01:09 +02:00
parent 1cbd176929
commit 3c49434b12
9 changed files with 63 additions and 38 deletions

View File

@ -26,10 +26,9 @@ namespace ppc::comp::tree::ast {
std::set<std::string> unnamed_parsers; std::set<std::string> unnamed_parsers;
std::map<std::string, parser_t> parsers; std::map<std::string, parser_t> parsers;
public: public:
group_t &insert(const std::string &name, parser_t parser, const std::string &relative_to, bool after);
group_t &add_last(const std::string &name, parser_t parser);
group_t &replace(const std::string &name, parser_t parser); group_t &replace(const std::string &name, parser_t parser);
group_t &add_named(const std::string &name, parser_t parser, const lang::namespace_name_t &identifier); group_t &add(const std::string &name, parser_t parser);
group_t &add(const std::string &name, const lang::namespace_name_t &identifier, parser_t parser);
bool operator()(ast_ctx_t &ctx, size_t &i, data::map_t &out) const; bool operator()(ast_ctx_t &ctx, size_t &i, data::map_t &out) const;
}; };
@ -77,7 +76,7 @@ namespace ppc::comp::tree::ast {
} }
parser_func_t parse_glob, parse_nmsp, parse_identifier, parse_type, 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_func, parse_field, parse_export, parse_struct;
parser_func_t parse_if, parse_while, parse_return, parse_break, parse_continue, parse_stat_comp; parser_func_t parse_if, parse_while, parse_return, parse_break, parse_continue, parse_stat_comp;
parser_func_t parse_exp_var, parse_exp_str_lit, parse_exp_int_lit, parse_exp_float_lit; parser_func_t parse_exp_var, parse_exp_str_lit, parse_exp_int_lit, parse_exp_float_lit;
} }

View File

@ -99,6 +99,10 @@ namespace ppc::data {
return values.find(key) != values.end(); return values.find(key) != values.end();
} }
void clear() {
values.clear();
}
std::size_t size() const { return values.size(); } std::size_t size() const { return values.size(); }
auto begin() const { return values.begin(); } auto begin() const { return values.begin(); }

View File

@ -12,20 +12,23 @@ group_t &ast_ctx_t::group(const std::string &name) {
ast_ctx_t::ast_ctx_t(msg_stack_t &messages, std::vector<token_t> &tokens): messages(messages), tokens(tokens) { ast_ctx_t::ast_ctx_t(msg_stack_t &messages, std::vector<token_t> &tokens): messages(messages), tokens(tokens) {
group("$_exp_val") group("$_exp_val")
.add_last("$_var", parse_exp_var) .add("$_var", parse_exp_var)
.add_last("$_int", parse_exp_int_lit) .add("$_int", parse_exp_int_lit)
.add_last("$_string", parse_exp_str_lit); .add("$_string", parse_exp_str_lit);
// .add_last("$_float", parse_exp_float_lit) // .add_last("$_float", parse_exp_float_lit)
group("$_stat") group("$_stat")
.add_named("$_while", parse_while, { "while" }) .add("$_while", { "while" }, parse_while)
.add_named("$_if", parse_if, { "if" }) .add("$_if", { "if" }, parse_if)
.add_named("$_return", parse_return, { "return" }) .add("$_return", { "return" }, parse_return)
.add_named("$_break", parse_break, { "break" }) .add("$_break", { "break" }, parse_break)
.add_named("$_continue", parse_continue, { "continue" }) .add("$_continue", { "continue" }, parse_continue)
.add_last("$_comp", parse_stat_comp) .add("$_comp", parse_stat_comp)
.add_last("$_exp", parse_stat_exp); .add("$_exp", parse_stat_exp);
group("$_def") group("$_def")
.add_last("$_func", parse_func) .add("$_func", parse_func)
.add_named("$_export", parse_export, { "export" }) .add("$_struct", { "struct" }, parse_struct)
.add_last("$_field", parse_field); .add("$_field", parse_field);
group("$_struct_def")
.add("$_func", parse_func)
.add("$_field", parse_field);
} }

View File

@ -3,10 +3,14 @@
bool ast::parse_export(ast_ctx_t &ctx, size_t &res_i, map_t &out) { bool ast::parse_export(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
tree_helper_t h(ctx, res_i); tree_helper_t h(ctx, res_i);
if (h.ended()) return false;
if (!h.curr().is_identifier("export")) return false;
h.advance("Unexpected end after export.");
if (out["exported"].is_true()) { if (out["exported"].is_true()) {
ctx.messages.push(message_t(message_t::WARNING, "Export is alredy specified for this definition.", h.prev_loc())); ctx.messages.push(message_t(message_t::WARNING, "Export is alredy specified for this definition.", h.prev_loc()));
} }
out["exported"] = true; out["exported"] = true;
return ctx.group("$_def")(ctx, res_i, out); return h.submit(false);
} }

View File

@ -5,6 +5,8 @@ bool ast::parse_field(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
if (h.ended()) return false; if (h.ended()) return false;
h.parse(parse_export, out);
if (!h.parse(parse_identifier, out["name"].map({}))) return false; if (!h.parse(parse_identifier, out["name"].map({}))) return false;
bool type = false, defval = false; bool type = false, defval = false;

View File

@ -5,6 +5,8 @@ static bool parse_arg(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
if (h.ended()) return false; if (h.ended()) return false;
h.parse(parse_export, out);
if (!h.parse(parse_identifier, out["name"].map({}))) return false; if (!h.parse(parse_identifier, out["name"].map({}))) return false;
bool type = false, defval = false; bool type = false, defval = false;
@ -34,6 +36,8 @@ bool ast::parse_func(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
if (h.ended()) return false; if (h.ended()) return false;
h.parse(parse_export, out);
if (!h.parse(parse_identifier, out["name"].map({}))) return false; if (!h.parse(parse_identifier, out["name"].map({}))) return false;
if (h.ended()) return false; if (h.ended()) return false;
if (!h.curr().is_operator(operator_t::PAREN_OPEN)) return false; if (!h.curr().is_operator(operator_t::PAREN_OPEN)) return false;

View File

@ -21,22 +21,6 @@ static bool read_nmsp(ast_ctx_t &ctx, size_t &i, lang::loc_namespace_name_t &nam
} }
group_t &group_t::insert(const std::string &name, parser_t parser, const std::string &relative_to, bool after) {
if (parsers.find(name) != parsers.end()) {
throw "The parser '" + name + "' is already 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++;
unnamed_parsers.insert(it, name);
return *this;
}
group_t &group_t::replace(const std::string &name, parser_t parser) { group_t &group_t::replace(const std::string &name, parser_t parser) {
auto it = parsers.find(name); auto it = parsers.find(name);
@ -48,7 +32,7 @@ group_t &group_t::replace(const std::string &name, parser_t parser) {
return *this; return *this;
} }
group_t &group_t::add_last(const std::string &name, parser_t parser) { group_t &group_t::add(const std::string &name, parser_t parser) {
if (parsers.find(name) != parsers.end()) { if (parsers.find(name) != parsers.end()) {
throw "The parser '" + name + "' is already in the group."; throw "The parser '" + name + "' is already in the group.";
} }
@ -58,7 +42,7 @@ group_t &group_t::add_last(const std::string &name, parser_t parser) {
return *this; return *this;
} }
group_t &group_t::add_named(const std::string &name, parser_t parser, const lang::namespace_name_t &identifier) { group_t &group_t::add(const std::string &name, const lang::namespace_name_t &identifier, parser_t parser) {
if (parsers.find(name) != parsers.end()) { if (parsers.find(name) != parsers.end()) {
throw "The parser '" + name + "' is already in the group."; throw "The parser '" + name + "' is already in the group.";
} }
@ -87,6 +71,7 @@ bool group_t::operator()(ast_ctx_t &ctx, size_t &i, data::map_t &out) const {
name.strip_location(), actual name.strip_location(), actual
)) { )) {
auto parser = parsers.find(this->named_parsers.find(actual)->second); auto parser = parsers.find(this->named_parsers.find(actual)->second);
out.clear();
out["$_name"] = parser->first; out["$_name"] = parser->first;
if (h.parse(parser->second, out)) return h.submit(false); if (h.parse(parser->second, out)) return h.submit(false);
else throw message_t::error("Unexpected construct specifier.", h.res_loc()); else throw message_t::error("Unexpected construct specifier.", h.res_loc());
@ -95,6 +80,7 @@ bool group_t::operator()(ast_ctx_t &ctx, size_t &i, data::map_t &out) const {
for (auto name : unnamed_parsers) { for (auto name : unnamed_parsers) {
out["$_name"] = name; out["$_name"] = name;
out.clear();
if (parsers.at(name)(ctx, i, out)) return true; if (parsers.at(name)(ctx, i, out)) return true;
} }

View File

@ -0,0 +1,24 @@
#include "compiler/treeifier/ast/helper.hh"
bool ast::parse_struct(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
tree_helper_t h(ctx, res_i);
if (h.ended()) return false;
if (!h.parse(parse_identifier, out["name"].map({}))) return false;
auto &content = out["content"].array({});
if (h.ended()) return false;
if (h.curr().is_operator(operator_t::SEMICOLON)) return h.submit(true);
if (!h.curr().is_operator(operator_t::BRACE_OPEN)) return false;
h.advance("Expected a definition, a closing brace, or a semicolon.");
while (!h.curr().is_operator(operator_t::BRACE_CLOSE)) {
h.throw_ended("Expected a definition or a closing brace.");
h.push_parse(ctx.group("$_struct_def"), content);
}
return h.submit(true);
}

View File

@ -1,7 +1,6 @@
#include <vector> #include <vector>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <filesystem>
struct project_t { struct project_t {
std::string output; std::string output;