summaryrefslogtreecommitdiffstats
path: root/src/generator.cpp
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-03-31 18:38:59 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-03-31 18:38:59 +0200
commit129b81e09375dbee4a12c468ef75f18243e8a0a4 (patch)
tree958cce08966c71e275d11bb20fc95656df65495a /src/generator.cpp
parent8b94b9cf2c91e00665771bb46e1d9a6400114e63 (diff)
downloadsolar-129b81e09375dbee4a12c468ef75f18243e8a0a4.tar
solar-129b81e09375dbee4a12c468ef75f18243e8a0a4.zip
generator: add methods to generate closed item sets
Diffstat (limited to 'src/generator.cpp')
-rw-r--r--src/generator.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/generator.cpp b/src/generator.cpp
index 62c2584..f8f4f1d 100644
--- a/src/generator.cpp
+++ b/src/generator.cpp
@@ -26,9 +26,70 @@
#include "generator.hpp"
+#include <queue>
+
namespace solar {
+std::set<item_t> generator_t::get_set(const std::string &nonterm) {
+ std::set<item_t> set;
+
+ auto entries = rules.equal_range(nonterm);
+ for (auto entry = entries.first; entry != entries.second; ++entry)
+ set.insert(entry->second);
+
+ return set;
+}
+
+void generator_t::close_set(std::set<item_t> *set) {
+ std::queue<item_t> queue;
+ for (const item_t &item : *set)
+ queue.emplace(item);
+
+ for (; !queue.empty(); queue.pop()) {
+ const item_t &cur = queue.front();
+ if (!cur.has_next())
+ continue;
+
+ const symbol_t &sym = cur.get_next_symbol();
+ if (sym.get_type() != SYMBOL_TYPE_NONTERM)
+ continue;
+
+ for (const item_t &item : get_set(sym.get_value())) {
+ if (set->insert(item).second)
+ queue.push(item);
+ }
+ }
+}
+
+void generator_t::print_item(const item_t &item) {
+ printf("%s |=", item.get_lhs().c_str());
+
+ for (size_t i = 0; i <= item.get_rhs().size(); i++) {
+ if (i == item.get_point())
+ printf(" .");
+
+ if (i == item.get_rhs().size())
+ break;
+
+ switch (item.get_rhs()[i].get_type()) {
+ case SYMBOL_TYPE_CHAR:
+ printf(" '%c'", item.get_rhs()[i].get_value()[0]);
+ break;
+
+ default:
+ printf(" %s", item.get_rhs()[i].get_value().c_str());
+ }
+ }
+
+ printf("\n");
+}
+
+void generator_t::print_set(const std::set<item_t> &set) {
+ for (const item_t &item : set)
+ print_item(item);
+}
+
generator_t::generator_t(const std::set<item_t> &rules0) {
for (item_t rule : rules0) {
rules.emplace(rule.get_lhs(), rule);
@@ -39,6 +100,10 @@ generator_t::generator_t(const std::set<item_t> &rules0) {
}
}
+ std::set<item_t> set0 = get_set("");
+ close_set(&set0);
+
+ print_set(set0);
}
}