Some work on general LR table generator
This commit is contained in:
parent
7333d48589
commit
80974d3a2e
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue