summaryrefslogtreecommitdiffstats
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
parent8b94b9cf2c91e00665771bb46e1d9a6400114e63 (diff)
downloadsolar-129b81e09375dbee4a12c468ef75f18243e8a0a4.tar
solar-129b81e09375dbee4a12c468ef75f18243e8a0a4.zip
generator: add methods to generate closed item sets
-rw-r--r--src/generator.cpp65
-rw-r--r--src/generator.hpp6
-rw-r--r--src/item.hpp2
3 files changed, 72 insertions, 1 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);
}
}
diff --git a/src/generator.hpp b/src/generator.hpp
index 74108d7..d9bcaf6 100644
--- a/src/generator.hpp
+++ b/src/generator.hpp
@@ -39,6 +39,12 @@ private:
std::multimap<std::string, item_t> rules;
std::multimap<symbol_t, item_t> items;
+ void close_set(std::set<item_t> *set);
+ std::set<item_t> get_set(const std::string &nonterm);
+
+ void print_item(const item_t &item);
+ void print_set(const std::set<item_t> &set);
+
public:
generator_t(const std::set<item_t> &rules0);
};
diff --git a/src/item.hpp b/src/item.hpp
index faebf79..ae282a9 100644
--- a/src/item.hpp
+++ b/src/item.hpp
@@ -69,7 +69,7 @@ struct item_t : public std::tuple<std::string, std::vector<symbol_t>, unsigned>
get_point()++;
}
- symbol_t get_next_symbol() const {
+ const symbol_t & get_next_symbol() const {
return get_rhs()[get_point()];
}
};