diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp index 2cf3e291bfd7a7b938ea88677b6ab15c4de4de1b..b1d5e6b6cddcd857dec5af972cd90be8ddf98679 100644 --- a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp +++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp @@ -28,85 +28,20 @@ bool IsLanguageEmpty::isLanguageEmpty( const T & grammar ) { return grammar::properties::ProductiveNonterminals::getProductiveNonterminals( grammar ).count( grammar.getInitialSymbol( ) ); } -template bool IsLanguageEmpty::isLanguageEmpty( const grammar::CFG & grammar ); -template bool IsLanguageEmpty::isLanguageEmpty( const grammar::EpsilonFreeCFG & grammar ); -template bool IsLanguageEmpty::isLanguageEmpty( const grammar::GNF & grammar ); -template bool IsLanguageEmpty::isLanguageEmpty( const grammar::CNF & grammar ); -template bool IsLanguageEmpty::isLanguageEmpty( const grammar::LG & grammar ); -template bool IsLanguageEmpty::isLanguageEmpty( const grammar::LeftLG & grammar ); -template bool IsLanguageEmpty::isLanguageEmpty( const grammar::LeftRG & grammar ); -template bool IsLanguageEmpty::isLanguageEmpty( const grammar::RightLG & grammar ); -template bool IsLanguageEmpty::isLanguageEmpty( const grammar::RightRG & grammar ); +auto IsLanguageEmptyCFG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::CFG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty); +auto IsLanguageEmptyEpsilonFreeCFG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::EpsilonFreeCFG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty); +auto IsLanguageEmptyGNF = IsLanguageEmpty::RegistratorWrapper<bool, grammar::GNF>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty); +auto IsLanguageEmptyCNF = IsLanguageEmpty::RegistratorWrapper<bool, grammar::CNF>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty); +auto IsLanguageEmptyLG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::LG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty); +auto IsLanguageEmptyLeftLG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::LeftLG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty); +auto IsLanguageEmptyLeftRG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::LeftRG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty); +auto IsLanguageEmptyRightLG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::RightLG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty); +auto IsLanguageEmptyRightRG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::RightRG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty); bool IsLanguageEmpty::isLanguageEmpty(const grammar::Grammar& grammar) { - bool out; - grammar.getData().Accept((void*) &out, IsLanguageEmpty::IS_LANGUAGE_EMPTY); - return out; + return getInstance().dispatch(grammar.getData()); } -void IsLanguageEmpty::Visit(void* data, const grammar::LeftLG& grammar) const { - bool & out = *((bool*) data); - out = this->isLanguageEmpty(grammar); -} - -void IsLanguageEmpty::Visit(void* data, const grammar::LeftRG& grammar) const { - bool & out = *((bool*) data); - out = this->isLanguageEmpty(grammar); -} - -void IsLanguageEmpty::Visit(void* data, const grammar::RightLG& grammar) const { - bool & out = *((bool*) data); - out = this->isLanguageEmpty(grammar); -} - -void IsLanguageEmpty::Visit(void* data, const grammar::RightRG& grammar) const { - bool & out = *((bool*) data); - out = this->isLanguageEmpty(grammar); -} - -void IsLanguageEmpty::Visit(void* data, const grammar::LG& grammar) const { - bool & out = *((bool*) data); - out = this->isLanguageEmpty(grammar); -} - -void IsLanguageEmpty::Visit(void* data, const grammar::CFG& grammar) const { - bool & out = *((bool*) data); - out = this->isLanguageEmpty(grammar); -} - -void IsLanguageEmpty::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const { - bool & out = *((bool*) data); - out = this->isLanguageEmpty(grammar); -} - -void IsLanguageEmpty::Visit(void* data, const grammar::CNF& grammar) const { - bool & out = *((bool*) data); - out = this->isLanguageEmpty(grammar); -} - -void IsLanguageEmpty::Visit(void* data, const grammar::GNF& grammar) const { - bool & out = *((bool*) data); - out = this->isLanguageEmpty(grammar); -} - -void IsLanguageEmpty::Visit(void*, const grammar::CSG&) const { - throw exception::AlibException("Unsupported grammar type CSG"); -} - -void IsLanguageEmpty::Visit(void*, const grammar::NonContractingGrammar&) const { - throw exception::AlibException("Unsupported grammar type NonConctractingGrammar"); -} - -void IsLanguageEmpty::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const { - throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar"); -} - -void IsLanguageEmpty::Visit(void*, const grammar::UnrestrictedGrammar&) const { - throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar"); -} - -const IsLanguageEmpty IsLanguageEmpty::IS_LANGUAGE_EMPTY; - } /* namespace properties */ } /* namespace grammar */ diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.h b/alib2algo/src/grammar/properties/IsLanguageEmpty.h index 0921e4f4ad39668fcbe82a52efa7d9c512910357..02d8837bae73b5e82899cd7c5885a968506c127b 100644 --- a/alib2algo/src/grammar/properties/IsLanguageEmpty.h +++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.h @@ -8,6 +8,8 @@ #ifndef IS_LANGUAGE_EMPTY_H_ #define IS_LANGUAGE_EMPTY_H_ +#include <common/multipleDispatch.hpp> + #include <grammar/Grammar.h> namespace grammar { @@ -17,10 +19,8 @@ namespace properties { /** * Implements algorithms from Melichar, chapter 3.3 */ -class IsLanguageEmpty : public grammar::VisitableGrammarBase::const_visitor_type { +class IsLanguageEmpty : public std::SingleDispatch<bool, grammar::GrammarBase> { public: - IsLanguageEmpty() {} - static bool isLanguageEmpty( const grammar::Grammar & grammar ); /* @@ -32,22 +32,10 @@ public: template<class T> static bool isLanguageEmpty( const T & grammar ); -private: - void Visit(void*, const grammar::LeftLG& grammar) const; - void Visit(void*, const grammar::LeftRG& grammar) const; - void Visit(void*, const grammar::RightLG& grammar) const; - void Visit(void*, const grammar::RightRG& grammar) const; - void Visit(void*, const grammar::LG& grammar) const; - void Visit(void*, const grammar::CFG& grammar) const; - void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const; - void Visit(void*, const grammar::CNF& grammar) const; - void Visit(void*, const grammar::GNF& grammar) const; - void Visit(void*, const grammar::CSG& grammar) const; - void Visit(void*, const grammar::NonContractingGrammar& grammar) const; - void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const; - void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const; - - static const IsLanguageEmpty IS_LANGUAGE_EMPTY; + static IsLanguageEmpty& getInstance() { + static IsLanguageEmpty res; + return res; + } }; } /* namespace properties */ diff --git a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp index eedaab2b1c758cc67c58831d60aa604dd40bd01d..3046cfd9918ad119ee968a9687ffc1cb3e314bd2 100644 --- a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp +++ b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp @@ -28,85 +28,20 @@ bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const T & grammar return grammar::properties::NullableNonterminals::getNullableNonterminals( grammar ).count( grammar.getInitialSymbol( ) ); } -template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::CFG & grammar ); -template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::EpsilonFreeCFG & grammar ); -template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::GNF & grammar ); -template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::CNF & grammar ); -template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::LG & grammar ); -template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::LeftLG & grammar ); -template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::LeftRG & grammar ); -template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::RightLG & grammar ); -template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::RightRG & grammar ); +auto IsLanguageGeneratingEpsilonCFG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::CFG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon); +auto IsLanguageGeneratingEpsilonEpsilonFreeCFG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::EpsilonFreeCFG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon); +auto IsLanguageGeneratingEpsilonGNF = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::GNF>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon); +auto IsLanguageGeneratingEpsilonCNF = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::CNF>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon); +auto IsLanguageGeneratingEpsilonLG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::LG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon); +auto IsLanguageGeneratingEpsilonLeftLG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::LeftLG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon); +auto IsLanguageGeneratingEpsilonLeftRG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::LeftRG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon); +auto IsLanguageGeneratingEpsilonRightLG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::RightLG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon); +auto IsLanguageGeneratingEpsilonRightRG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::RightRG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon); bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon(const grammar::Grammar& grammar) { - bool out; - grammar.getData().Accept((void*) &out, IsLanguageGeneratingEpsilon::IS_LANGUAGE_GENERATING_EPSILON); - return out; + return getInstance().dispatch(grammar.getData()); } -void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::LeftLG& grammar) const { - bool & out = *((bool*) data); - out = std::move(this->isLanguageGeneratingEpsilon(grammar)); -} - -void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::LeftRG& grammar) const { - bool & out = *((bool*) data); - out = std::move(this->isLanguageGeneratingEpsilon(grammar)); -} - -void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::RightLG& grammar) const { - bool & out = *((bool*) data); - out = std::move(this->isLanguageGeneratingEpsilon(grammar)); -} - -void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::RightRG& grammar) const { - bool & out = *((bool*) data); - out = std::move(this->isLanguageGeneratingEpsilon(grammar)); -} - -void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::LG& grammar) const { - bool & out = *((bool*) data); - out = std::move(this->isLanguageGeneratingEpsilon(grammar)); -} - -void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::CFG& grammar) const { - bool & out = *((bool*) data); - out = std::move(this->isLanguageGeneratingEpsilon(grammar)); -} - -void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const { - bool & out = *((bool*) data); - out = std::move(this->isLanguageGeneratingEpsilon(grammar)); -} - -void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::CNF& grammar) const { - bool & out = *((bool*) data); - out = std::move(this->isLanguageGeneratingEpsilon(grammar)); -} - -void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::GNF& grammar) const { - bool & out = *((bool*) data); - out = std::move(this->isLanguageGeneratingEpsilon(grammar)); -} - -void IsLanguageGeneratingEpsilon::Visit(void*, const grammar::CSG&) const { - throw exception::AlibException("Unsupported grammar type CSG"); -} - -void IsLanguageGeneratingEpsilon::Visit(void*, const grammar::NonContractingGrammar&) const { - throw exception::AlibException("Unsupported grammar type NonConctractingGrammar"); -} - -void IsLanguageGeneratingEpsilon::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const { - throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar"); -} - -void IsLanguageGeneratingEpsilon::Visit(void*, const grammar::UnrestrictedGrammar&) const { - throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar"); -} - -const IsLanguageGeneratingEpsilon IsLanguageGeneratingEpsilon::IS_LANGUAGE_GENERATING_EPSILON; - } /* namespace properties */ } /* namespace grammar */ diff --git a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h index ef87b98b7c62aed9cf78fba3fedd480d2fd9e3d9..9e082a97bedc20fb207f4fb6e89a95bf85c39958 100644 --- a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h +++ b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h @@ -8,6 +8,8 @@ #ifndef IS_LANGUAGE_GENERATING_EPSILON_H_ #define IS_LANGUAGE_GENERATING_EPSILON_H_ +#include <common/multipleDispatch.hpp> + #include <grammar/Grammar.h> namespace grammar { @@ -17,10 +19,8 @@ namespace properties { /** * Implements algorithms from Melichar, chapter 3.3 */ -class IsLanguageGeneratingEpsilon : public grammar::VisitableGrammarBase::const_visitor_type { +class IsLanguageGeneratingEpsilon : public std::SingleDispatch<bool, grammar::GrammarBase> { public: - IsLanguageGeneratingEpsilon() {} - static bool isLanguageGeneratingEpsilon( const grammar::Grammar & grammar ); /* @@ -32,22 +32,10 @@ public: template<class T> static bool isLanguageGeneratingEpsilon( const T & grammar ); -private: - void Visit(void*, const grammar::LeftLG& grammar) const; - void Visit(void*, const grammar::LeftRG& grammar) const; - void Visit(void*, const grammar::RightLG& grammar) const; - void Visit(void*, const grammar::RightRG& grammar) const; - void Visit(void*, const grammar::LG& grammar) const; - void Visit(void*, const grammar::CFG& grammar) const; - void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const; - void Visit(void*, const grammar::CNF& grammar) const; - void Visit(void*, const grammar::GNF& grammar) const; - void Visit(void*, const grammar::CSG& grammar) const; - void Visit(void*, const grammar::NonContractingGrammar& grammar) const; - void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const; - void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const; - - static const IsLanguageGeneratingEpsilon IS_LANGUAGE_GENERATING_EPSILON; + static IsLanguageGeneratingEpsilon& getInstance() { + static IsLanguageGeneratingEpsilon res; + return res; + } }; } /* namespace properties */ diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp index 2534518e51fd46854e4d8d8b3e0eb0e078577fab..7f28661b296119985b50bfb8f626c737343a52f8 100644 --- a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp +++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp @@ -55,85 +55,20 @@ std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle return Ni.at(i); } -template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::CFG& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::EpsilonFreeCFG& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::GNF& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::CNF& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::LG& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::LeftLG& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::LeftRG& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::RightLG& grammar, const alphabet::Symbol& nonterminal); -template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::RightRG& grammar, const alphabet::Symbol& nonterminal); +auto NonterminalUnitRuleCycleCFG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CFG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle); +auto NonterminalUnitRuleCycleEpsilonFreeCFG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::EpsilonFreeCFG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle); +auto NonterminalUnitRuleCycleGNF = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::GNF>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle); +auto NonterminalUnitRuleCycleCNF = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle); +auto NonterminalUnitRuleCycleLG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle); +auto NonterminalUnitRuleCycleLeftLG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftLG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle); +auto NonterminalUnitRuleCycleLeftRG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftRG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle); +auto NonterminalUnitRuleCycleRightLG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightLG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle); +auto NonterminalUnitRuleCycleRightRG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightRG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle); std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::Grammar& grammar, const alphabet::Symbol& nonterminal) { - std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> out(nonterminal, {}); - grammar.getData().Accept((void*) &out, NonterminalUnitRuleCycle::NONTERMINAL_UNIT_RULE_CYCLE); - return out.second; + return getInstance().dispatch(grammar.getData(), nonterminal); } -void NonterminalUnitRuleCycle::Visit(void* data, const grammar::LeftLG& grammar) const { - std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data); - out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first)); -} - -void NonterminalUnitRuleCycle::Visit(void* data, const grammar::LeftRG& grammar) const { - std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data); - out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first)); -} - -void NonterminalUnitRuleCycle::Visit(void* data, const grammar::RightLG& grammar) const { - std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data); - out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first)); -} - -void NonterminalUnitRuleCycle::Visit(void* data, const grammar::RightRG& grammar) const { - std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data); - out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first)); -} - -void NonterminalUnitRuleCycle::Visit(void* data, const grammar::LG& grammar) const { - std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data); - out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first)); -} - -void NonterminalUnitRuleCycle::Visit(void* data, const grammar::CFG& grammar) const { - std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data); - out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first)); -} - -void NonterminalUnitRuleCycle::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const { - std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data); - out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first)); -} - -void NonterminalUnitRuleCycle::Visit(void* data, const grammar::CNF& grammar) const { - std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data); - out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first)); -} - -void NonterminalUnitRuleCycle::Visit(void* data, const grammar::GNF& grammar) const { - std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data); - out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first)); -} - -void NonterminalUnitRuleCycle::Visit(void*, const grammar::CSG&) const { - throw exception::AlibException("Unsupported grammar type CSG"); -} - -void NonterminalUnitRuleCycle::Visit(void*, const grammar::NonContractingGrammar&) const { - throw exception::AlibException("Unsupported grammar type NonConctractingGrammar"); -} - -void NonterminalUnitRuleCycle::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const { - throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar"); -} - -void NonterminalUnitRuleCycle::Visit(void*, const grammar::UnrestrictedGrammar&) const { - throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar"); -} - -const NonterminalUnitRuleCycle NonterminalUnitRuleCycle::NONTERMINAL_UNIT_RULE_CYCLE; - } /* namespace properties */ } /* namespace grammar */ diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h index c5802dc48d161c931ce41eb30249aeab7666d84b..62c9206b9467a92b3eef83a6b09a9a527c664886 100644 --- a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h +++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h @@ -8,6 +8,8 @@ #ifndef NONTERMINAL_UNIT_RULE_CYCLE_H_ #define NONTERMINAL_UNIT_RULE_CYCLE_H_ +#include <common/multipleDispatch.hpp> + #include <grammar/Grammar.h> #include <alphabet/Symbol.h> @@ -18,10 +20,8 @@ namespace properties { /** * Implements algorithms from Melichar, chapter 3.3 */ -class NonterminalUnitRuleCycle : public grammar::VisitableGrammarBase::const_visitor_type { +class NonterminalUnitRuleCycle : public std::SingleDispatchLastStaticParam<std::set<alphabet::Symbol>, grammar::GrammarBase, const alphabet::Symbol> { public: - NonterminalUnitRuleCycle() {} - static std::set<alphabet::Symbol> getNonterminalUnitRuleCycle( const grammar::Grammar & grammar, const alphabet::Symbol& nonterminal ); /** @@ -36,22 +36,10 @@ public: template<class T> static std::set<alphabet::Symbol> getNonterminalUnitRuleCycle(const T& grammar, const alphabet::Symbol& nonterminal); -private: - void Visit(void*, const grammar::LeftLG& grammar) const; - void Visit(void*, const grammar::LeftRG& grammar) const; - void Visit(void*, const grammar::RightLG& grammar) const; - void Visit(void*, const grammar::RightRG& grammar) const; - void Visit(void*, const grammar::LG& grammar) const; - void Visit(void*, const grammar::CFG& grammar) const; - void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const; - void Visit(void*, const grammar::CNF& grammar) const; - void Visit(void*, const grammar::GNF& grammar) const; - void Visit(void*, const grammar::CSG& grammar) const; - void Visit(void*, const grammar::NonContractingGrammar& grammar) const; - void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const; - void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const; - - static const NonterminalUnitRuleCycle NONTERMINAL_UNIT_RULE_CYCLE; + static NonterminalUnitRuleCycle& getInstance() { + static NonterminalUnitRuleCycle res; + return res; + } }; } /* namespace properties */ diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.cpp b/alib2algo/src/grammar/properties/NullableNonterminals.cpp index 01fcae4083386e46b28b9544531dd31cd2142115..3749bf0c4bfa00d13c4c5591f0b72a387e2f3bc2 100644 --- a/alib2algo/src/grammar/properties/NullableNonterminals.cpp +++ b/alib2algo/src/grammar/properties/NullableNonterminals.cpp @@ -51,85 +51,20 @@ std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals(const T return Ni.at(i); } -template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::CFG& grammar ); -template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::EpsilonFreeCFG& grammar ); -template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::GNF& grammar ); -template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::CNF& grammar ); -template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::LG& grammar ); -template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::LeftLG& grammar ); -template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::LeftRG& grammar ); -template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::RightLG& grammar ); -template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::RightRG& grammar ); +auto NullableNonterminalsCFG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CFG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals); +auto NullableNonterminalsEpsilonFreeCFG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::EpsilonFreeCFG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals); +auto NullableNonterminalsGNF = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::GNF>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals); +auto NullableNonterminalsCNF = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals); +auto NullableNonterminalsLG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals); +auto NullableNonterminalsLeftLG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftLG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals); +auto NullableNonterminalsLeftRG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftRG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals); +auto NullableNonterminalsRightLG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightLG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals); +auto NullableNonterminalsRightRG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightRG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals); std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals(const grammar::Grammar& grammar) { - std::set<alphabet::Symbol> out; - grammar.getData().Accept((void*) &out, NullableNonterminals::NULLABLE_NONTERMINALS); - return out; + return getInstance().dispatch(grammar.getData()); } -void NullableNonterminals::Visit(void* data, const grammar::LeftLG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getNullableNonterminals(grammar)); -} - -void NullableNonterminals::Visit(void* data, const grammar::LeftRG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getNullableNonterminals(grammar)); -} - -void NullableNonterminals::Visit(void* data, const grammar::RightLG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getNullableNonterminals(grammar)); -} - -void NullableNonterminals::Visit(void* data, const grammar::RightRG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getNullableNonterminals(grammar)); -} - -void NullableNonterminals::Visit(void* data, const grammar::LG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getNullableNonterminals(grammar)); -} - -void NullableNonterminals::Visit(void* data, const grammar::CFG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getNullableNonterminals(grammar)); -} - -void NullableNonterminals::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getNullableNonterminals(grammar)); -} - -void NullableNonterminals::Visit(void* data, const grammar::CNF& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getNullableNonterminals(grammar)); -} - -void NullableNonterminals::Visit(void* data, const grammar::GNF& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getNullableNonterminals(grammar)); -} - -void NullableNonterminals::Visit(void*, const grammar::CSG&) const { - throw exception::AlibException("Unsupported grammar type CSG"); -} - -void NullableNonterminals::Visit(void*, const grammar::NonContractingGrammar&) const { - throw exception::AlibException("Unsupported grammar type NonConctractingGrammar"); -} - -void NullableNonterminals::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const { - throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar"); -} - -void NullableNonterminals::Visit(void*, const grammar::UnrestrictedGrammar&) const { - throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar"); -} - -const NullableNonterminals NullableNonterminals::NULLABLE_NONTERMINALS; - } /* namespace properties */ } /* namespace grammar */ diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.h b/alib2algo/src/grammar/properties/NullableNonterminals.h index 85e47beb5409b8815fa14f9b6309d9d0c47fbe66..dc67ac96b5ff5026ee948dd14c3445a12b9bf6e6 100644 --- a/alib2algo/src/grammar/properties/NullableNonterminals.h +++ b/alib2algo/src/grammar/properties/NullableNonterminals.h @@ -8,6 +8,8 @@ #ifndef NULLABLE_NONTERMINALS_H_ #define NULLABLE_NONTERMINALS_H_ +#include <common/multipleDispatch.hpp> + #include <grammar/Grammar.h> #include <alphabet/Symbol.h> @@ -18,10 +20,8 @@ namespace properties { /** * Implements algorithms from Melichar, chapter 3.3 */ -class NullableNonterminals : public grammar::VisitableGrammarBase::const_visitor_type { +class NullableNonterminals : public std::SingleDispatch<std::set<alphabet::Symbol>, grammar::GrammarBase> { public: - NullableNonterminals() {} - static std::set<alphabet::Symbol> getNullableNonterminals( const grammar::Grammar & grammar ); /** @@ -36,22 +36,10 @@ public: template<class T> static std::set<alphabet::Symbol> getNullableNonterminals(const T& grammar); -private: - void Visit(void*, const grammar::LeftLG& grammar) const; - void Visit(void*, const grammar::LeftRG& grammar) const; - void Visit(void*, const grammar::RightLG& grammar) const; - void Visit(void*, const grammar::RightRG& grammar) const; - void Visit(void*, const grammar::LG& grammar) const; - void Visit(void*, const grammar::CFG& grammar) const; - void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const; - void Visit(void*, const grammar::CNF& grammar) const; - void Visit(void*, const grammar::GNF& grammar) const; - void Visit(void*, const grammar::CSG& grammar) const; - void Visit(void*, const grammar::NonContractingGrammar& grammar) const; - void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const; - void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const; - - static const NullableNonterminals NULLABLE_NONTERMINALS; + static NullableNonterminals& getInstance() { + static NullableNonterminals res; + return res; + } }; } /* namespace properties */ diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp index 6b6757ce3a2f70e509ac9fc04809778e68259995..e32f023dc1b882b5deabcda7f85509c20e7f4b14 100644 --- a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp +++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp @@ -56,85 +56,20 @@ std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( co return Ni.at( i ); } -template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::CFG & grammar ); -template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::EpsilonFreeCFG & grammar ); -template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::GNF & grammar ); -template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::CNF & grammar ); -template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::LG & grammar ); -template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::LeftLG & grammar ); -template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::LeftRG & grammar ); -template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::RightLG & grammar ); -template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::RightRG & grammar ); +auto ProductiveNonterminalsCFG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CFG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals); +auto ProductiveNonterminalsEpsilonFreeCFG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::EpsilonFreeCFG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals); +auto ProductiveNonterminalsGNF = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::GNF>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals); +auto ProductiveNonterminalsCNF = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals); +auto ProductiveNonterminalsLG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals); +auto ProductiveNonterminalsLeftLG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftLG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals); +auto ProductiveNonterminalsLeftRG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftRG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals); +auto ProductiveNonterminalsRightLG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightLG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals); +auto ProductiveNonterminalsRightRG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightRG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals); std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals(const grammar::Grammar& grammar) { - std::set<alphabet::Symbol> out; - grammar.getData().Accept((void*) &out, ProductiveNonterminals::PRODUCTIVE_NONTERMINALS); - return out; + return getInstance().dispatch(grammar.getData()); } -void ProductiveNonterminals::Visit(void* data, const grammar::LeftLG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getProductiveNonterminals(grammar)); -} - -void ProductiveNonterminals::Visit(void* data, const grammar::LeftRG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getProductiveNonterminals(grammar)); -} - -void ProductiveNonterminals::Visit(void* data, const grammar::RightLG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getProductiveNonterminals(grammar)); -} - -void ProductiveNonterminals::Visit(void* data, const grammar::RightRG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getProductiveNonterminals(grammar)); -} - -void ProductiveNonterminals::Visit(void* data, const grammar::LG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getProductiveNonterminals(grammar)); -} - -void ProductiveNonterminals::Visit(void* data, const grammar::CFG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getProductiveNonterminals(grammar)); -} - -void ProductiveNonterminals::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getProductiveNonterminals(grammar)); -} - -void ProductiveNonterminals::Visit(void* data, const grammar::CNF& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getProductiveNonterminals(grammar)); -} - -void ProductiveNonterminals::Visit(void* data, const grammar::GNF& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getProductiveNonterminals(grammar)); -} - -void ProductiveNonterminals::Visit(void*, const grammar::CSG&) const { - throw exception::AlibException("Unsupported grammar type CSG"); -} - -void ProductiveNonterminals::Visit(void*, const grammar::NonContractingGrammar&) const { - throw exception::AlibException("Unsupported grammar type NonConctractingGrammar"); -} - -void ProductiveNonterminals::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const { - throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar"); -} - -void ProductiveNonterminals::Visit(void*, const grammar::UnrestrictedGrammar&) const { - throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar"); -} - -const ProductiveNonterminals ProductiveNonterminals::PRODUCTIVE_NONTERMINALS; - } /* namespace properties */ } /* namespace grammar */ diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.h b/alib2algo/src/grammar/properties/ProductiveNonterminals.h index 688c011f06e17e8d57c2406081ce95ee50adb66b..0b88d4144d35a227811e986e4da356509bd4e8f0 100644 --- a/alib2algo/src/grammar/properties/ProductiveNonterminals.h +++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.h @@ -8,6 +8,8 @@ #ifndef PRODUCTIVE_NONTERMINALS_H_ #define PRODUCTIVE_NONTERMINALS_H_ +#include <common/multipleDispatch.hpp> + #include <grammar/Grammar.h> #include <alphabet/Symbol.h> @@ -18,10 +20,8 @@ namespace properties { /** * Implements algorithms from Melichar, chapter 3.3 */ -class ProductiveNonterminals : public grammar::VisitableGrammarBase::const_visitor_type { +class ProductiveNonterminals : public std::SingleDispatch<std::set<alphabet::Symbol>, grammar::GrammarBase> { public: - ProductiveNonterminals() {} - static std::set<alphabet::Symbol> getProductiveNonterminals( const grammar::Grammar & grammar ); /** @@ -30,22 +30,10 @@ public: template<class T> static std::set<alphabet::Symbol> getProductiveNonterminals( const T & grammar ); -private: - void Visit(void*, const grammar::LeftLG& grammar) const; - void Visit(void*, const grammar::LeftRG& grammar) const; - void Visit(void*, const grammar::RightLG& grammar) const; - void Visit(void*, const grammar::RightRG& grammar) const; - void Visit(void*, const grammar::LG& grammar) const; - void Visit(void*, const grammar::CFG& grammar) const; - void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const; - void Visit(void*, const grammar::CNF& grammar) const; - void Visit(void*, const grammar::GNF& grammar) const; - void Visit(void*, const grammar::CSG& grammar) const; - void Visit(void*, const grammar::NonContractingGrammar& grammar) const; - void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const; - void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const; - - static const ProductiveNonterminals PRODUCTIVE_NONTERMINALS; + static ProductiveNonterminals& getInstance() { + static ProductiveNonterminals res; + return res; + } }; } /* namespace properties */ diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.cpp b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp index 3c0d9bfd63326ce50e3e444b28be11bc8d57601a..3f83b5dd7fd5a15f1f928578e55583507814fcfe 100644 --- a/alib2algo/src/grammar/properties/UnreachableSymbols.cpp +++ b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp @@ -57,85 +57,20 @@ std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const T & return Vi.at( i ); } -template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::CFG & grammar ); -template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::EpsilonFreeCFG & grammar ); -template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::GNF & grammar ); -template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::CNF & grammar ); -template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::LG & grammar ); -template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::LeftLG & grammar ); -template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::LeftRG & grammar ); -template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::RightLG & grammar ); -template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::RightRG & grammar ); +auto UnreachableSymbolsCFG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CFG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols); +auto UnreachableSymbolsEpsilonFreeCFG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::EpsilonFreeCFG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols); +auto UnreachableSymbolsGNF = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::GNF>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols); +auto UnreachableSymbolsCNF = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols); +auto UnreachableSymbolsLG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols); +auto UnreachableSymbolsLeftLG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftLG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols); +auto UnreachableSymbolsLeftRG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftRG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols); +auto UnreachableSymbolsRightLG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightLG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols); +auto UnreachableSymbolsRightRG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightRG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols); std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols(const grammar::Grammar& grammar) { - std::set<alphabet::Symbol> out; - grammar.getData().Accept((void*) &out, UnreachableSymbols::UNREACHABLE_NONTERMINALS); - return out; + return getInstance().dispatch(grammar.getData()); } -void UnreachableSymbols::Visit(void* data, const grammar::LeftLG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getUnreachableSymbols(grammar)); -} - -void UnreachableSymbols::Visit(void* data, const grammar::LeftRG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getUnreachableSymbols(grammar)); -} - -void UnreachableSymbols::Visit(void* data, const grammar::RightLG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getUnreachableSymbols(grammar)); -} - -void UnreachableSymbols::Visit(void* data, const grammar::RightRG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getUnreachableSymbols(grammar)); -} - -void UnreachableSymbols::Visit(void* data, const grammar::LG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getUnreachableSymbols(grammar)); -} - -void UnreachableSymbols::Visit(void* data, const grammar::CFG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getUnreachableSymbols(grammar)); -} - -void UnreachableSymbols::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getUnreachableSymbols(grammar)); -} - -void UnreachableSymbols::Visit(void* data, const grammar::CNF& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getUnreachableSymbols(grammar)); -} - -void UnreachableSymbols::Visit(void* data, const grammar::GNF& grammar) const { - std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data); - out = std::move(this->getUnreachableSymbols(grammar)); -} - -void UnreachableSymbols::Visit(void*, const grammar::CSG&) const { - throw exception::AlibException("Unsupported grammar type CSG"); -} - -void UnreachableSymbols::Visit(void*, const grammar::NonContractingGrammar&) const { - throw exception::AlibException("Unsupported grammar type NonConctractingGrammar"); -} - -void UnreachableSymbols::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const { - throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar"); -} - -void UnreachableSymbols::Visit(void*, const grammar::UnrestrictedGrammar&) const { - throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar"); -} - -const UnreachableSymbols UnreachableSymbols::UNREACHABLE_NONTERMINALS; - } /* namespace properties */ } /* namespace grammar */ diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.h b/alib2algo/src/grammar/properties/UnreachableSymbols.h index a77f3421e29c259b977002c11cbaf3631736b7c5..c25efea00914da8b6c03f7512dc20a5b7946a6d3 100644 --- a/alib2algo/src/grammar/properties/UnreachableSymbols.h +++ b/alib2algo/src/grammar/properties/UnreachableSymbols.h @@ -8,6 +8,8 @@ #ifndef UNREACHABLE_SYMBOLS_H_ #define UNREACHABLE_SYMBOLS_H_ +#include <common/multipleDispatch.hpp> + #include <grammar/Grammar.h> #include <alphabet/Symbol.h> @@ -18,10 +20,8 @@ namespace properties { /** * Implements algorithms from Melichar, chapter 3.3 */ -class UnreachableSymbols : public grammar::VisitableGrammarBase::const_visitor_type { +class UnreachableSymbols : public std::SingleDispatch<std::set<alphabet::Symbol>, grammar::GrammarBase> { public: - UnreachableSymbols() {} - static std::set<alphabet::Symbol> getUnreachableSymbols( const grammar::Grammar & grammar ); /** @@ -30,22 +30,10 @@ public: template<class T> static std::set<alphabet::Symbol> getUnreachableSymbols( const T & grammar ); -private: - void Visit(void*, const grammar::LeftLG& grammar) const; - void Visit(void*, const grammar::LeftRG& grammar) const; - void Visit(void*, const grammar::RightLG& grammar) const; - void Visit(void*, const grammar::RightRG& grammar) const; - void Visit(void*, const grammar::LG& grammar) const; - void Visit(void*, const grammar::CFG& grammar) const; - void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const; - void Visit(void*, const grammar::CNF& grammar) const; - void Visit(void*, const grammar::GNF& grammar) const; - void Visit(void*, const grammar::CSG& grammar) const; - void Visit(void*, const grammar::NonContractingGrammar& grammar) const; - void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const; - void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const; - - static const UnreachableSymbols UNREACHABLE_NONTERMINALS; + static UnreachableSymbols& getInstance() { + static UnreachableSymbols res; + return res; + } }; } /* namespace properties */ diff --git a/alib2algo/src/regexp/properties/RegExpEpsilon.h b/alib2algo/src/regexp/properties/RegExpEpsilon.h index 887a42c16b7f61a457cd49f588b246def89e683b..f0cdaaf0945d3f08e9abd8f863e76e7548663357 100644 --- a/alib2algo/src/regexp/properties/RegExpEpsilon.h +++ b/alib2algo/src/regexp/properties/RegExpEpsilon.h @@ -22,8 +22,7 @@ namespace properties { * Checks, whether regexp (or its subtree) describes epsilon (empty string). * */ -class RegExpEpsilon : public std::SingleDispatch<bool, regexp::RegExpBase>, regexp::FormalRegExpElement::const_visitor_type, regexp::UnboundedRegExpElement::const_visitor_type -{ +class RegExpEpsilon : public std::SingleDispatch<bool, regexp::RegExpBase>, regexp::FormalRegExpElement::const_visitor_type, regexp::UnboundedRegExpElement::const_visitor_type { public: RegExpEpsilon() {}