generator: generate item sets recursively
This commit is contained in:
parent
129b81e093
commit
03b5a87eeb
2 changed files with 59 additions and 5 deletions
|
@ -62,6 +62,45 @@ void generator_t::close_set(std::set<item_t> *set) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void generator_t::generate_itemsets() {
|
||||||
|
std::queue<std::set<item_t>> queue;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::set<item_t> set0 = get_set("");
|
||||||
|
close_set(&set0);
|
||||||
|
|
||||||
|
add_set(set0);
|
||||||
|
queue.push(set0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; !queue.empty(); queue.pop()) {
|
||||||
|
const std::set<item_t> &cur = queue.front();
|
||||||
|
|
||||||
|
const std::set<item_t> empty_set;
|
||||||
|
std::map<symbol_t, std::set<item_t>> new_sets;
|
||||||
|
|
||||||
|
for (const item_t &item : cur) {
|
||||||
|
if (!item.has_next())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const symbol_t &sym = item.get_next_symbol();
|
||||||
|
|
||||||
|
item_t shifted = item;
|
||||||
|
shifted.shift();
|
||||||
|
|
||||||
|
std::set<item_t> &set = new_sets.emplace(sym, empty_set).first->second;
|
||||||
|
set.insert(std::move(shifted));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &entry : new_sets) {
|
||||||
|
close_set(&entry.second);
|
||||||
|
|
||||||
|
if (add_set(entry.second).first)
|
||||||
|
queue.push(entry.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void generator_t::print_item(const item_t &item) {
|
void generator_t::print_item(const item_t &item) {
|
||||||
printf("%s |=", item.get_lhs().c_str());
|
printf("%s |=", item.get_lhs().c_str());
|
||||||
|
|
||||||
|
@ -100,10 +139,17 @@ generator_t::generator_t(const std::set<item_t> &rules0) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<item_t> set0 = get_set("");
|
generate_itemsets();
|
||||||
close_set(&set0);
|
|
||||||
|
|
||||||
print_set(set0);
|
const std::set<item_t> *setlist[itemsets.size()];
|
||||||
|
for (const auto &entry : itemsets)
|
||||||
|
setlist[entry.second] = &entry.first;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < itemsets.size(); i++) {
|
||||||
|
printf("Item %u:\n", i);
|
||||||
|
print_set(*setlist[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,12 +38,20 @@ class generator_t {
|
||||||
private:
|
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;
|
||||||
|
std::map<std::set<item_t>, unsigned> itemsets;
|
||||||
|
|
||||||
void close_set(std::set<item_t> *set);
|
void close_set(std::set<item_t> *set);
|
||||||
std::set<item_t> get_set(const std::string &nonterm);
|
std::set<item_t> get_set(const std::string &nonterm);
|
||||||
|
|
||||||
void print_item(const item_t &item);
|
std::pair<bool, unsigned> add_set(const std::set<item_t> &set) {
|
||||||
void print_set(const std::set<item_t> &set);
|
auto ret = itemsets.emplace(set, itemsets.size());
|
||||||
|
return std::make_pair(ret.second, ret.first->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generate_itemsets();
|
||||||
|
|
||||||
|
static void print_item(const item_t &item);
|
||||||
|
static 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);
|
||||||
|
|
Reference in a new issue