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