From c44d01e68e7f1292519383e71dbafbcf7f0bda56 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sun, 9 Apr 2017 16:26:11 +0200
Subject: [PATCH] improve addRule in some grammars

---
 alib2data/src/grammar/ContextFree/CNF.h       | 15 ++++------
 .../src/grammar/ContextFree/EpsilonFreeCFG.h  |  4 +--
 alib2data/src/grammar/ContextFree/LG.h        | 12 ++++----
 alib2data/src/grammar/ContextSensitive/CSG.h  | 28 +++++++++----------
 .../ContextSensitive/NonContractingGrammar.h  |  9 +++---
 alib2data/src/grammar/Regular/LeftLG.h        |  6 ++--
 alib2data/src/grammar/Regular/LeftRG.h        |  6 ++--
 alib2data/src/grammar/Regular/RightLG.h       |  6 ++--
 alib2data/src/grammar/Regular/RightRG.h       |  6 ++--
 9 files changed, 37 insertions(+), 55 deletions(-)

diff --git a/alib2data/src/grammar/ContextFree/CNF.h b/alib2data/src/grammar/ContextFree/CNF.h
index a24e260b36..d237a00925 100644
--- a/alib2data/src/grammar/ContextFree/CNF.h
+++ b/alib2data/src/grammar/ContextFree/CNF.h
@@ -145,28 +145,23 @@ GrammarBase * CNF < SymbolType >::plunder ( ) && {
 
 template < class SymbolType >
 bool CNF < SymbolType >::addRule ( SymbolType leftHandSide, std::variant < SymbolType, std::pair < SymbolType, SymbolType > > rightHandSide ) {
-	if ( rightHandSide.template is < SymbolType > ( ) ) {
-		if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) )
-			throw GrammarException ( "Rule must rewrite nonterminal symbol" );
+	if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) )
+		throw GrammarException ( "Rule must rewrite nonterminal symbol" );
 
+	if ( rightHandSide.template is < SymbolType > ( ) ) {
 		if ( !getTerminalAlphabet ( ).count ( rightHandSide.template get < SymbolType > ( ) ) )
 			throw GrammarException ( "Rule must rewrite to terminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 	} else {
 		const std::pair < SymbolType, SymbolType > rhs = rightHandSide.template get < std::pair < SymbolType, SymbolType > > ( );
 
-		if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) )
-			throw GrammarException ( "Rule must rewrite nonterminal symbol" );
-
 		if ( !getNonterminalAlphabet ( ).count ( rhs.first ) )
 			throw GrammarException ( "Symbol \"" + std::to_string ( rhs.first ) + "\" is not a nonterminal symbol" );
 
 		if ( !getNonterminalAlphabet ( ).count ( rhs.second ) )
 			throw GrammarException ( "Symbol \"" + std::to_string ( rhs.second ) + "\" is not a nonterminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 	}
+
+	return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 }
 
 template < class SymbolType >
diff --git a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h
index 809b4fcc08..4c136ba725 100644
--- a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h
+++ b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h
@@ -140,9 +140,7 @@ GrammarBase * EpsilonFreeCFG < SymbolType >::plunder ( ) && {
 
 template < class SymbolType >
 bool EpsilonFreeCFG < SymbolType >::addRule ( SymbolType leftHandSide, std::vector < SymbolType > rightHandSide ) {
-	int rSize = rightHandSide.size ( );
-
-	if ( rSize == 0 )
+	if ( rightHandSide.size ( ) == 0 )
 		throw GrammarException ( "Epsilon rule is not allowed" );
 
 	if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) )
