From b80d7cb8d52e1975058302edbe968987c1b8574f Mon Sep 17 00:00:00 2001
From: Martin Zak <zakmart1@fit.cvut.cz>
Date: Sun, 17 Nov 2013 17:07:04 +0100
Subject: [PATCH] Adds LeftRegularGrammar

---
 alib/src/grammar/LeftRegularGrammar.cpp | 62 +++++++++++++++++++++++++
 alib/src/grammar/LeftRegularGrammar.h   | 24 ++++++++++
 examples/grammar/leftRegular.xml        | 46 ++++++++++++++++++
 3 files changed, 132 insertions(+)
 create mode 100644 alib/src/grammar/LeftRegularGrammar.cpp
 create mode 100644 alib/src/grammar/LeftRegularGrammar.h
 create mode 100644 examples/grammar/leftRegular.xml

diff --git a/alib/src/grammar/LeftRegularGrammar.cpp b/alib/src/grammar/LeftRegularGrammar.cpp
new file mode 100644
index 0000000000..d5e93ee179
--- /dev/null
+++ b/alib/src/grammar/LeftRegularGrammar.cpp
@@ -0,0 +1,62 @@
+/*
+ * LeftRegularGrammar.cpp
+ *
+ *  Created on: Nov 17, 2013
+ *      Author: martin
+ */
+
+#include "LeftRegularGrammar.h"
+
+namespace grammar {
+
+bool LeftRegularGrammar::isValidRule(const Rule& rule) const {
+	return checkLeftSide(rule.getLeftSide()) && checkRightSide(rule.getRightSide());
+}
+
+bool LeftRegularGrammar::checkLeftSide(const list<Symbol>& leftSide) const {
+	if (leftSide.size() != 1) {
+		return false;
+	}
+
+	if (nonTerminalSymbols.find(leftSide.front()) == nonTerminalSymbols.end()) {
+		return false;
+	}
+
+	return true;
+}
+
+bool LeftRegularGrammar::checkRightSide(const list<Symbol>& rightSide) const {
+	if (rightSide.size() == 0) {
+		return true;
+	} else if (rightSide.size() == 1) {
+		const Symbol& symbol = rightSide.front();
+
+		//check epsilon
+		if (symbol.getSymbol() == "") {
+			return true;
+		}
+
+		//check that symbol exists
+		return ((terminalSymbols.find(symbol) != terminalSymbols.end())
+				|| (nonTerminalSymbols.find(symbol) != nonTerminalSymbols.end()));
+	} else {
+		//check if first symbol is nonterminal
+		list<Symbol>::const_iterator symbol = rightSide.begin();
+		if (nonTerminalSymbols.find(*symbol) == nonTerminalSymbols.end()) {
+			return false;
+		}
+
+		symbol++;
+
+		//check if following symbols are terminal
+		for (; symbol != rightSide.end(); symbol++) {
+			if (terminalSymbols.find(*symbol) == terminalSymbols.end()) {
+				return false;
+			}
+		}
+
+		return true;
+	}
+}
+
+} /* namespace grammar */
diff --git a/alib/src/grammar/LeftRegularGrammar.h b/alib/src/grammar/LeftRegularGrammar.h
new file mode 100644
index 0000000000..37d71be653
--- /dev/null
+++ b/alib/src/grammar/LeftRegularGrammar.h
@@ -0,0 +1,24 @@
+/*
+ * LeftRegularGrammar.h
+ *
+ *  Created on: Nov 17, 2013
+ *      Author: martin
+ */
+
+#ifndef LEFTREGULARGRAMMAR_H_
+#define LEFTREGULARGRAMMAR_H_
+
+#include "Grammar.h"
+
+namespace grammar {
+
+class LeftRegularGrammar : public Grammar {
+private:
+	bool checkLeftSide(const list<Symbol>& leftSide) const;
+	bool checkRightSide(const list<Symbol>& rightSide) const;
+protected:
+	bool isValidRule(const Rule& rule) const;
+};
+
+} /* namespace grammar */
+#endif /* LEFTREGULARGRAMMAR_H_ */
diff --git a/examples/grammar/leftRegular.xml b/examples/grammar/leftRegular.xml
new file mode 100644
index 0000000000..f1ab4aa2e9
--- /dev/null
+++ b/examples/grammar/leftRegular.xml
@@ -0,0 +1,46 @@
+<grammar>
+	<nonTerminalSymbols>
+		<symbol>S</symbol>
+		<symbol>A</symbol>
+	</nonTerminalSymbols>
+
+	<terminalSymbols>
+		<symbol>a</symbol>
+		<symbol>b</symbol>
+	</terminalSymbols>
+
+	<rules>
+		<rule>
+			<leftSide>
+				<symbol>S</symbol>
+			</leftSide>
+
+			<rightSide>
+				<symbol>A</symbol>
+			</rightSide>
+		</rule>
+		<rule>
+			<leftSide>
+				<symbol>A</symbol>
+			</leftSide>
+
+			<rightSide>
+				<symbol>a</symbol>
+			</rightSide>
+		</rule>
+		<rule>
+			<leftSide>
+				<symbol>A</symbol>
+			</leftSide>
+			<rightSide>
+				<symbol>A</symbol>
+				<symbol>b</symbol>
+				<symbol>b</symbol>
+				<symbol>b</symbol>
+			</rightSide>
+		</rule>
+	</rules>
+
+	<startSymbol>S</startSymbol>
+	
+</grammar>
-- 
GitLab