From c7038d65b98ff517726d8cdd7e3393275a20634f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 10 Apr 2015 23:22:12 +0200 Subject: output: also collapse goto case branches --- src/output.cpp | 30 ++++++++++++++++++++++++++++++ src/output.hpp | 1 + src/output_lr0.cpp | 30 +----------------------------- src/output_slr.cpp | 30 +----------------------------- 4 files changed, 33 insertions(+), 58 deletions(-) diff --git a/src/output.cpp b/src/output.cpp index cd08a9e..cfefbbb 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -213,6 +213,36 @@ void output_t::emit_reductions() { } } +void output_t::emit_gotos(const std::string &lhs) { + std::map> gotos; + + for (size_t state = 0; state < get_generator()->get_state_count(); state++) { + auto it = get_generator()->get_gotos().find(std::make_pair(state, lhs)); + if (it == get_generator()->get_gotos().end()) + continue; + + std::set &states = gotos.insert(std::make_pair(it->second, std::set())).first->second; + states.insert(state); + } + + if (gotos.size() == 1) { + auto it = gotos.begin(); + std::fprintf(source_file, "\t\t\t\tparser->stack[++parser->top].state = %u;\n", it->first); + } + else { + std::fprintf(source_file, "\t\t\t\tswitch (parser->stack[parser->top].state) {\n"); + + for (const auto &entry : gotos) { + for (unsigned state : entry.second) + std::fprintf(source_file, "\t\t\t\tcase %u:\n", state); + std::fprintf(source_file, "\t\t\t\t\tparser->stack[++parser->top].state = %u;\n", entry.first); + std::fprintf(source_file, "\t\t\t\t\tbreak;\n\n"); + } + + std::fprintf(source_file, "\t\t\t\t}\n"); + } +} + void output_t::emit_states() { for (size_t state = 0; state < get_generator()->get_state_count(); state++) emit_state(state); diff --git a/src/output.hpp b/src/output.hpp index 6704ed4..66baf41 100644 --- a/src/output.hpp +++ b/src/output.hpp @@ -65,6 +65,7 @@ protected: void emit_reduction(unsigned rule_id); void emit_reductions(); + void emit_gotos(const std::string &lhs); void emit_states(); void emit_header_include(); void emit_source(); diff --git a/src/output_lr0.cpp b/src/output_lr0.cpp index 031ed43..9d4897e 100644 --- a/src/output_lr0.cpp +++ b/src/output_lr0.cpp @@ -93,35 +93,7 @@ void output_lr0_t::emit_state_reduce(const item_t &item, int rule_id) { std::fprintf(source_file, ");\n"); } - std::vector> gotos; - - for (size_t i = 0; i < generator->get_state_count(); i++) { - auto it = generator->get_gotos().find(std::make_pair(i, item.get_lhs())); - if (it == generator->get_gotos().end()) - continue; - - gotos.emplace_back(i, it->second); - } - - if (gotos.size() == 1) { - std::fprintf(source_file, "\t\t\tparser->stack[++parser->top].state = %u;\n", gotos[0].second); - } - else { - std::fprintf(source_file, "\t\t\tswitch (parser->stack[parser->top].state) {\n"); - - for (size_t i = 0; i < generator->get_state_count(); i++) { - auto it = generator->get_gotos().find(std::make_pair(i, item.get_lhs())); - if (it == generator->get_gotos().end()) - continue; - - std::fprintf(source_file, "\t\t\tcase %u:\n", unsigned(i)); - std::fprintf(source_file, "\t\t\t\tparser->stack[++parser->top].state = %u;\n", unsigned(it->second)); - std::fprintf(source_file, "\t\t\t\tbreak;\n"); - } - - - std::fprintf(source_file, "\t\t\t}\n"); - } + emit_gotos(item.get_lhs()); } void output_lr0_t::emit_state(unsigned state) { diff --git a/src/output_slr.cpp b/src/output_slr.cpp index 563fd60..4a7b463 100644 --- a/src/output_slr.cpp +++ b/src/output_slr.cpp @@ -94,35 +94,7 @@ void output_slr_t::emit_state_reduce_code(const item_t &item, int rule_id) { std::fprintf(source_file, ");\n"); } - std::vector> gotos; - - for (size_t i = 0; i < generator->get_state_count(); i++) { - auto it = generator->get_gotos().find(std::make_pair(i, item.get_lhs())); - if (it == generator->get_gotos().end()) - continue; - - gotos.emplace_back(i, it->second); - } - - if (gotos.size() == 1) { - std::fprintf(source_file, "\t\t\t\tparser->stack[++parser->top].state = %u;\n", gotos[0].second); - } - else { - std::fprintf(source_file, "\t\t\t\tswitch (parser->stack[parser->top].state) {\n"); - - for (size_t i = 0; i < generator->get_state_count(); i++) { - auto it = generator->get_gotos().find(std::make_pair(i, item.get_lhs())); - if (it == generator->get_gotos().end()) - continue; - - std::fprintf(source_file, "\t\t\t\tcase %u:\n", unsigned(i)); - std::fprintf(source_file, "\t\t\t\t\tparser->stack[++parser->top].state = %u;\n", unsigned(it->second)); - std::fprintf(source_file, "\t\t\t\t\tbreak;\n\n"); - } - - - std::fprintf(source_file, "\t\t\t\t}\n"); - } + emit_gotos(item.get_lhs()); } bool output_slr_t::emit_state_reduce(unsigned state) { -- cgit v1.2.3