diff --git a/alib2data/src/grammar/ContextFree/LG.h b/alib2data/src/grammar/ContextFree/LG.h
index 4c81ce04f8..6fa87be0b9 100644
--- a/alib2data/src/grammar/ContextFree/LG.h
+++ b/alib2data/src/grammar/ContextFree/LG.h
@@ -148,27 +148,25 @@ bool LG < SymbolType >::addRule ( SymbolType leftHandSide, std::variant < std::v
 	if ( rightHandSide.template is < std::vector < SymbolType > > ( ) ) {
 		const std::vector < SymbolType > & rhs = rightHandSide.template get < std::vector < SymbolType > > ( );
 
-		for ( const auto & symbol : rhs )
+		for ( const SymbolType & symbol : rhs )
 			if ( !getTerminalAlphabet ( ).count ( symbol ) )
 				throw GrammarException ( "Symbol " + std::to_string ( symbol ) + " is not a terminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 	} else {
 		const std::tuple < std::vector < SymbolType >, SymbolType, std::vector < SymbolType > > & rhs = rightHandSide.template get < std::tuple < std::vector < SymbolType >, SymbolType, std::vector < SymbolType > > > ( );
 
-		for ( const auto & symbol : std::get < 0 > ( rhs ) )
+		for ( const SymbolType & symbol : std::get < 0 > ( rhs ) )
 			if ( !getTerminalAlphabet ( ).count ( symbol ) )
 				throw GrammarException ( "Symbol " + std::to_string ( symbol ) + " is not a terminal symbol" );
 
 		if ( !getNonterminalAlphabet ( ).count ( std::get < 1 > ( rhs ) ) )
 			throw GrammarException ( "Symbol " + std::to_string ( std::get < 1 > ( rhs ) ) + " is not a nonterminal symbol" );
 
-		for ( const auto & symbol : std::get < 2 > ( rhs ) )
+		for ( const SymbolType & symbol : std::get < 2 > ( rhs ) )
 			if ( !getTerminalAlphabet ( ).count ( symbol ) )
 				throw GrammarException ( "Symbol " + std::to_string ( symbol ) + " is not a terminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 	}
+
+	return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 }
 
 template < class SymbolType >
diff --git a/alib2data/src/grammar/ContextSensitive/CSG.h b/alib2data/src/grammar/ContextSensitive/CSG.h
index a241871519..13cf1f4555 100644
--- a/alib2data/src/grammar/ContextSensitive/CSG.h
+++ b/alib2data/src/grammar/ContextSensitive/CSG.h
@@ -134,28 +134,26 @@ GrammarBase * CSG < SymbolType >::plunder ( ) && {
 
 template < class SymbolType >
 bool CSG < SymbolType >::addRule ( std::vector < SymbolType > lContext, SymbolType leftHandSide, std::vector < SymbolType > rContext, std::vector < SymbolType > rightHandSide ) {
-	int rSize = rightHandSide.size ( );
+	for ( const SymbolType & symbol : lContext )
+		if ( !getTerminalAlphabet ( ).count ( symbol ) && !getNonterminalAlphabet ( ).count ( symbol ) )
+			throw GrammarException ( "Symbol \"" + std::to_string ( symbol ) + "\" is not neither terminal nor nonterminal symbol" );
 
-	if ( rSize == 0 ) {
-		throw GrammarException ( "Epsilon rule is not allowed" );
-	} else {
-		for ( const SymbolType & symbol : lContext )
-			if ( !getTerminalAlphabet ( ).count ( symbol ) && !getNonterminalAlphabet ( ).count ( symbol ) )
-				throw GrammarException ( "Symbol \"" + std::to_string ( symbol ) + "\" is not neither terminal nor nonterminal symbol" );
+	if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) )
+		throw GrammarException ( "Rule must rewrite nonterminal symbol" );
 
-		if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) )
-			throw GrammarException ( "Rule must rewrite nonterminal symbol" );
-
-		for ( const SymbolType & symbol : rContext )
-			if ( !getTerminalAlphabet ( ).count ( symbol ) && !getNonterminalAlphabet ( ).count ( symbol ) )
-				throw GrammarException ( "Symbol \"" + std::to_string ( symbol ) + "\" is not neither terminal nor nonterminal symbol" );
+	for ( const SymbolType & symbol : rContext )
+		if ( !getTerminalAlphabet ( ).count ( symbol ) && !getNonterminalAlphabet ( ).count ( symbol ) )
+			throw GrammarException ( "Symbol \"" + std::to_string ( symbol ) + "\" is not neither terminal nor nonterminal symbol" );
 
+	if ( rightHandSide.size ( ) == 0 ) {
+		throw GrammarException ( "Epsilon rule is not allowed" );
+	} else {
 		for ( const SymbolType & symbol : rightHandSide )
 			if ( !getTerminalAlphabet ( ).count ( symbol ) && !getNonterminalAlphabet ( ).count ( symbol ) )
 				throw GrammarException ( "Symbol \"" + std::to_string ( symbol ) + "\" is not neither terminal nor nonterminal symbol" );
-
-		return rules[make_tuple ( std::move ( lContext ), std::move ( leftHandSide ), std::move ( rContext ) )].insert ( std::move ( rightHandSide ) ).second;
 	}
+
+	return rules[make_tuple ( std::move ( lContext ), std::move ( leftHandSide ), std::move ( rContext ) )].insert ( std::move ( rightHandSide ) ).second;
 }
 
 template < class SymbolType >
diff --git a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h
index de01bff186..05988372ac 100644
--- a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h
+++ b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h
@@ -135,10 +135,6 @@ GrammarBase * NonContractingGrammar < SymbolType >::plunder ( ) && {
 template < class SymbolType >
 bool NonContractingGrammar < SymbolType >::addRule ( std::vector < SymbolType > leftHandSide, std::vector < SymbolType > rightHandSide ) {
 	int lSize = leftHandSide.size ( );
-	int rSize = rightHandSide.size ( );
-
-	if ( lSize > rSize )
-		throw GrammarException ( "Invalid size of right hand side of a rule" );
 
 	if ( std::all_of ( leftHandSide.begin ( ), leftHandSide.end ( ), [this] ( const SymbolType symbol ) {
 			return !getNonterminalAlphabet ( ).count ( symbol );
@@ -149,6 +145,11 @@ bool NonContractingGrammar < SymbolType >::addRule ( std::vector < SymbolType >
 		if ( !getTerminalAlphabet ( ).count ( symbol ) && !getNonterminalAlphabet ( ).count ( symbol ) )
 			throw GrammarException ( "Symbol \"" + std::to_string ( symbol ) + "\" is not neither terminal nor nonterminal symbol" );
 
+	int rSize = rightHandSide.size ( );
+
+	if ( lSize > rSize )
+		throw GrammarException ( "Invalid size of right hand side of a rule" );
+
 	for ( const SymbolType & symbol : rightHandSide )
 		if ( !getTerminalAlphabet ( ).count ( symbol ) && !getNonterminalAlphabet ( ).count ( symbol ) )
 			throw GrammarException ( "Symbol \"" + std::to_string ( symbol ) + "\" is not neither terminal nor nonterminal symbol" );
diff --git a/alib2data/src/grammar/Regular/LeftLG.h b/alib2data/src/grammar/Regular/LeftLG.h
index 19229345d7..a9d357117a 100644
--- a/alib2data/src/grammar/Regular/LeftLG.h
+++ b/alib2data/src/grammar/Regular/LeftLG.h
@@ -148,8 +148,6 @@ bool LeftLG < SymbolType >::addRule ( SymbolType leftHandSide, std::variant < st
 		for ( const auto & symbol : rightHandSide.template get < std::vector < SymbolType > > ( ) )
 			if ( !getTerminalAlphabet ( ).count ( symbol ) )
 				throw GrammarException ( "Symbol " + std::to_string ( symbol ) + " is not a terminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 	} else {
 		const std::pair < SymbolType, std::vector < SymbolType > > & rhs = rightHandSide.template get < std::pair < SymbolType, std::vector < SymbolType > > > ( );
 
@@ -159,9 +157,9 @@ bool LeftLG < SymbolType >::addRule ( SymbolType leftHandSide, std::variant < st
 		for ( const auto & symbol : rhs.second )
 			if ( !getTerminalAlphabet ( ).count ( symbol ) )
 				throw GrammarException ( "Symbol " + std::to_string ( symbol ) + " is not a terminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 	}
+
+	return rules [ std::move ( leftHandSide ) ].insert ( std::move ( rightHandSide ) ).second;
 }
 
 template < class SymbolType >
diff --git a/alib2data/src/grammar/Regular/LeftRG.h b/alib2data/src/grammar/Regular/LeftRG.h
index 7bc223fcf9..47fc58e385 100644
--- a/alib2data/src/grammar/Regular/LeftRG.h
+++ b/alib2data/src/grammar/Regular/LeftRG.h
@@ -227,16 +227,14 @@ bool LeftRG < SymbolType >::addRule ( SymbolType leftHandSide, std::variant < Sy
 
 		if ( !getTerminalAlphabet ( ).count ( rhs ) )
 			throw GrammarException ( "Rule must rewrite to terminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 	} else {
 		const std::pair < SymbolType, SymbolType > & rhs = rightHandSide.template get < std::pair < SymbolType, SymbolType > > ( );
 
 		if ( !getNonterminalAlphabet ( ).count ( rhs.first ) || !getTerminalAlphabet ( ).count ( rhs.second ) )
 			throw GrammarException ( "Rule must rewrite to terminal symbol followed by nonterminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 	}
+
+	return rules [ std::move ( leftHandSide ) ].insert ( std::move ( rightHandSide ) ).second;
 }
 
 template < class SymbolType >
diff --git a/alib2data/src/grammar/Regular/RightLG.h b/alib2data/src/grammar/Regular/RightLG.h
index ec0c428fcd..c3d430c30b 100644
--- a/alib2data/src/grammar/Regular/RightLG.h
+++ b/alib2data/src/grammar/Regular/RightLG.h
@@ -148,8 +148,6 @@ bool RightLG < SymbolType >::addRule ( SymbolType leftHandSide, std::variant < s
 		for ( const auto & symbol : rightHandSide.template get < std::vector < SymbolType > > ( ) )
 			if ( !getTerminalAlphabet ( ).count ( symbol ) )
 				throw GrammarException ( "Symbol " + std::to_string ( symbol ) + " is not a terminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 	} else {
 		const std::pair < std::vector < SymbolType >, SymbolType > & rhs = rightHandSide.template get < std::pair < std::vector < SymbolType >, SymbolType > > ( );
 
@@ -159,9 +157,9 @@ bool RightLG < SymbolType >::addRule ( SymbolType leftHandSide, std::variant < s
 		for ( const auto & symbol : rhs.first )
 			if ( !getTerminalAlphabet ( ).count ( symbol ) )
 				throw GrammarException ( "Symbol " + std::to_string ( symbol ) + " is not a terminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 	}
+
+	return rules [ std::move ( leftHandSide ) ].insert ( std::move ( rightHandSide ) ).second;
 }
 
 template < class SymbolType >
diff --git a/alib2data/src/grammar/Regular/RightRG.h b/alib2data/src/grammar/Regular/RightRG.h
index 359d498efd..de42427fa2 100644
--- a/alib2data/src/grammar/Regular/RightRG.h
+++ b/alib2data/src/grammar/Regular/RightRG.h
@@ -170,16 +170,14 @@ bool RightRG < SymbolType >::addRule ( SymbolType leftHandSide, std::variant < S
 
 		if ( !getTerminalAlphabet ( ).count ( rhs ) )
 			throw GrammarException ( "Rule must rewrite to terminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 	} else {
 		const std::pair < SymbolType, SymbolType > & rhs = rightHandSide.template get < std::pair < SymbolType, SymbolType > > ( );
 
 		if ( !getTerminalAlphabet ( ).count ( rhs.first ) || !getNonterminalAlphabet ( ).count ( rhs.second ) )
 			throw GrammarException ( "Rule must rewrite to terminal symbol followed by nonterminal symbol" );
-
-		return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 	}
+
+	return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second;
 }
 
 template < class SymbolType >
-- 
GitLab