diff --git a/alib2/src/grammar/Unrestricted/UnrestrictedGrammar.cpp b/alib2/src/grammar/Unrestricted/UnrestrictedGrammar.cpp index 272b4b58cb1360d68a03057baf6039ddee09799d..d621171b71aabfa7220e41036f47bae0f16201f9 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");