Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

extval on parser generator #1788

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading