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