From ccfa95a79f90548a3a8ed8090bdebff5cab93e65 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Ko=C4=8Di=C4=8Dka?= <martin.kocicka@gmail.com>
Date: Wed, 11 May 2016 10:52:12 +0200
Subject: [PATCH] added universal LR parsing algorithm

---
 alib2algo/src/grammar/parsing/LRParser.cpp | 43 ++++++++++++++++++++++
 alib2algo/src/grammar/parsing/LRParser.h   |  4 ++
 2 files changed, 47 insertions(+)

diff --git a/alib2algo/src/grammar/parsing/LRParser.cpp b/alib2algo/src/grammar/parsing/LRParser.cpp
index 11428be758..86a8246ffb 100644
--- a/alib2algo/src/grammar/parsing/LRParser.cpp
+++ b/alib2algo/src/grammar/parsing/LRParser.cpp
@@ -85,6 +85,49 @@ LR0Items LRParser::getNextStateItems ( LR0Items items, alphabet::Symbol symbol,
 	return getClosure ( transitionItems, originalGrammar );
 }
 
+bool LRParser::parse ( LRActionTable actionTable, LRGotoTable gotoTable, automaton::State initialState, std::vector < alphabet::Symbol > input ) {
+	std::stack < automaton::State > states;
+	states.push ( initialState );
+
+	unsigned currentPosition = 0;
+	while ( true ) {
+		LRActionTable::iterator actionIterator = actionTable.find ( { states.top ( ), input[currentPosition] } );
+		if ( actionIterator == actionTable.end ( ) ) {
+			return false;
+		}
+
+		switch ( actionIterator->second.first ) {
+			case LRAction::Shift:
+				states.push ( actionIterator->second.second.get < automaton::State > ( ) );
+
+				++currentPosition;
+				break;
+
+			case LRAction::Reduce: {
+				std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > reduceBy = actionIterator->second.second.get < std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > ( );
+				for ( unsigned i = 0; i < reduceBy.second.size ( ); ++i ) {
+					states.pop ( );
+				}
+
+				LRGotoTable::iterator nextStateIterator = gotoTable.find ( { states.top ( ), reduceBy.first } );
+				if (nextStateIterator == gotoTable.end()) {
+					return false;
+				}
+
+				states.push ( nextStateIterator->second );
+
+				break;
+			}
+
+			case LRAction::Accept:
+				return true;
+				break;
+		}
+	}
+
+	return false;
+}
+
 } /* namespace parsing */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/parsing/LRParser.h b/alib2algo/src/grammar/parsing/LRParser.h
index 561f69bf8d..2f1ad997f0 100644
--- a/alib2algo/src/grammar/parsing/LRParser.h
+++ b/alib2algo/src/grammar/parsing/LRParser.h
@@ -12,6 +12,8 @@
 #include <grammar/ContextFree/CFG.h>
 #include <grammar/parsing/LRParserTypes.h>
 
+#include <vector>
+
 namespace grammar {
 
 namespace parsing {
@@ -25,6 +27,8 @@ public:
 	static LR0Items getClosure ( LR0Items items, grammar::CFG originalGrammar );
 
 	static LR0Items getNextStateItems ( LR0Items items, alphabet::Symbol symbol, grammar::CFG originalGrammar );
+
+	static bool parse ( LRActionTable actionTable, LRGotoTable gotoTable, automaton::State initialState, std::vector < alphabet::Symbol > input );
 };
 
 } /* namespace parsing */
-- 
GitLab