diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp index 2a4fbdd79ae93ac25e67a69d80638b49bb8cb4a7..e969139dfc647d684391d29fbffd7dd29877c94a 100644 --- a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp +++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp @@ -18,6 +18,7 @@ #include <grammar/Regular/RightRG.h> #include <std/set.hpp> +#include <deque> namespace grammar { @@ -64,6 +65,75 @@ template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnit 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); +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; +} + +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 2bfd991526c5a8844ff84ce607e69e3aac43f4e4..0d64caae300889f7eefd27750d41009026a61521 100644 --- a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h +++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h @@ -8,12 +8,7 @@ #ifndef NONTERMINAL_UNIT_RULE_CYCLE_H_ #define NONTERMINAL_UNIT_RULE_CYCLE_H_ -#include <algorithm> -#include <deque> -#include <set> - -#include <exception/AlibException.h> - +#include <grammar/Grammar.h> #include <alphabet/Symbol.h> namespace grammar { @@ -23,8 +18,10 @@ namespace properties { /** * Implements algorithms from Melichar, chapter 3.3 */ -class NonterminalUnitRuleCycle { +class NonterminalUnitRuleCycle : public grammar::VisitableGrammarBase::const_visitor_type { public: + static std::set<alphabet::Symbol> getNonterminalUnitRuleCycle( const grammar::Grammar & grammar, const alphabet::Symbol& nonterminal ); + /** * Retrieves set N = {B : A->^* B} for given grammar and nonterminal * @@ -36,6 +33,23 @@ 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; }; } /* namespace properties */