From 80974d3a2ef0e18b39215a2375ee623fbe0804db Mon Sep 17 00:00:00 2001 From: Robin Jadoul Date: Sat, 26 Nov 2016 14:11:20 +0100 Subject: [PATCH] Some work on general LR table generator --- include/Parsodus/lrtables/generator.h | 18 ++++++++++++++++- src/lrtables/generator.cpp | 29 +++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/include/Parsodus/lrtables/generator.h b/include/Parsodus/lrtables/generator.h index f49988d..423be1c 100644 --- a/include/Parsodus/lrtables/generator.h +++ b/include/Parsodus/lrtables/generator.h @@ -18,9 +18,10 @@ class Generator { /** * Constructor * + * @param start The start symbol for the grammar * @param g The grammar to translate */ - Generator(const Grammar& g); + Generator(const std::string& start, const Grammar& g); /** * Generate an LRTable based on given grammar @@ -35,6 +36,15 @@ class Generator { */ virtual bool needsFollowSet() = 0; + /** + * Build the starting item to build all item sets from + * + * @param startrule The constructed extended starting rule + * @param eof The token used as end of file + */ + virtual Item initial_item(Rule startrule, std::string eof) = 0; + + std::set first(std::string s); std::set follow(std::string s); @@ -49,7 +59,13 @@ class Generator { */ void buildFollow(); + /** + * Compute the closure of an item set + */ + std::set closure(const std::set& its); + Grammar m_gram; + Rule m_startrule; std::map> m_first; std::map> m_follow; }; diff --git a/src/lrtables/generator.cpp b/src/lrtables/generator.cpp index 665c0a5..8cf8a17 100644 --- a/src/lrtables/generator.cpp +++ b/src/lrtables/generator.cpp @@ -1,11 +1,20 @@ #include "Parsodus/lrtables/generator.h" +#include + namespace pds { namespace lr { + +const std::string EXTENDED_START = "^"; +const std::string EOF_PLACEHOLDER = "$"; template -Generator::Generator(const Grammar& g) : m_gram(g), m_first(), m_follow() { +Generator::Generator(const std::string& start, const Grammar& g) : m_gram(g), m_startrule(Rule{EXTENDED_START, {start}}), m_first(), m_follow() { + m_gram.terminals.insert(EOF_PLACEHOLDER); //End of file + m_gram.variables.insert(EXTENDED_START); //modified start rule + m_gram.rules[EXTENDED_START].insert(m_startrule); + if (needsFollowSet()) { buildFirst(); buildFollow(); @@ -15,6 +24,22 @@ Generator::Generator(const Grammar& g) : m_gram(g), m_first(), m_follow() template LRTable Generator::generate() { //TODO + LRTable table; + std::vector> itemsets; + itemsets.emplace_back(closure({initial_item(m_startrule, EOF_PLACEHOLDER)})); + + std::queue itemqueue; + itemqueue.push(itemsets[0]); + while (!itemqueue.empty()) { + std::set cur = std::move(itemqueue.front()); + itemqueue.pop(); + + for (std::pair> succ : successors(cur)) { + //Add new itemset or merge + } + } + + return table; } template @@ -70,7 +95,7 @@ void Generator::buildFirst() { template void Generator::buildFollow() { //EOF follow the added start rule. - m_follow["^"].insert("$"); + m_follow[EXTENDED_START].insert(EOF_PLACEHOLDER); bool changes = true;