diff --git a/alib2algo/src/grammar/simplify/EpsilonRemover.cpp b/alib2algo/src/grammar/simplify/EpsilonRemover.cpp index 6da99955335737e9ba5ba83d1258bae0defc657b..76abf3b1ba05b50ef5eecf5d10301a3484a7753c 100644 --- a/alib2algo/src/grammar/simplify/EpsilonRemover.cpp +++ b/alib2algo/src/grammar/simplify/EpsilonRemover.cpp @@ -7,103 +7,18 @@ #include "EpsilonRemover.h" -#include "../properties/NullableNonterminals.h" - namespace grammar { namespace simplify { -void removeNullableNonterminals(grammar::EpsilonFreeCFG < > & grammar, const std::set<alphabet::Symbol>& nullableNonterminals, const alphabet::Symbol& lhs, const std::vector<alphabet::Symbol>& rhs, unsigned i, std::vector<alphabet::Symbol> clear) { - if(rhs.size() == i) { - if(clear.size() == 0) return; - grammar.addRule(lhs, clear); - } else if(nullableNonterminals.find(rhs[i]) != nullableNonterminals.end()) { - removeNullableNonterminals(grammar, nullableNonterminals, lhs, rhs, i+1, clear); - clear.push_back(rhs[i]); - removeNullableNonterminals(grammar, nullableNonterminals, lhs, rhs, i+1, clear); - } else { - clear.push_back(rhs[i]); - removeNullableNonterminals(grammar, nullableNonterminals, lhs, rhs, i+1, clear); - } -} - -template<class T> -grammar::EpsilonFreeCFG < > removeInternal( const T & origGrammar ) { - grammar::EpsilonFreeCFG < > grammar(origGrammar.getInitialSymbol()); - - for( const auto & symbol : origGrammar.getNonterminalAlphabet() ) - grammar.addNonterminalSymbol( symbol ); - - for( const auto & symbol : origGrammar.getTerminalAlphabet() ) - grammar.addTerminalSymbol( symbol ); - - std::set<alphabet::Symbol> nullableNonterminals = grammar::properties::NullableNonterminals::getNullableNonterminals(origGrammar); - - for( const auto & rule : origGrammar.getRawRules( ) ) - for(const auto & rhs : rule.second) { - if(rhs.size() == 0) continue; - - removeNullableNonterminals(grammar, nullableNonterminals, rule.first, rhs, 0, {}); - } - - if(nullableNonterminals.find(origGrammar.getInitialSymbol()) != nullableNonterminals.end()) - grammar.setGeneratesEpsilon(true); - - return grammar; -} - -grammar::EpsilonFreeCFG < > EpsilonRemover::remove(const grammar::CFG < > & origGrammar) { - return removeInternal(origGrammar); -} - auto EpsilonRemoverCFG = EpsilonRemover::RegistratorWrapper<grammar::EpsilonFreeCFG < >, grammar::CFG < > >(EpsilonRemover::remove); - -grammar::EpsilonFreeCFG < > EpsilonRemover::remove(const grammar::EpsilonFreeCFG < > & origGrammar) { - return origGrammar; -} - auto EpsilonRemoverEpsilonFreeCFG = EpsilonRemover::RegistratorWrapper<grammar::EpsilonFreeCFG < >, grammar::EpsilonFreeCFG < > >(EpsilonRemover::remove); - -grammar::CNF < > EpsilonRemover::remove(const grammar::CNF < > & origGrammar) { - return origGrammar; -} - auto EpsilonRemoverCNF = EpsilonRemover::RegistratorWrapper<grammar::CNF < >, grammar::CNF < > >(EpsilonRemover::remove); - -grammar::GNF < > EpsilonRemover::remove(const grammar::GNF < > & origGrammar) { - return origGrammar; -} - auto EpsilonRemoverGNF = EpsilonRemover::RegistratorWrapper<grammar::GNF < >, grammar::GNF < > >(EpsilonRemover::remove); - -grammar::EpsilonFreeCFG < > EpsilonRemover::remove(const grammar::LG < > & origGrammar) { - return removeInternal(origGrammar); -} - auto EpsilonRemoverLG = EpsilonRemover::RegistratorWrapper<grammar::EpsilonFreeCFG < >, grammar::LG < > >(EpsilonRemover::remove); - -grammar::EpsilonFreeCFG < > EpsilonRemover::remove(const grammar::LeftLG < > & origGrammar) { - return removeInternal(origGrammar); -} - auto EpsilonRemoverLeftLG = EpsilonRemover::RegistratorWrapper<grammar::EpsilonFreeCFG < >, grammar::LeftLG < > >(EpsilonRemover::remove); - -grammar::LeftRG < > EpsilonRemover::remove(const grammar::LeftRG < > & origGrammar) { - return origGrammar; -} - auto EpsilonRemoverLeftRG = EpsilonRemover::RegistratorWrapper<grammar::LeftRG < >, grammar::LeftRG < > >(EpsilonRemover::remove); - -grammar::EpsilonFreeCFG < > EpsilonRemover::remove(const grammar::RightLG < > & origGrammar) { - return removeInternal(origGrammar); -} - auto EpsilonRemoverRightLG = EpsilonRemover::RegistratorWrapper<grammar::EpsilonFreeCFG < >, grammar::RightLG < > >(EpsilonRemover::remove); - -grammar::RightRG < > EpsilonRemover::remove(const grammar::RightRG < > & origGrammar) { - return origGrammar; -} - auto EpsilonRemoverRightRG = EpsilonRemover::RegistratorWrapper<grammar::RightRG < >, grammar::RightRG < > >(EpsilonRemover::remove); grammar::Grammar EpsilonRemover::remove(const grammar::Grammar& grammar) { diff --git a/alib2algo/src/grammar/simplify/EpsilonRemover.h b/alib2algo/src/grammar/simplify/EpsilonRemover.h index 0dd6dfe6a4a2ebe5dae9ac704f255a122d202a24..0bdb818dcf63436ab98ff4a4632ac85da0b61776 100644 --- a/alib2algo/src/grammar/simplify/EpsilonRemover.h +++ b/alib2algo/src/grammar/simplify/EpsilonRemover.h @@ -24,25 +24,126 @@ #include <grammar/Regular/RightLG.h> #include <grammar/Regular/RightRG.h> +#include "../properties/NullableNonterminals.h" + namespace grammar { namespace simplify { class EpsilonRemover : public std::SingleDispatch<EpsilonRemover, grammar::Grammar, const grammar::GrammarBase &> { + template < class SymbolType > + static void removeNullableNonterminals(grammar::EpsilonFreeCFG < SymbolType > & grammar, const std::set<SymbolType>& nullableNonterminals, const SymbolType& lhs, const std::vector<SymbolType>& rhs, unsigned i, std::vector<SymbolType> clear); + + template<class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > > + static grammar::EpsilonFreeCFG < SymbolType > removeInternal( const T & origGrammar ); public: static grammar::Grammar remove( const grammar::Grammar & grammar ); - static grammar::EpsilonFreeCFG < > remove( const grammar::CFG < > & grammar ); - static grammar::EpsilonFreeCFG < > remove( const grammar::EpsilonFreeCFG < > & grammar ); - static grammar::GNF < > remove( const grammar::GNF < > & grammar ); - static grammar::CNF < > remove( const grammar::CNF < > & grammar ); - static grammar::EpsilonFreeCFG < > remove( const grammar::LG < > & grammar ); - static grammar::EpsilonFreeCFG < > remove( const grammar::LeftLG < > & grammar ); - static grammar::LeftRG < > remove( const grammar::LeftRG < > & grammar ); - static grammar::EpsilonFreeCFG < > remove( const grammar::RightLG < > & grammar ); - static grammar::RightRG < > remove( const grammar::RightRG < > & grammar ); + template < class SymbolType > + static grammar::EpsilonFreeCFG < SymbolType > remove( const grammar::CFG < SymbolType > & grammar ); + template < class SymbolType > + static grammar::EpsilonFreeCFG < SymbolType > remove( const grammar::EpsilonFreeCFG < SymbolType > & grammar ); + template < class SymbolType > + static grammar::GNF < SymbolType > remove( const grammar::GNF < SymbolType > & grammar ); + template < class SymbolType > + static grammar::CNF < SymbolType > remove( const grammar::CNF < SymbolType > & grammar ); + template < class SymbolType > + static grammar::EpsilonFreeCFG < SymbolType > remove( const grammar::LG < SymbolType > & grammar ); + template < class SymbolType > + static grammar::EpsilonFreeCFG < SymbolType > remove( const grammar::LeftLG < SymbolType > & grammar ); + template < class SymbolType > + static grammar::LeftRG < SymbolType > remove( const grammar::LeftRG < SymbolType > & grammar ); + template < class SymbolType > + static grammar::EpsilonFreeCFG < SymbolType > remove( const grammar::RightLG < SymbolType > & grammar ); + template < class SymbolType > + static grammar::RightRG < SymbolType > remove( const grammar::RightRG < SymbolType > & grammar ); }; +template < class SymbolType > +void EpsilonRemover::removeNullableNonterminals(grammar::EpsilonFreeCFG < SymbolType > & grammar, const std::set<SymbolType>& nullableNonterminals, const SymbolType& lhs, const std::vector<SymbolType>& rhs, unsigned i, std::vector<SymbolType> clear) { + if(rhs.size() == i) { + if(clear.size() == 0) return; + grammar.addRule(lhs, clear); + } else if(nullableNonterminals.find(rhs[i]) != nullableNonterminals.end()) { + removeNullableNonterminals(grammar, nullableNonterminals, lhs, rhs, i+1, clear); + clear.push_back(rhs[i]); + removeNullableNonterminals(grammar, nullableNonterminals, lhs, rhs, i+1, clear); + } else { + clear.push_back(rhs[i]); + removeNullableNonterminals(grammar, nullableNonterminals, lhs, rhs, i+1, clear); + } +} + +template<class T, class SymbolType > +grammar::EpsilonFreeCFG < SymbolType > EpsilonRemover::removeInternal( const T & origGrammar ) { + grammar::EpsilonFreeCFG < SymbolType > grammar(origGrammar.getInitialSymbol()); + + for( const auto & symbol : origGrammar.getNonterminalAlphabet() ) + grammar.addNonterminalSymbol( symbol ); + + for( const auto & symbol : origGrammar.getTerminalAlphabet() ) + grammar.addTerminalSymbol( symbol ); + + std::set<SymbolType> nullableNonterminals = grammar::properties::NullableNonterminals::getNullableNonterminals(origGrammar); + + for( const auto & rule : origGrammar.getRawRules( ) ) + for(const auto & rhs : rule.second) { + if(rhs.size() == 0) continue; + + EpsilonRemover::removeNullableNonterminals(grammar, nullableNonterminals, rule.first, rhs, 0, {}); + } + + if(nullableNonterminals.find(origGrammar.getInitialSymbol()) != nullableNonterminals.end()) + grammar.setGeneratesEpsilon(true); + + return grammar; +} + +template < class SymbolType > +grammar::EpsilonFreeCFG < SymbolType > EpsilonRemover::remove(const grammar::CFG < SymbolType > & origGrammar) { + return EpsilonRemover::removeInternal(origGrammar); +} + +template < class SymbolType > +grammar::EpsilonFreeCFG < SymbolType > EpsilonRemover::remove(const grammar::EpsilonFreeCFG < SymbolType > & origGrammar) { + return origGrammar; +} + +template < class SymbolType > +grammar::CNF < SymbolType > EpsilonRemover::remove(const grammar::CNF < SymbolType > & origGrammar) { + return origGrammar; +} + +template < class SymbolType > +grammar::GNF < SymbolType > EpsilonRemover::remove(const grammar::GNF < SymbolType > & origGrammar) { + return origGrammar; +} + +template < class SymbolType > +grammar::EpsilonFreeCFG < SymbolType > EpsilonRemover::remove(const grammar::LG < SymbolType > & origGrammar) { + return EpsilonRemover::removeInternal(origGrammar); +} + +template < class SymbolType > +grammar::EpsilonFreeCFG < SymbolType > EpsilonRemover::remove(const grammar::LeftLG < SymbolType > & origGrammar) { + return EpsilonRemover::removeInternal(origGrammar); +} + +template < class SymbolType > +grammar::LeftRG < SymbolType > EpsilonRemover::remove(const grammar::LeftRG < SymbolType > & origGrammar) { + return origGrammar; +} + +template < class SymbolType > +grammar::EpsilonFreeCFG < SymbolType > EpsilonRemover::remove(const grammar::RightLG < SymbolType > & origGrammar) { + return EpsilonRemover::removeInternal(origGrammar); +} + +template < class SymbolType > +grammar::RightRG < SymbolType > EpsilonRemover::remove(const grammar::RightRG < SymbolType > & origGrammar) { + return origGrammar; +} + } /* namespace simplify */ } /* namespace grammar */