output: also collapse goto case branches

This commit is contained in:
Matthias Schiffer 2015-04-10 23:22:12 +02:00
parent c2728e4c83
commit c7038d65b9
4 changed files with 33 additions and 58 deletions

View file

@ -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);

View file

@ -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();

View file

@ -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) {

View file

@ -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) {