diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.cpp b/alib2algo/src/grammar/properties/NullableNonterminals.cpp index f61bf0b691d641f468f5861ca8199e85089be365..01fcae4083386e46b28b9544531dd31cd2142115 100644 --- a/alib2algo/src/grammar/properties/NullableNonterminals.cpp +++ b/alib2algo/src/grammar/properties/NullableNonterminals.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 { @@ -59,6 +61,75 @@ template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminal template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::RightLG& grammar ); template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::RightRG& grammar ); +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; +} + +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 c80c3b9bf83f4b43dd8db91c5cdd6759dd71d623..7c55b69614fd15bc9002ef6592bf82d92d2c6a27 100644 --- a/alib2algo/src/grammar/properties/NullableNonterminals.h +++ b/alib2algo/src/grammar/properties/NullableNonterminals.h @@ -8,12 +8,7 @@ #ifndef NULLABLE_NONTERMINALS_H_ #define NULLABLE_NONTERMINALS_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 NullableNonterminals { +class NullableNonterminals : public grammar::VisitableGrammarBase::const_visitor_type { public: + static std::set<alphabet::Symbol> getNullableNonterminals( const grammar::Grammar & grammar ); + /** * Retrieve all nullable nonterminals from grammar * Nullable nonterminal is such nonterminal A for which holds that A ->^* \eps @@ -36,6 +33,23 @@ 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; }; } /* namespace properties */