diff options
Diffstat (limited to 'src/output.cpp')
-rw-r--r-- | src/output.cpp | 40 |
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"); |