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 /src/output.cpp | |
parent | c2728e4c835c6ae7db4d23ef60e5df3b9be3061a (diff) | |
download | solar-c7038d65b98ff517726d8cdd7e3393275a20634f.tar solar-c7038d65b98ff517726d8cdd7e3393275a20634f.zip |
output: also collapse goto case branches
Diffstat (limited to 'src/output.cpp')
-rw-r--r-- | src/output.cpp | 30 |
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); |