Some work on general LR table generator
This commit is contained in:
		
							parent
							
								
									7333d48589
								
							
						
					
					
						commit
						80974d3a2e
					
				|  | @ -18,9 +18,10 @@ class Generator { | ||||||
|         /**
 |         /**
 | ||||||
|          * Constructor |          * Constructor | ||||||
|          * |          * | ||||||
|  |          * @param start The start symbol for the grammar | ||||||
|          * @param g The grammar to translate |          * @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 |          * Generate an LRTable based on given grammar | ||||||
|  | @ -35,6 +36,15 @@ class Generator { | ||||||
|          */ |          */ | ||||||
|         virtual bool needsFollowSet() = 0; |         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> first(std::string s); | ||||||
|         std::set<std::string> follow(std::string s); |         std::set<std::string> follow(std::string s); | ||||||
| 
 | 
 | ||||||
|  | @ -49,7 +59,13 @@ class Generator { | ||||||
|          */ |          */ | ||||||
|         void buildFollow(); |         void buildFollow(); | ||||||
| 
 | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Compute the closure of an item set | ||||||
|  |          */ | ||||||
|  |         std::set<Item> closure(const std::set<Item>& its); | ||||||
|  | 
 | ||||||
|         Grammar m_gram; |         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_first; | ||||||
|         std::map<std::string, std::set<std::string>> m_follow; |         std::map<std::string, std::set<std::string>> m_follow; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -1,11 +1,20 @@ | ||||||
| #include "Parsodus/lrtables/generator.h" | #include "Parsodus/lrtables/generator.h" | ||||||
| 
 | 
 | ||||||
|  | #include <queue> | ||||||
|  | 
 | ||||||
| namespace pds { | namespace pds { | ||||||
| namespace lr | namespace lr | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
|  | const std::string EXTENDED_START = "^"; | ||||||
|  | const std::string EOF_PLACEHOLDER = "$"; | ||||||
|  |     | ||||||
| template <typename Item> | 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()) { |     if (needsFollowSet()) { | ||||||
|         buildFirst(); |         buildFirst(); | ||||||
|         buildFollow(); |         buildFollow(); | ||||||
|  | @ -15,6 +24,22 @@ Generator<Item>::Generator(const Grammar& g) : m_gram(g), m_first(), m_follow() | ||||||
| template <typename Item> | template <typename Item> | ||||||
| LRTable Generator<Item>::generate() { | LRTable Generator<Item>::generate() { | ||||||
|     //TODO
 |     //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> | template <typename Item> | ||||||
|  | @ -70,7 +95,7 @@ void Generator<Item>::buildFirst() { | ||||||
| template <typename Item> | template <typename Item> | ||||||
| void Generator<Item>::buildFollow() { | void Generator<Item>::buildFollow() { | ||||||
|     //EOF follow the added start rule.
 |     //EOF follow the added start rule.
 | ||||||
|     m_follow["^"].insert("$"); |     m_follow[EXTENDED_START].insert(EOF_PLACEHOLDER); | ||||||
| 
 | 
 | ||||||
|     bool changes = true; |     bool changes = true; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue