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