summaryrefslogtreecommitdiffstats
path: root/src/generator.cpp
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-03-31 22:52:25 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-03-31 23:40:44 +0200
commit3f1b701ad15458829468ce176ee6cecd16c4b420 (patch)
treef237e4925191a002adbcd4745a6288da84c3194a /src/generator.cpp
parent342f927aace815c2b6e7903def14d4aca9bc2233 (diff)
downloadsolar-3f1b701ad15458829468ce176ee6cecd16c4b420.tar
solar-3f1b701ad15458829468ce176ee6cecd16c4b420.zip
generator: add actions and gotos for LR(0) parsers
Diffstat (limited to 'src/generator.cpp')
-rw-r--r--src/generator.cpp79
1 files changed, 61 insertions, 18 deletions
diff --git a/src/generator.cpp b/src/generator.cpp
index e8fd07b..ec5d1f8 100644
--- a/src/generator.cpp
+++ b/src/generator.cpp
@@ -34,9 +34,9 @@ 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);
+ auto entries = nonterms.equal_range(nonterm);
for (auto entry = entries.first; entry != entries.second; ++entry)
- set.insert(entry->second);
+ set.insert(rules[entry->second]);
return set;
}
@@ -63,7 +63,7 @@ void generator_t::close_set(std::set<item_t> *set) {
}
void generator_t::generate_itemsets() {
- std::queue<std::pair<std::set<item_t>, unsigned>> queue;
+ std::queue<std::pair<std::set<item_t>, size_t>> queue;
{
std::set<item_t> set0 = get_set("");
@@ -95,11 +95,27 @@ void generator_t::generate_itemsets() {
close_set(&entry.second);
auto added = add_set(entry.second);
- transitions.emplace(std::make_pair(cur.second, entry.first), added.first->second);
+
+ if (entry.first.get_type() == SYMBOL_TYPE_NONTERM)
+ gotos.emplace(std::make_pair(cur.second, entry.first), added.first->second);
+ else
+ actions.emplace(std::make_pair(cur.second, entry.first), std::make_pair('s', added.first->second));
if (added.second)
queue.push(*added.first);
}
+
+ for (const item_t &item : cur.first) {
+ auto it = rule_ids.find(item);
+ if (it != rule_ids.end()) {
+ //if (it->second) {
+ // for (const symbol_t &term : terminals)
+ // transitions.emplace(std::make_pair(cur.second, term), std::make_pair('r', it->second));
+ //}
+
+ actions.emplace(std::make_pair(cur.second, symbol_t::make_term("")), std::make_pair('r', it->second));
+ }
+ }
}
}
@@ -114,11 +130,11 @@ void generator_t::print_symbol(const symbol_t &sym) {
}
}
-void generator_t::print_item(const item_t &item) {
+void generator_t::print_item(const item_t &item, bool point) {
printf("%s |=", item.get_lhs().c_str());
for (size_t i = 0; i <= item.get_rhs().size(); i++) {
- if (i == item.get_point())
+ if (i == item.get_point() && point)
printf(" .");
if (i == item.get_rhs().size())
@@ -133,37 +149,64 @@ void generator_t::print_item(const item_t &item) {
void generator_t::print_set(const std::set<item_t> &set) {
for (const item_t &item : set)
- print_item(item);
+ print_item(item, true);
}
-generator_t::generator_t(const std::set<item_t> &rules0) {
- for (item_t rule : rules0) {
- rules.emplace(rule.get_lhs(), rule);
+generator_t::generator_t(const std::vector<item_t> &rules0) : rules(rules0) {
+ for (size_t i = 0; i < rules.size(); i++) {
+ item_t rule = rules[i];
+
+ nonterms.emplace(rule.get_lhs(), i);
while (rule.has_next()) {
- items.emplace(rule.get_next_symbol(), rule);
+ const symbol_t &sym = rule.get_next_symbol();
+ items.emplace(sym, rule);
+
+ if (sym.get_type() != SYMBOL_TYPE_NONTERM)
+ terminals.insert(sym);
+
rule.shift();
}
+
+ rule_ids.emplace(rule, i);
}
generate_itemsets();
+ printf("Rules:\n");
+ for (size_t i = 0; i < rules.size(); i++) {
+ printf("(%u) ", unsigned(i));
+ print_item(rules[i], false);
+ }
+ printf("\n");
+
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);
+ for (size_t i = 0; i < itemsets.size(); i++) {
+ printf("Item %u:\n", unsigned(i));
print_set(*setlist[i]);
printf("\n");
}
- printf("Transitions:\n");
- for (const auto &t : transitions) {
- printf("%u ", t.first.first);
- print_symbol(t.first.second);
- printf(" -> %u\n", t.second);
+ printf("Actions:\n");
+ for (const auto &a : actions) {
+ printf("%u ", unsigned(a.first.first));
+
+ if (a.second.second) {
+ print_symbol(a.first.second);
+ printf(" -> %c%u\n", a.second.first, unsigned(a.second.second));
+ }
+ else {
+ printf("$ -> acc\n");
+ }
}
+ printf("\n");
+
+ printf("Gotos:\n");
+ for (const auto &g : gotos)
+ printf("%u %s -> %u\n", unsigned(g.first.first), g.first.second.get_value().c_str(), unsigned(g.second));
}
}