summaryrefslogtreecommitdiffstats
path: root/src/output_lr0.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/output_lr0.cpp')
-rw-r--r--src/output_lr0.cpp13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/output_lr0.cpp b/src/output_lr0.cpp
index 62c5966..5d0c882 100644
--- a/src/output_lr0.cpp
+++ b/src/output_lr0.cpp
@@ -63,7 +63,7 @@ void output_lr0_t::emit_state_reduce(const item_t &item, int rule_id) {
std::fprintf(source_file, "\t\t\t");
if (!type.empty())
- std::fprintf(source_file, "parser->stack[parser->top].value.symbol_%s = ", item.get_lhs().c_str());
+ std::fprintf(source_file, "result.symbol_%s = ", item.get_lhs().c_str());
std::fprintf(source_file, "%sreduce_%i(", prefix(), rule_id);
bool empty = true;
@@ -90,6 +90,17 @@ void output_lr0_t::emit_state_reduce(const item_t &item, int rule_id) {
}
std::fprintf(source_file, ");\n");
+
+ for (unsigned i = 0; i < rhs.size(); i++) {
+ auto it = generator->get_grammar().destructors.find(rhs[i]);
+ if (it == generator->get_grammar().destructors.end())
+ continue;
+
+ std::fprintf(source_file, "\t\t\t%s(parser->stack[parser->top + %u].value.%s);\n", it->second.c_str(), i, symbol_values[rhs[i]].c_str());
+ }
+
+ if (!type.empty())
+ std::fprintf(source_file, "\t\t\tparser->stack[parser->top].value.symbol_%s = result.symbol_%s;\n", item.get_lhs().c_str(), item.get_lhs().c_str());
}
emit_gotos(item.get_lhs());