From 670d2e41828cbdb6af541c17ea87ee6a64025a98 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Thu, 10 Jul 2014 20:18:42 +0200
Subject: [PATCH] Checking of grammar rules shape for unrestricted g

---
 .../Unrestricted/UnrestrictedGrammar.cpp      | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/alib2/src/grammar/Unrestricted/UnrestrictedGrammar.cpp b/alib2/src/grammar/Unrestricted/UnrestrictedGrammar.cpp
index 272b4b58cb..d621171b71 100644
--- a/alib2/src/grammar/Unrestricted/UnrestrictedGrammar.cpp
+++ b/alib2/src/grammar/Unrestricted/UnrestrictedGrammar.cpp
@@ -62,6 +62,27 @@ bool UnrestrictedGrammar::removeNonterminalSymbol(const alphabet::Symbol& symbol
 }
 
 bool UnrestrictedGrammar::addRule(const std::vector<alphabet::Symbol>& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	int lSize = leftHandSide.size();
+	int rSize = rightHandSide.size();
+
+	if(lSize > rSize + 1)
+		throw GrammarException("Invalid size of right hand side of a rule");
+
+	int lContext;
+	int rContext;
+	for(lContext = 0; lContext < lSize - 1 && leftHandSide[lContext] == rightHandSide[lContext]; lContext++);
+	for(rContext = 0; rContext < lSize - 1 && leftHandSide[lSize - rContext] == rightHandSide[rSize - rContext]; rContext++);
+
+	if(lContext + rContext + 1 < lSize)
+		throw GrammarException("Rule must rewrite only one symbol");
+
+	if(lContext + rContext + 1 == lSize && !nonterminalAlphabet.count(leftHandSide[lContext]))
+		throw GrammarException("Rule must rewrite nonterminal symbol");
+
+	if(/* lContext + rContext + 1 > lSize */ std::all_of(leftHandSide.begin(), leftHandSide.end(), [&](const alphabet::Symbol symbol) {return !nonterminalAlphabet.count(symbol);}))
+		throw GrammarException("Rule must rewrite nonterminal symbol");
+
+
 	for(const alphabet::Symbol& symbol : leftHandSide)
 		if(terminalAlphabet.find(symbol) == terminalAlphabet.end() && nonterminalAlphabet.find(symbol) == nonterminalAlphabet.end())
 			throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is not neither terminal nor nonterminal symbol");
-- 
GitLab