diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-04-10 23:22:12 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-04-10 23:22:12 +0200 |
commit | c7038d65b98ff517726d8cdd7e3393275a20634f (patch) | |
tree | 14ec24890f38d064c0fc47826a700319911b203f | |
parent | c2728e4c835c6ae7db4d23ef60e5df3b9be3061a (diff) | |
download | solar-c7038d65b98ff517726d8cdd7e3393275a20634f.tar solar-c7038d65b98ff517726d8cdd7e3393275a20634f.zip |
output: also collapse goto case branches
-rw-r--r-- | src/output.cpp | 30 | ||||
-rw-r--r-- | src/output.hpp | 1 | ||||
-rw-r--r-- | src/output_lr0.cpp | 30 | ||||
-rw-r--r-- | 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<unsigned, std::set<unsigned>> 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<unsigned> &states = gotos.insert(std::make_pair(it->second, std::set<unsigned>())).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<std::pair<unsigned, unsigned>> 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<std::pair<unsigned, unsigned>> 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) { |