summaryrefslogtreecommitdiffstats
path: root/src/output_slr.cpp
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-04-16 22:07:29 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-04-17 17:20:25 +0200
commit6c8cd11dad10587e5dde9ab7706384927b961bb6 (patch)
tree83df2371191ee2dea8ba2154ef538b91d38089ed /src/output_slr.cpp
parentbb018683c93673679bb54b63c8aff43f507948de (diff)
downloadsolar-6c8cd11dad10587e5dde9ab7706384927b961bb6.tar
solar-6c8cd11dad10587e5dde9ab7706384927b961bb6.zip
Completely refactor code generation
Diffstat (limited to 'src/output_slr.cpp')
-rw-r--r--src/output_slr.cpp134
1 files changed, 8 insertions, 126 deletions
diff --git a/src/output_slr.cpp b/src/output_slr.cpp
index 3c9e1c2..9be1adb 100644
--- a/src/output_slr.cpp
+++ b/src/output_slr.cpp
@@ -24,139 +24,21 @@
*/
+#include "output_header.hpp"
#include "output_slr.hpp"
+#include "output_source_slr.hpp"
namespace solar {
-void output_slr_t::emit_state_shift(unsigned state) {
- std::map<unsigned, std::set<symbol_t>> shifts;
+void output_slr(const generator_slr_t *generator, const char *source, const char *header) {
+ output_common_t common(generator, "parse_", "TOK_");
- for (const symbol_t &token : generator->get_terminals()) {
- auto it = generator->get_shifts().find(std::make_pair(state, token));
- if (it == generator->get_shifts().end())
- continue;
+ output_source_slr_t output_source(common, source, header);
+ output_source.write();
- std::set<symbol_t> &symbols = shifts.insert(std::make_pair(it->second, std::set<symbol_t>())).first->second;
- symbols.insert(token);
- }
-
- for (const auto &entry : shifts) {
- for (const symbol_t &sym : entry.second)
- std::fprintf(source_file, "\t\t\tcase %s:\n", symbol_case(sym).c_str());
-
- std::fprintf(source_file, "\t\t\t\tparser->stack[++parser->top].state = %u;\n", entry.first);
- std::fprintf(source_file, "\t\t\t\treturn 1;\n\n");
- }
-}
-
-void output_slr_t::emit_state_reduce_code(const item_t &item, int rule_id) {
- const auto &rhs = item.get_rhs();
- if (rhs.size())
- std::fprintf(source_file, "\t\t\t\tparser->top -= %u;\n", unsigned(rhs.size()));
-
- if (rule_id >= 0) {
- const std::string &type = generator->get_grammar().get_nonterm_type(item.get_lhs());
-
- std::fprintf(source_file, "\t\t\t\t");
- if (!type.empty())
- std::fprintf(source_file, "result.symbol_%s = ", item.get_lhs().c_str());
- std::fprintf(source_file, "%sreduce_%i(", prefix(), rule_id);
-
- bool empty = true;
- const auto &vars = generator->get_grammar().rules[rule_id].variables;
- for (unsigned i = 0; i < vars.size(); i++) {
- if (vars[i].first.empty())
- continue;
-
- if (!empty)
- std::fprintf(source_file, ", ");
-
- std::fprintf(source_file, "parser->stack[parser->top + %u].value.%s", i, symbol_values[rhs[i]].c_str());
- empty = false;
- }
-
- for (const auto &arg : generator->get_grammar().extra_args) {
- if (!empty)
- std::fprintf(source_file, ", ");
-
- std::fprintf(source_file, "%s", arg.second.c_str());
-
- empty = false;
- }
-
- std::fprintf(source_file, ");\n");
-
- for (unsigned i = 0; i < vars.size(); i++) {
- if (!vars[i].second)
- continue;
-
- auto it = generator->get_grammar().destructors.find(rhs[i]);
- if (it == generator->get_grammar().destructors.end())
- continue;
-
- std::fprintf(source_file, "\t\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\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());
-}
-
-bool output_slr_t::emit_state_reduce(unsigned state) {
- std::map<unsigned, std::set<symbol_t>> reductions;
-
- for (const symbol_t &token : generator->get_terminals()) {
- auto it = generator->get_reductions().find(std::make_pair(state, token));
- if (it == generator->get_reductions().end())
- continue;
-
- std::set<symbol_t> &symbols = reductions.insert(std::make_pair(it->second, std::set<symbol_t>())).first->second;
- symbols.insert(token);
- }
-
- for (const auto &entry : reductions) {
- if (reductions.size() == 1) {
- std::fprintf(source_file, "\t\t\tdefault:\n");
- }
- else {
- for (const symbol_t &sym : entry.second)
- std::fprintf(source_file, "\t\t\tcase %s:\n", symbol_case(sym).c_str());
- }
-
- const rule_t &rule = generator->get_grammar().rules[entry.first];
- emit_state_reduce_code(rule.item, rule.action.empty() ? -1 : entry.first);
-
- if (reductions.size() != 1)
- std::fprintf(source_file, "\t\t\t\tbreak;\n\n");
-
- }
-
- return (reductions.size() == 1);
-}
-
-void output_slr_t::emit_state(unsigned state) {
- std::fprintf(source_file, "\t\tcase %u:\n", state);
- std::fprintf(source_file, "\t\t\tswitch (token) {\n");
-
- if (generator->get_shifts().find(std::make_pair(state, symbol_t::make_nonterm(""))) != generator->get_shifts().end()) {
- std::fprintf(source_file, "\t\t\tcase 0:\n");
- std::fprintf(source_file, "\t\t\t\treturn 0;\n\n");
- }
-
- emit_state_shift(state);
-
- bool def = emit_state_reduce(state);
-
- if (!def) {
- std::fprintf(source_file, "\t\t\tdefault:\n");
- std::fprintf(source_file, "\t\t\t\treturn -1;\n");
- }
-
- std::fprintf(source_file, "\t\t\t}\n");
- std::fprintf(source_file, "\t\t\tbreak;\n\n");
+ output_header_t output_header(common, header);
+ output_header.write();
}
}