summaryrefslogtreecommitdiffstats
path: root/src/output.cpp
diff options
context:
space:
mode:
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);