Some work on general LR table generator

This commit is contained in:
Robin Jadoul 2016-11-26 14:11:20 +01:00
parent 7333d48589
commit 80974d3a2e
2 changed files with 44 additions and 3 deletions

View File

@ -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<std::string> first(std::string s);
std::set<std::string> follow(std::string s);
@ -49,7 +59,13 @@ class Generator {
*/
void buildFollow();
/**
* Compute the closure of an item set
*/
std::set<Item> closure(const std::set<Item>& its);
Grammar m_gram;
Rule m_startrule;
std::map<std::string, std::set<std::string>> m_first;
std::map<std::string, std::set<std::string>> m_follow;
};

View File

@ -1,11 +1,20 @@
#include "Parsodus/lrtables/generator.h"
#include <queue>
namespace pds {
namespace lr
{
const std::string EXTENDED_START = "^";
const std::string EOF_PLACEHOLDER = "$";
template <typename Item>
Generator<Item>::Generator(const Grammar& g) : m_gram(g), m_first(), m_follow() {
Generator<Item>::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<Item>::Generator(const Grammar& g) : m_gram(g), m_first(), m_follow()
template <typename Item>
LRTable Generator<Item>::generate() {
//TODO
LRTable table;
std::vector<std::set<Item>> itemsets;
itemsets.emplace_back(closure({initial_item(m_startrule, EOF_PLACEHOLDER)}));
std::queue<Item> itemqueue;
itemqueue.push(itemsets[0]);
while (!itemqueue.empty()) {
std::set<Item> cur = std::move(itemqueue.front());
itemqueue.pop();
for (std::pair<std::string, std::set<Item>> succ : successors(cur)) {
//Add new itemset or merge
}
}
return table;
}
template <typename Item>
@ -70,7 +95,7 @@ void Generator<Item>::buildFirst() {
template <typename Item>
void Generator<Item>::buildFollow() {
//EOF follow the added start rule.
m_follow["^"].insert("$");
m_follow[EXTENDED_START].insert(EOF_PLACEHOLDER);
bool changes = true;