generator: add methods to generate closed item sets

This commit is contained in:
Matthias Schiffer 2015-03-31 18:38:59 +02:00
parent 8b94b9cf2c
commit 129b81e093
3 changed files with 72 additions and 1 deletions

View file

@ -26,9 +26,70 @@
#include "generator.hpp" #include "generator.hpp"
#include <queue>
namespace solar { 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) { generator_t::generator_t(const std::set<item_t> &rules0) {
for (item_t rule : rules0) { for (item_t rule : rules0) {
rules.emplace(rule.get_lhs(), rule); 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);
} }
} }

View file

@ -39,6 +39,12 @@ private:
std::multimap<std::string, item_t> rules; std::multimap<std::string, item_t> rules;
std::multimap<symbol_t, item_t> items; 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: public:
generator_t(const std::set<item_t> &rules0); generator_t(const std::set<item_t> &rules0);
}; };

View file

@ -69,7 +69,7 @@ struct item_t : public std::tuple<std::string, std::vector<symbol_t>, unsigned>
get_point()++; get_point()++;
} }
symbol_t get_next_symbol() const { const symbol_t & get_next_symbol() const {
return get_rhs()[get_point()]; return get_rhs()[get_point()];
} }
}; };