summaryrefslogtreecommitdiffstats
path: root/src/output.cpp
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 /src/output.cpp
parentc2728e4c835c6ae7db4d23ef60e5df3b9be3061a (diff)
downloadsolar-c7038d65b98ff517726d8cdd7e3393275a20634f.tar
solar-c7038d65b98ff517726d8cdd7e3393275a20634f.zip
output: also collapse goto case branches
Diffstat (limited to 'src/output.cpp')
-rw-r--r--src/output.cpp30
1 files changed, 30 insertions, 0 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);