From 129b81e09375dbee4a12c468ef75f18243e8a0a4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 31 Mar 2015 18:38:59 +0200 Subject: generator: add methods to generate closed item sets --- src/generator.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/generator.hpp | 6 +++++ src/item.hpp | 2 +- 3 files changed, 72 insertions(+), 1 deletion(-) 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 + namespace solar { +std::set generator_t::get_set(const std::string &nonterm) { + std::set 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 *set) { + std::queue 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 &set) { + for (const item_t &item : set) + print_item(item); +} + generator_t::generator_t(const std::set &rules0) { for (item_t rule : rules0) { rules.emplace(rule.get_lhs(), rule); @@ -39,6 +100,10 @@ generator_t::generator_t(const std::set &rules0) { } } + std::set 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 rules; std::multimap items; + void close_set(std::set *set); + std::set get_set(const std::string &nonterm); + + void print_item(const item_t &item); + void print_set(const std::set &set); + public: generator_t(const std::set &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, unsigned> get_point()++; } - symbol_t get_next_symbol() const { + const symbol_t & get_next_symbol() const { return get_rhs()[get_point()]; } }; -- cgit v1.2.3