summaryrefslogtreecommitdiffstats
path: root/src/output.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/output.cpp')
-rw-r--r--src/output.cpp40
1 files changed, 32 insertions, 8 deletions
diff --git a/src/output.cpp b/src/output.cpp
index 0901b29..1b4d6d8 100644
--- a/src/output.cpp
+++ b/src/output.cpp
@@ -64,8 +64,8 @@ void output_t::emit_tokens() {
}
void output_t::emit_token_value() {
- std::fprintf(source_file, "typedef struct %stoken_value {\n", prefix());
- std::fprintf(source_file, "} %stoken_value_t;\n\n", prefix());
+ std::fprintf(header_file, "typedef struct %stoken_value {\n", prefix());
+ std::fprintf(header_file, "} %stoken_value_t;\n\n", prefix());
}
void output_t::emit_header() {
@@ -75,6 +75,22 @@ void output_t::emit_header() {
std::fprintf(header_file, "typedef struct %scontext %scontext_t;\n", prefix(), prefix());
}
+void output_t::emit_reduction(unsigned rule_id, const std::string &action) {
+ std::fprintf(source_file, "void %sreduce_%u(void) {", prefix(), rule_id);
+ std::fprintf(source_file, "%s", action.c_str());
+ std::fprintf(source_file, "}\n\n");
+
+}
+
+void output_t::emit_reductions() {
+ const auto &rules = generator->get_rules();
+
+ for (size_t i = 0; i < rules.size(); i++) {
+ if (!rules[i].second.empty())
+ emit_reduction(i, rules[i].second);
+ }
+}
+
void output_t::emit_state_shift(unsigned i) {
std::fprintf(source_file, "\t\t\tswitch (token) {\n");
@@ -103,10 +119,13 @@ void output_t::emit_state_shift(unsigned i) {
std::fprintf(source_file, "\t\t\t}\n");
}
-void output_t::emit_state_reduce(const item_t &item) {
+void output_t::emit_state_reduce(const item_t &item, int rule_id) {
if (item.get_rhs().size())
std::fprintf(source_file, "\t\t\tparser->top -= %u;\n", unsigned(item.get_rhs().size()));
+ if (rule_id >= 0)
+ std::fprintf(source_file, "\t\t\t%sreduce_%i();\n", prefix(), rule_id);
+
std::vector<std::pair<unsigned, unsigned>> gotos;
for (size_t i = 0; i < generator->get_state_count(); i++) {
@@ -142,10 +161,13 @@ void output_t::emit_state(unsigned i) {
std::fprintf(source_file, "\t\tcase %u:\n", i);
auto it = generator->get_reductions().find(i);
- if (it == generator->get_reductions().end())
+ if (it == generator->get_reductions().end()) {
emit_state_shift(i);
- else
- emit_state_reduce(generator->get_rules()[it->second]);
+ }
+ else {
+ const auto &rule = generator->get_rules()[it->second];
+ emit_state_reduce(rule.first, rule.second.empty() ? -1 : it->second);
+ }
std::fprintf(source_file, "\t\t\tbreak;\n\n");
}
@@ -160,10 +182,12 @@ void output_t::emit_source() {
std::fprintf(source_file, "\tunsigned state;\n");
std::fprintf(source_file, "} %scontext_state_t;\n\n", prefix());
- std::fprintf(source_file, "typedef struct %scontext {\n", prefix());
+ std::fprintf(source_file, "struct %scontext {\n", prefix());
std::fprintf(source_file, "\tunsigned top;\n");
std::fprintf(source_file, "\t%scontext_state_t stack[%u];\n", prefix(), stack_size);
- std::fprintf(source_file, "} %scontext_t;\n\n", prefix());
+ std::fprintf(source_file, "};\n\n");
+
+ emit_reductions();
std::fprintf(source_file, "int %spush(%scontext_t *parser, int token, const %stoken_value_t *value) {\n", prefix(), prefix(), prefix());
std::fprintf(source_file, "\twhile (1) {\n");