diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp index 63e33cdb9ef352382d9daf3cb97737565d2c28c9..6b6757ce3a2f70e509ac9fc04809778e68259995 100644 --- a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp +++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp @@ -17,7 +17,9 @@ #include <grammar/Regular/RightLG.h> #include <grammar/Regular/RightRG.h> -#include <std/set.hpp> +#include <set> +#include <deque> +#include <algorithm> namespace grammar { @@ -64,6 +66,75 @@ template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterm template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::RightLG & grammar ); template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::RightRG & grammar ); +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; +} + +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 6139ad94085beb92027ab12dc8d84c4c4c1cca0a..317b51cd280cdb92cc57d79013c63c128aba2db1 100644 --- a/alib2algo/src/grammar/properties/ProductiveNonterminals.h +++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.h @@ -8,12 +8,7 @@ #ifndef PRODUCTIVE_NONTERMINALS_H_ #define PRODUCTIVE_NONTERMINALS_H_ -#include <algorithm> -#include <deque> -#include <set> - -#include <exception/AlibException.h> - +#include <grammar/Grammar.h> #include <alphabet/Symbol.h> namespace grammar { @@ -23,14 +18,32 @@ namespace properties { /** * Implements algorithms from Melichar, chapter 3.3 */ -class ProductiveNonterminals { +class ProductiveNonterminals : public grammar::VisitableGrammarBase::const_visitor_type { public: + static std::set<alphabet::Symbol> getProductiveNonterminals( const grammar::Grammar & grammar ); + /** * Implements steps 1 through 3 in Melichar 3.6 */ 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; }; } /* namespace properties */