From 71e67ea2bc8b985a6361ce5ea27f363eeb26ead1 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Sat, 15 Aug 2015 13:21:54 +0200 Subject: [PATCH] continue with grammar properties --- .../grammar/properties/IsLanguageEmpty.cpp | 85 +++---------------- .../src/grammar/properties/IsLanguageEmpty.h | 26 ++---- .../IsLanguageGeneratingEpsilon.cpp | 85 +++---------------- .../properties/IsLanguageGeneratingEpsilon.h | 26 ++---- .../properties/NonterminalUnitRuleCycle.cpp | 85 +++---------------- .../properties/NonterminalUnitRuleCycle.h | 26 ++---- .../properties/NullableNonterminals.cpp | 85 +++---------------- .../grammar/properties/NullableNonterminals.h | 26 ++---- .../properties/ProductiveNonterminals.cpp | 85 +++---------------- .../properties/ProductiveNonterminals.h | 26 ++---- .../grammar/properties/UnreachableSymbols.cpp | 85 +++---------------- .../grammar/properties/UnreachableSymbols.h | 26 ++---- .../src/regexp/properties/RegExpEpsilon.h | 3 +- 13 files changed, 103 insertions(+), 566 deletions(-) diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp index 2cf3e291bf..b1d5e6b6cd 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 0921e4f4ad..02d8837bae 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 eedaab2b1c..3046cfd991 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 ef87b98b7c..9e082a97be 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 2534518e51..7f28661b29 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 c5802dc48d..62c9206b94 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 01fcae4083..3749bf0c4b 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 85e47beb54..dc67ac96b5 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 6b6757ce3a..e32f023dc1 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 688c011f06..0b88d4144d 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 3c0d9bfd63..3f83b5dd7f 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 a77f3421e2..c25efea009 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 887a42c16b..f0cdaaf094 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() {} -- GitLab