summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-04-10 23:22:12 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-04-10 23:22:12 +0200
commitc7038d65b98ff517726d8cdd7e3393275a20634f (patch)
tree14ec24890f38d064c0fc47826a700319911b203f
parentc2728e4c835c6ae7db4d23ef60e5df3b9be3061a (diff)
downloadsolar-c7038d65b98ff517726d8cdd7e3393275a20634f.tar
solar-c7038d65b98ff517726d8cdd7e3393275a20634f.zip
output: also collapse goto case branches
-rw-r--r--src/output.cpp30
-rw-r--r--src/output.hpp1
-rw-r--r--src/output_lr0.cpp30
-rw-r--r--src/output_slr.cpp30
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) {