Skip to content

Commit

Permalink
extval on parser generator
Browse files Browse the repository at this point in the history
  • Loading branch information
Nivaturimika authored Oct 25, 2024
1 parent 1e8038b commit 42cebaf
Showing 1 changed file with 47 additions and 18 deletions.
65 changes: 47 additions & 18 deletions ParserGenerator/parser_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct value_association {
std::string key;
std::string type;
value_and_optional handler;
bool is_extern = false;
};
struct group_association {
std::string key;
Expand Down Expand Up @@ -199,11 +200,13 @@ void tokenize_file(std::stringstream& stream) {
}
}

std::optional<token> get_token(auto& it) {
template<typename T>
std::optional<token> get_token(T& it) {
return std::optional(*it++);
}

token get_specific_token(auto& it, bool& err_cond, token_type const& type) {
template<typename T>
token get_specific_token(T& it, bool& err_cond, token_type const& type) {
auto o = get_token(it);
if(!o.has_value()) {
// TODO: This is risky - but allows for accurate-ish reporting
Expand Down Expand Up @@ -257,6 +260,9 @@ void parse() {
groups.back().set_handler = group_association{ key.data, opt.data, value_and_optional{handler_type.data, handler_opt.data}, false };
} else if(type.data == "extern") {
groups.back().set_handler = group_association{ key.data, opt.data, value_and_optional{handler_type.data, handler_opt.data}, true };
} else if(type.data == "extval") {
groups.back().single_value_handler_type = opt.data;
groups.back().single_value_handler_result = value_and_optional{ handler_type.data, handler_opt.data };
} else if(type.data == "value") {
groups.back().single_value_handler_type = opt.data;
groups.back().single_value_handler_result = value_and_optional{ handler_type.data, handler_opt.data };
Expand Down Expand Up @@ -307,7 +313,9 @@ void parse() {
if(type.data == "parser" || type.data == "group") {
groups.back().any_group_handler = group_association{ "", opt.data, value_and_optional{handler_type.data, handler_opt.data}, false };
} else if(type.data == "value") {
groups.back().any_value_handler = value_association{ "", opt.data, value_and_optional{handler_type.data, handler_opt.data} };
groups.back().any_value_handler = value_association{ "", opt.data, value_and_optional{handler_type.data, handler_opt.data}, false };
} else if(type.data == "extval") {
groups.back().any_value_handler = value_association{ "", opt.data, value_and_optional{handler_type.data, handler_opt.data}, true };
} else if(type.data == "extern") {
groups.back().any_group_handler = group_association{ "", opt.data, value_and_optional{handler_type.data, handler_opt.data}, true };

Expand Down Expand Up @@ -344,12 +352,14 @@ void parse() {
}
if(type.data == "parser" || type.data == "group") {
groups.back().groups.push_back(group_association{ key.data, opt.data, value_and_optional{handler_type.data, handler_opt.data}, false });
} else if(type.data == "value") {
groups.back().values.push_back(value_association{ key.data, opt.data, value_and_optional{handler_type.data, handler_opt.data} });
} else if(type.data == "extern") {
groups.back().groups.push_back(group_association{ key.data, opt.data, value_and_optional{handler_type.data, handler_opt.data}, true });
} else if(type.data == "value") {
groups.back().values.push_back(value_association{ key.data, opt.data, value_and_optional{handler_type.data, handler_opt.data}, false });
} else if(type.data == "extval") {
groups.back().values.push_back(value_association{ key.data, opt.data, value_and_optional{handler_type.data, handler_opt.data}, true });
} else {
report_error(104, type.loc_info, "Invalid #free type '" + type.data + "'\n");
report_error(104, type.loc_info, "Invalid key type '" + type.data + "'\n");
}
}
} else if(key.type == token_type::newline) {
Expand Down Expand Up @@ -550,7 +560,8 @@ std::string construct_match_tree_internal(V const& vector, F const& generator_ma
return output;
}

std::string construct_match_tree_outer(auto const& vector, auto const& generator_match, std::string_view const no_match) {
template<typename T, typename U>
std::string construct_match_tree_outer(T const& vector, U const& generator_match, std::string_view const no_match) {
auto const maxlen = max_length(vector);
std::string output = tabulate("switch(int32_t(cur.content.length())) {\n");
for(int32_t l = 1; l <= maxlen; ++l) {
Expand Down Expand Up @@ -830,18 +841,36 @@ void file_write_out(std::fstream& stream, std::vector<group_contents>& groups) {
*/
auto match_handler = [](value_association const& v) {
std::string out;
if(v.handler.value == "discard") {
} else if(v.handler.value == "member") {
out = "cobj." + (v.handler.opt.length() > 0 ? v.handler.opt : v.key) +
" = parse_" + v.type + "(rh_token.content, rh_token.line, err);";
} else if(v.handler.value == "member_fn") {
out = "cobj." + (v.handler.opt.length() > 0 ? v.handler.opt : v.key) +
"(assoc_type, parse_" + v.type + "(rh_token.content, rh_token.line, err), err, cur.line, context);";
} else if(v.handler.value == "function") {
out = (v.handler.opt.length() > 0 ? v.handler.opt : v.key) +
"(cobj, assoc_type, parse_" + v.type + "(rh_token.content, rh_token.line, err), err, cur.line, context);";
if(v.is_extern) {
if(v.handler.value == "discard") {
out = "/* discarded */";
} else if(v.handler.value == "member") {
out = "cobj." + (v.handler.opt.length() > 0 ? v.handler.opt : v.key) +
" = " + v.type + "(rh_token.content, rh_token.line, err, context);";
} else if(v.handler.value == "member_fn") {
out = "cobj." + (v.handler.opt.length() > 0 ? v.handler.opt : v.key) +
"(assoc_type, " + v.type + "(rh_token.content, rh_token.line, err, context), err, cur.line, context);";
} else if(v.handler.value == "function") {
out = (v.handler.opt.length() > 0 ? v.handler.opt : v.key) +
"(cobj, assoc_type, " + v.type + "(rh_token.content, rh_token.line, err, context), err, cur.line, context);";
} else {
out = "err.unhandled_association_key(cur);";
}
} else {
out = "err.unhandled_association_key(cur);";
if(v.handler.value == "discard") {
out = "/* discarded */";
} else if(v.handler.value == "member") {
out = "cobj." + (v.handler.opt.length() > 0 ? v.handler.opt : v.key) +
" = parse_" + v.type + "(rh_token.content, rh_token.line, err);";
} else if(v.handler.value == "member_fn") {
out = "cobj." + (v.handler.opt.length() > 0 ? v.handler.opt : v.key) +
"(assoc_type, parse_" + v.type + "(rh_token.content, rh_token.line, err), err, cur.line, context);";
} else if(v.handler.value == "function") {
out = (v.handler.opt.length() > 0 ? v.handler.opt : v.key) +
"(cobj, assoc_type, parse_" + v.type + "(rh_token.content, rh_token.line, err), err, cur.line, context);";
} else {
out = "err.unhandled_association_key(cur);";
}
}
return out;
};
Expand Down

0 comments on commit 42cebaf

Please sign in to comment.