diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/generator.cpp | 65 | ||||
-rw-r--r-- | src/generator.hpp | 6 | ||||
-rw-r--r-- | src/item.hpp | 2 |
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()]; } }; |