From b0d97d1408f57a483fe4a20ca6e209a36f9e8fe8 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Wed, 22 Oct 2014 18:38:52 +0200 Subject: [PATCH] unify default convertors --- alib2algo/src/automaton/convert/ToGrammar.cpp | 94 +++++++ alib2algo/src/automaton/convert/ToGrammar.h | 55 +++++ alib2algo/src/automaton/convert/ToRegExp.cpp | 98 ++++++++ alib2algo/src/automaton/convert/ToRegExp.h | 56 +++++ alib2algo/src/grammar/convert/ToAutomaton.cpp | 232 ++++++++++-------- alib2algo/src/grammar/convert/ToAutomaton.h | 46 ++-- alib2algo/src/grammar/convert/ToRegExp.cpp | 87 +++++++ alib2algo/src/grammar/convert/ToRegExp.h | 52 ++++ alib2algo/src/regexp/convert/ToAutomaton.cpp | 40 +++ alib2algo/src/regexp/convert/ToAutomaton.h | 42 ++++ .../regexp/convert/ToAutomatonGlushkov.cpp | 5 + alib2algo/src/regexp/convert/ToGrammar.cpp | 41 ++++ alib2algo/src/regexp/convert/ToGrammar.h | 38 +++ .../convert/ToGrammarRightRGDerivation.cpp | 2 +- .../convert/ToGrammarRightRGGlushkov.cpp | 3 + 15 files changed, 773 insertions(+), 118 deletions(-) create mode 100644 alib2algo/src/automaton/convert/ToGrammar.cpp create mode 100644 alib2algo/src/automaton/convert/ToGrammar.h create mode 100644 alib2algo/src/automaton/convert/ToRegExp.cpp create mode 100644 alib2algo/src/automaton/convert/ToRegExp.h create mode 100644 alib2algo/src/grammar/convert/ToRegExp.cpp create mode 100644 alib2algo/src/grammar/convert/ToRegExp.h create mode 100644 alib2algo/src/regexp/convert/ToAutomaton.cpp create mode 100644 alib2algo/src/regexp/convert/ToAutomaton.h create mode 100644 alib2algo/src/regexp/convert/ToGrammar.cpp create mode 100644 alib2algo/src/regexp/convert/ToGrammar.h diff --git a/alib2algo/src/automaton/convert/ToGrammar.cpp b/alib2algo/src/automaton/convert/ToGrammar.cpp new file mode 100644 index 0000000000..14c933d7fe --- /dev/null +++ b/alib2algo/src/automaton/convert/ToGrammar.cpp @@ -0,0 +1,94 @@ +/* + * ToGrammarLeftRG.h + * + * Created on: 9. 2. 2014 + * Author: ToGrammarmas Pecka + */ + +#include "ToGrammar.h" +#include "ToGrammarRightRG.h" +#include <exception/AlibException.h> + +namespace automaton { + +namespace convert { + +grammar::Grammar ToGrammar::convert(const automaton::Automaton& automaton) { + grammar::Grammar* out = NULL; + automaton.getData().Accept((void*) &out, ToGrammar::TO_GRAMMAR); + grammar::Grammar res = std::move(*out); + delete out; + return res; +} + +void ToGrammar::Visit(void*, const automaton::EpsilonNFA& ) const { + throw exception::AlibException("Unsupported automaton type EpsilonNFA"); +} + +void ToGrammar::Visit(void*, const automaton::MultiInitialStateNFA& ) const { + throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); +} + +void ToGrammar::Visit(void* data, const automaton::NFA& automaton) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(ToGrammarRightRG::convert(automaton)); +} + +void ToGrammar::Visit(void* data, const automaton::DFA& automaton) const { + grammar::Grammar* & out = *((grammar::Grammar**) data); + out = new grammar::Grammar(ToGrammarRightRG::convert(automaton)); +} + +void ToGrammar::Visit(void*, const automaton::ExtendedNFA& ) const { + throw exception::AlibException("Unsupported automaton type ExtendedNFA"); +} + +void ToGrammar::Visit(void*, const automaton::CompactNFA& ) const { + throw exception::AlibException("Unsupported automaton type CompactNFA"); +} + +void ToGrammar::Visit(void*, const DPDA&) const { + throw exception::AlibException("Unsupported automaton type DPDA"); +} + +void ToGrammar::Visit(void*, const SinglePopDPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); +} + +void ToGrammar::Visit(void*, const InputDrivenNPDA&) const { + throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); +} + +void ToGrammar::Visit(void*, const VisiblyPushdownDPDA&) const { + throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); +} + +void ToGrammar::Visit(void*, const VisiblyPushdownNPDA&) const { + throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); +} + +void ToGrammar::Visit(void*, const RealTimeHeightDeterministicDPDA&) const { + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); +} + +void ToGrammar::Visit(void*, const RealTimeHeightDeterministicNPDA&) const { + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); +} + +void ToGrammar::Visit(void*, const NPDA&) const { + throw exception::AlibException("Unsupported automaton type NPDA"); +} + +void ToGrammar::Visit(void*, const SinglePopNPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +} + +void ToGrammar::Visit(void*, const OneTapeDTM&) const { + throw exception::AlibException("Unsupported automaton type OneTapeDTM"); +} + +const ToGrammar ToGrammar::TO_GRAMMAR; + +} /* namespace convert */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/convert/ToGrammar.h b/alib2algo/src/automaton/convert/ToGrammar.h new file mode 100644 index 0000000000..5a25ba02cb --- /dev/null +++ b/alib2algo/src/automaton/convert/ToGrammar.h @@ -0,0 +1,55 @@ +/* + * ToGrammar.h + * + * Created on: 9. 2. 2014 + * Author: Jan Travnicek + */ + +#ifndef _AUTOMATON_TO_GRAMMAR_H__ +#define _AUTOMATON_TO_GRAMMAR_H__ + +#include <grammar/Regular/LeftRG.h> +#include <automaton/FSM/NFA.h> +#include <automaton/FSM/DFA.h> + +#include <grammar/Grammar.h> +#include <automaton/Automaton.h> + +namespace automaton { + +namespace convert { + +class ToGrammar : public automaton::VisitableAutomatonBase::const_visitor_type { +public: + /** + * Performs conversion. + * @return left regular grammar equivalent to source automaton. + */ + static grammar::Grammar convert(const automaton::Automaton& automaton); + +private: + void Visit(void*, const EpsilonNFA& automaton) const; + void Visit(void*, const MultiInitialStateNFA& automaton) const; + void Visit(void*, const NFA& automaton) const; + void Visit(void*, const DFA& automaton) const; + void Visit(void*, const ExtendedNFA& automaton) const; + void Visit(void*, const CompactNFA& automaton) const; + void Visit(void*, const DPDA& automaton) const; + void Visit(void*, const SinglePopDPDA& automaton) const; + void Visit(void*, const InputDrivenNPDA& automaton) const; + void Visit(void*, const VisiblyPushdownDPDA& automaton) const; + void Visit(void*, const VisiblyPushdownNPDA& automaton) const; + void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const; + void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const; + void Visit(void*, const NPDA& automaton) const; + void Visit(void*, const SinglePopNPDA& automaton) const; + void Visit(void*, const OneTapeDTM& automaton) const; + + static const ToGrammar TO_GRAMMAR; +}; + +} /* namespace convert */ + +} /* namespace automaton */ + +#endif /* _AUTOMATON_TO_GRAMMAR_H__ */ diff --git a/alib2algo/src/automaton/convert/ToRegExp.cpp b/alib2algo/src/automaton/convert/ToRegExp.cpp new file mode 100644 index 0000000000..f3aed4a1eb --- /dev/null +++ b/alib2algo/src/automaton/convert/ToRegExp.cpp @@ -0,0 +1,98 @@ +/* + * ToRegExpLeftRG.h + * + * Created on: 9. 2. 2014 + * Author: ToRegExpmas Pecka + */ + +#include "ToRegExp.h" +#include "ToRegExpStateElimination.h" +#include <exception/AlibException.h> + +namespace automaton { + +namespace convert { + +regexp::RegExp ToRegExp::convert(const automaton::Automaton& automaton) { + regexp::RegExp* out = NULL; + automaton.getData().Accept((void*) &out, ToRegExp::TO_REGEXP); + regexp::RegExp res = std::move(*out); + delete out; + return res; +} + +void ToRegExp::Visit(void* data, const automaton::EpsilonNFA& automaton) const { + regexp::RegExp* & out = *((regexp::RegExp**) data); + out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton)); +} + +void ToRegExp::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const { + regexp::RegExp* & out = *((regexp::RegExp**) data); + out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton)); +} + +void ToRegExp::Visit(void* data, const automaton::NFA& automaton) const { + regexp::RegExp* & out = *((regexp::RegExp**) data); + out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton)); +} + +void ToRegExp::Visit(void* data, const automaton::DFA& automaton) const { + regexp::RegExp* & out = *((regexp::RegExp**) data); + out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton)); +} + +void ToRegExp::Visit(void* data, const automaton::ExtendedNFA& automaton) const { + regexp::RegExp* & out = *((regexp::RegExp**) data); + out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton)); +} + +void ToRegExp::Visit(void* data, const automaton::CompactNFA& automaton) const { + regexp::RegExp* & out = *((regexp::RegExp**) data); + out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton)); +} + +void ToRegExp::Visit(void*, const DPDA&) const { + throw exception::AlibException("Unsupported automaton type DPDA"); +} + +void ToRegExp::Visit(void*, const SinglePopDPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); +} + +void ToRegExp::Visit(void*, const InputDrivenNPDA&) const { + throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); +} + +void ToRegExp::Visit(void*, const VisiblyPushdownDPDA&) const { + throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); +} + +void ToRegExp::Visit(void*, const VisiblyPushdownNPDA&) const { + throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); +} + +void ToRegExp::Visit(void*, const RealTimeHeightDeterministicDPDA&) const { + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); +} + +void ToRegExp::Visit(void*, const RealTimeHeightDeterministicNPDA&) const { + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); +} + +void ToRegExp::Visit(void*, const NPDA&) const { + throw exception::AlibException("Unsupported automaton type NPDA"); +} + +void ToRegExp::Visit(void*, const SinglePopNPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +} + +void ToRegExp::Visit(void*, const OneTapeDTM&) const { + throw exception::AlibException("Unsupported automaton type OneTapeDTM"); +} + +const ToRegExp ToRegExp::TO_REGEXP; + +} /* namespace convert */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/convert/ToRegExp.h b/alib2algo/src/automaton/convert/ToRegExp.h new file mode 100644 index 0000000000..b525181950 --- /dev/null +++ b/alib2algo/src/automaton/convert/ToRegExp.h @@ -0,0 +1,56 @@ +/* + * ToRegExp.h + * + * Created on: 9. 2. 2014 + * Author: Jan Travnicek + */ + +#ifndef _AUTOMATON_TO_REGEXP_H__ +#define _AUTOMATON_TO_REGEXP_H__ + +#include <automaton/FSM/DFA.h> +#include <automaton/FSM/NFA.h> +#include <automaton/FSM/EpsilonNFA.h> +#include <regexp/unbounded/UnboundedRegExp.h> + +#include <automaton/Automaton.h> +#include <regexp/RegExp.h> + +namespace automaton { + +namespace convert { + +class ToRegExp : public automaton::VisitableAutomatonBase::const_visitor_type { +public: + /** + * Performs conversion. + * @return left regular grammar equivalent to source automaton. + */ + static regexp::RegExp convert(const automaton::Automaton& automaton); + +private: + void Visit(void*, const EpsilonNFA& automaton) const; + void Visit(void*, const MultiInitialStateNFA& automaton) const; + void Visit(void*, const NFA& automaton) const; + void Visit(void*, const DFA& automaton) const; + void Visit(void*, const ExtendedNFA& automaton) const; + void Visit(void*, const CompactNFA& automaton) const; + void Visit(void*, const DPDA& automaton) const; + void Visit(void*, const SinglePopDPDA& automaton) const; + void Visit(void*, const InputDrivenNPDA& automaton) const; + void Visit(void*, const VisiblyPushdownDPDA& automaton) const; + void Visit(void*, const VisiblyPushdownNPDA& automaton) const; + void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const; + void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const; + void Visit(void*, const NPDA& automaton) const; + void Visit(void*, const SinglePopNPDA& automaton) const; + void Visit(void*, const OneTapeDTM& automaton) const; + + static const ToRegExp TO_REGEXP; +}; + +} /* namespace convert */ + +} /* namespace automaton */ + +#endif /* _AUTOMATON_TO_REGEXP_H__ */ diff --git a/alib2algo/src/grammar/convert/ToAutomaton.cpp b/alib2algo/src/grammar/convert/ToAutomaton.cpp index e7c6938db3..68a1e5ca47 100644 --- a/alib2algo/src/grammar/convert/ToAutomaton.cpp +++ b/alib2algo/src/grammar/convert/ToAutomaton.cpp @@ -15,128 +15,164 @@ namespace convert { automaton::Automaton ToAutomaton::convert(const grammar::Grammar& grammar) { - automaton::Automaton* out = NULL; - grammar.getData().Accept((void*) &out, ToAutomaton::TO_AUTOMATON); - automaton::Automaton res = std::move(*out); - delete out; - return res; + automaton::Automaton* out = NULL; + grammar.getData().Accept((void*) &out, ToAutomaton::TO_AUTOMATON); + automaton::Automaton res = std::move(*out); + delete out; + return res; } automaton::NFA ToAutomaton::convert(const grammar::LeftRG& grammar) { - std::map<alphabet::Symbol, automaton::State> stateMap; - std::set<automaton::State> states; - - // step 2 - for(const auto& symbol : grammar.getNonterminalAlphabet()) - { - automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel()); - states.insert(state); - stateMap.insert(std::make_pair(symbol, state)); - } - - // step 1, 4 - const automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), states); - states.insert(q0); - automaton::NFA automaton(q0); - automaton.setInputSymbols(grammar.getTerminalAlphabet()); - automaton.setStates(states); - - // step 3 - for(const auto& rule : grammar.getRules()) - { - const alphabet::Symbol& lhs = rule.first; - for(const auto& ruleRHS : rule.second) - { - if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->Ca => \delta(C,a)=B - { - const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>(); - automaton.addTransition(stateMap.find(rhs.first)->second, rhs.second, stateMap.find(lhs)->second); - } - else // if B->a => \delta(StartState,a)=B - { - const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>(); - automaton.addTransition(q0, rhs, stateMap.find(lhs)->second); - } - } - } - - // step 5 - automaton.addFinalState(stateMap.find(grammar.getInitialSymbol())->second); - if(grammar.getGeneratesEpsilon()) - automaton.addFinalState(q0); - - return automaton; + std::map<alphabet::Symbol, automaton::State> stateMap; + std::set<automaton::State> states; + + // step 2 + for(const auto& symbol : grammar.getNonterminalAlphabet()) + { + automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel()); + states.insert(state); + stateMap.insert(std::make_pair(symbol, state)); + } + + // step 1, 4 + const automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), states); + states.insert(q0); + automaton::NFA automaton(q0); + automaton.setInputSymbols(grammar.getTerminalAlphabet()); + automaton.setStates(states); + + // step 3 + for(const auto& rule : grammar.getRules()) + { + const alphabet::Symbol& lhs = rule.first; + for(const auto& ruleRHS : rule.second) + { + if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->Ca => \delta(C,a)=B + { + const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>(); + automaton.addTransition(stateMap.find(rhs.first)->second, rhs.second, stateMap.find(lhs)->second); + } + else // if B->a => \delta(StartState,a)=B + { + const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>(); + automaton.addTransition(q0, rhs, stateMap.find(lhs)->second); + } + } + } + + // step 5 + automaton.addFinalState(stateMap.find(grammar.getInitialSymbol())->second); + if(grammar.getGeneratesEpsilon()) + automaton.addFinalState(q0); + + return automaton; } automaton::NFA ToAutomaton::convert(const grammar::RightRG& grammar) { - std::map<alphabet::Symbol, automaton::State> stateMap; - std::set<automaton::State> states; - - // step2 - for(const auto& symbol : grammar.getNonterminalAlphabet()) - { - automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel()); - states.insert(state); - stateMap.insert(std::make_pair(symbol, state)); - } - - // step 1, 4 - const automaton::State AState = automaton::createUniqueState(automaton::State("A"), states); - states.insert(AState); - automaton::NFA automaton(stateMap.find(grammar.getInitialSymbol())->second); - automaton.setStates(states); - - automaton.setInputSymbols(grammar.getTerminalAlphabet()); - - // step 3 - for(const auto& rule : grammar.getRules()) - { - const alphabet::Symbol& lhs = rule.first; - for(const auto& ruleRHS : rule.second) - { - if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->aC => \delta(B,a)=C - { - const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>(); - automaton.addTransition(stateMap.find(lhs)->second, rhs.first, stateMap.find(rhs.second)->second); - } - else // if B->a => \delta(B,a)=AState - { - const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>(); - automaton.addTransition(stateMap.find(lhs)->second, rhs, AState); - } - } - } - - // step 5 - automaton.addFinalState(AState); - if(grammar.getGeneratesEpsilon()) - automaton.addFinalState(automaton.getInitialState()); - - return automaton; + std::map<alphabet::Symbol, automaton::State> stateMap; + std::set<automaton::State> states; + + // step2 + for(const auto& symbol : grammar.getNonterminalAlphabet()) + { + automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel()); + states.insert(state); + stateMap.insert(std::make_pair(symbol, state)); + } + + // step 1, 4 + const automaton::State AState = automaton::createUniqueState(automaton::State("A"), states); + states.insert(AState); + automaton::NFA automaton(stateMap.find(grammar.getInitialSymbol())->second); + automaton.setStates(states); + + automaton.setInputSymbols(grammar.getTerminalAlphabet()); + + // step 3 + for(const auto& rule : grammar.getRules()) + { + const alphabet::Symbol& lhs = rule.first; + for(const auto& ruleRHS : rule.second) + { + if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->aC => \delta(B,a)=C + { + const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>(); + automaton.addTransition(stateMap.find(lhs)->second, rhs.first, stateMap.find(rhs.second)->second); + } + else // if B->a => \delta(B,a)=AState + { + const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>(); + automaton.addTransition(stateMap.find(lhs)->second, rhs, AState); + } + } + } + + // step 5 + automaton.addFinalState(AState); + if(grammar.getGeneratesEpsilon()) + automaton.addFinalState(automaton.getInitialState()); + + return automaton; } void ToAutomaton::Visit(void* userData, const grammar::RightRG& grammar) const { - automaton::Automaton* & out = *((automaton::Automaton**) userData); - out = new automaton::Automaton(this->convert(grammar)); + automaton::Automaton* & out = *((automaton::Automaton**) userData); + out = new automaton::Automaton(this->convert(grammar)); } void ToAutomaton::Visit(void* userData, const grammar::LeftRG& grammar) const { - automaton::Automaton* & out = *((automaton::Automaton**) userData); - out = new automaton::Automaton(this->convert(grammar)); + automaton::Automaton* & out = *((automaton::Automaton**) userData); + out = new automaton::Automaton(this->convert(grammar)); } void ToAutomaton::Visit(void*, const grammar::RightLG&) const { - throw exception::AlibException("Unsupported grammar type RightLG"); + throw exception::AlibException("Unsupported grammar type RightLG"); } void ToAutomaton::Visit(void*, const grammar::LeftLG&) const { - throw exception::AlibException("Unsupported grammar type LeftLG"); + throw exception::AlibException("Unsupported grammar type LeftLG"); +} + +void ToAutomaton::Visit(void*, const grammar::LG& ) const { + throw exception::AlibException("Unsupported grammar type LG"); +} + +void ToAutomaton::Visit(void*, const grammar::CFG& ) const { + throw exception::AlibException("Unsupported grammar type CFG"); +} + +void ToAutomaton::Visit(void*, const grammar::EpsilonFreeCFG& ) const { + throw exception::AlibException("Unsupported grammar type EpsilonFreeCFG"); +} + +void ToAutomaton::Visit(void*, const grammar::CNF& ) const { + throw exception::AlibException("Unsupported grammar type CFG"); +} + +void ToAutomaton::Visit(void*, const grammar::GNF& ) const { + throw exception::AlibException("Unsupported grammar type GNF"); +} + +void ToAutomaton::Visit(void*, const grammar::CSG&) const { + throw exception::AlibException("Unsupported grammar type CSG"); +} + +void ToAutomaton::Visit(void*, const grammar::NonContractingGrammar&) const { + throw exception::AlibException("Unsupported grammar type NonConctractingGrammar"); +} + +void ToAutomaton::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar"); +} + +void ToAutomaton::Visit(void*, const grammar::UnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar"); } const ToAutomaton ToAutomaton::TO_AUTOMATON; diff --git a/alib2algo/src/grammar/convert/ToAutomaton.h b/alib2algo/src/grammar/convert/ToAutomaton.h index 2f069ef9e6..aeea0edfbc 100644 --- a/alib2algo/src/grammar/convert/ToAutomaton.h +++ b/alib2algo/src/grammar/convert/ToAutomaton.h @@ -5,8 +5,8 @@ * Author: Tomas Pecka */ -#ifndef _TO_AUTOMATON_H_ -#define _TO_AUTOMATON_H_ +#ifndef _GRAMMAR_TO_AUTOMATON_H_ +#define _GRAMMAR_TO_AUTOMATON_H_ #include <grammar/Grammar.h> #include <grammar/Regular/LeftRG.h> @@ -23,30 +23,38 @@ namespace convert { * Converts regular grammar to nondeterministic finite automaton. * Sources: Melichar 2.98 (RightRG -> NFA) and 2.102 (LeftRG -> NFA). */ -class ToAutomaton : public grammar::VisitableConstRGBase -{ +class ToAutomaton : public grammar::VisitableGrammarBase::const_visitor_type { public: - /** - * Performs conversion. - * @param grammar Regular grammar to convert. - * @return FSM equivalent to source grammar. - */ - static automaton::Automaton convert(const grammar::Grammar& grammar); + /** + * Performs conversion. + * @param grammar Regular grammar to convert. + * @return FSM equivalent to source grammar. + */ + static automaton::Automaton convert(const grammar::Grammar& grammar); - static automaton::NFA convert(const grammar::LeftRG& grammar); - static automaton::NFA convert(const grammar::RightRG& grammar); + static automaton::NFA convert(const grammar::LeftRG& grammar); + static automaton::NFA convert(const grammar::RightRG& grammar); private: - void Visit(void*, const grammar::RightRG& grammar) const; - void Visit(void*, const grammar::LeftRG& grammar) const; - void Visit(void*, const grammar::RightLG& grammar) const; - void Visit(void*, const grammar::LeftLG& grammar) const; - - static const ToAutomaton TO_AUTOMATON; + void Visit(void*, const grammar::RightRG& grammar) const; + void Visit(void*, const grammar::LeftRG& grammar) const; + void Visit(void*, const grammar::RightLG& grammar) const; + void Visit(void*, const grammar::LeftLG& 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 ToAutomaton TO_AUTOMATON; }; } /* namespace convert */ } /* namespace grammar */ -#endif /* _TO_AUTOMATON_H_ */ +#endif /* _GRAMMAR_TO_AUTOMATON_H_ */ diff --git a/alib2algo/src/grammar/convert/ToRegExp.cpp b/alib2algo/src/grammar/convert/ToRegExp.cpp new file mode 100644 index 0000000000..fe2696f7f4 --- /dev/null +++ b/alib2algo/src/grammar/convert/ToRegExp.cpp @@ -0,0 +1,87 @@ +/* + * ToRegExp.cpp + * + * Created on: 4. 3. 2014 + * Author: Tomas Pecka + */ + +#include "ToRegExp.h" +#include "ToRegExpAlgebraic.h" +#include <exception/AlibException.h> + +namespace grammar { + +namespace convert { + +regexp::RegExp ToRegExp::convert(const grammar::Grammar& grammar) +{ + regexp::RegExp* out = NULL; + grammar.getData().Accept((void*) &out, ToRegExp::TO_REG_EXP); + regexp::RegExp res = std::move(*out); + delete out; + return res; +} + +void ToRegExp::Visit(void* userData, const grammar::RightRG& grammar) const +{ + regexp::RegExp* & out = *((regexp::RegExp**) userData); + out = new regexp::RegExp(ToRegExpAlgebraic::convert(grammar)); +} + +void ToRegExp::Visit(void* userData, const grammar::LeftRG& grammar) const +{ + regexp::RegExp* & out = *((regexp::RegExp**) userData); + out = new regexp::RegExp(ToRegExpAlgebraic::convert(grammar)); +} + +void ToRegExp::Visit(void*, const grammar::RightLG&) const +{ + throw exception::AlibException("Unsupported grammar type RightLG"); +} + +void ToRegExp::Visit(void*, const grammar::LeftLG&) const +{ + throw exception::AlibException("Unsupported grammar type LeftLG"); +} + +void ToRegExp::Visit(void*, const grammar::LG& ) const { + throw exception::AlibException("Unsupported grammar type LG"); +} + +void ToRegExp::Visit(void*, const grammar::CFG& ) const { + throw exception::AlibException("Unsupported grammar type CFG"); +} + +void ToRegExp::Visit(void*, const grammar::EpsilonFreeCFG& ) const { + throw exception::AlibException("Unsupported grammar type EpsilonFreeCFG"); +} + +void ToRegExp::Visit(void*, const grammar::CNF& ) const { + throw exception::AlibException("Unsupported grammar type CFG"); +} + +void ToRegExp::Visit(void*, const grammar::GNF& ) const { + throw exception::AlibException("Unsupported grammar type GNF"); +} + +void ToRegExp::Visit(void*, const grammar::CSG&) const { + throw exception::AlibException("Unsupported grammar type CSG"); +} + +void ToRegExp::Visit(void*, const grammar::NonContractingGrammar&) const { + throw exception::AlibException("Unsupported grammar type NonConctractingGrammar"); +} + +void ToRegExp::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar"); +} + +void ToRegExp::Visit(void*, const grammar::UnrestrictedGrammar&) const { + throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar"); +} + +const ToRegExp ToRegExp::TO_REG_EXP; + +} /* namespace convert */ + +} /* namespace grammar */ diff --git a/alib2algo/src/grammar/convert/ToRegExp.h b/alib2algo/src/grammar/convert/ToRegExp.h new file mode 100644 index 0000000000..aace07b45d --- /dev/null +++ b/alib2algo/src/grammar/convert/ToRegExp.h @@ -0,0 +1,52 @@ +/* + * ToRegExp.h + * + * Created on: 4. 3. 2014 + * Author: Jan Travnicek + */ + +#ifndef GRAMMAR_TO_REG_EXP_H_ +#define GRAMMAR_TO_REG_EXP_H_ + +#include <grammar/Grammar.h> +#include <grammar/Regular/RightRG.h> +#include <grammar/Regular/LeftRG.h> + +#include <regexp/RegExp.h> + +namespace grammar { + +namespace convert { + +class ToRegExp : public grammar::VisitableConstRGBase +{ +public: + /** + * @return regexp equivalent to source right regular grammar. + * @param grammar Grammar to convert + */ + static regexp::RegExp convert(const grammar::Grammar& grammar); + +protected: + void Visit(void*, const grammar::RightRG& grammar) const; + void Visit(void*, const grammar::LeftRG& grammar) const; + void Visit(void*, const grammar::RightLG& grammar) const; + void Visit(void*, const grammar::LeftLG& 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 ToRegExp TO_REG_EXP; +}; + +} /* namespace covert */ + +} /* namespace grammar */ + +#endif /* GRAMMAR_TO_REG_EXP_H_ */ diff --git a/alib2algo/src/regexp/convert/ToAutomaton.cpp b/alib2algo/src/regexp/convert/ToAutomaton.cpp new file mode 100644 index 0000000000..781ecccc3f --- /dev/null +++ b/alib2algo/src/regexp/convert/ToAutomaton.cpp @@ -0,0 +1,40 @@ +/* + * ToAutomaton.cpp + * + * Created on: 11. 1. 2014 + * Author: Jan Travnicek + */ + +#include "ToAutomaton.h" +#include "ToAutomatonGlushkov.h" +#include <exception/AlibException.h> + +namespace regexp { + +namespace convert { + +automaton::Automaton ToAutomaton::convert(const regexp::RegExp& regexp) +{ + automaton::Automaton* out = NULL; + regexp.getData().Accept((void*) &out, ToAutomaton::TO_AUTOMATON); + automaton::Automaton res = std::move(*out); + delete out; + return res; +} + +void ToAutomaton::Visit(void* userData, const regexp::FormalRegExp& regexp) const +{ + automaton::Automaton* &out = *((automaton::Automaton**) userData); + out = new automaton::Automaton(ToAutomatonGlushkov::convert(regexp)); +} +void ToAutomaton::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const +{ + automaton::Automaton* &out = *((automaton::Automaton**) userData); + out = new automaton::Automaton(ToAutomatonGlushkov::convert(regexp)); +} + +const ToAutomaton ToAutomaton::TO_AUTOMATON; + +} /* namespace convert */ + +} /* namespace regexp */ diff --git a/alib2algo/src/regexp/convert/ToAutomaton.h b/alib2algo/src/regexp/convert/ToAutomaton.h new file mode 100644 index 0000000000..9894aff997 --- /dev/null +++ b/alib2algo/src/regexp/convert/ToAutomaton.h @@ -0,0 +1,42 @@ +/* + * RegExpToAutomaton.h + * + * Created on: 11. 1. 2014 + * Author: Tomas Pecka + */ + +#ifndef REG_EXP_TO_AUTOMATON_H_ +#define REG_EXP_TO_AUTOMATON_H_ + +#include <regexp/RegExp.h> +#include <regexp/formal/FormalRegExp.h> +#include <regexp/unbounded/UnboundedRegExp.h> + +#include <automaton/Automaton.h> +#include <automaton/FSM/NFA.h> + +namespace regexp { + +namespace convert { + +class ToAutomaton : public regexp::VisitableRegExpBase::const_visitor_type +{ +public: + /** + * Performs conversion. + * @return FSM equivalent to original regular expression. + */ + static automaton::Automaton convert(const regexp::RegExp& regexp); + +private: + void Visit(void*, const regexp::FormalRegExp& regexp) const; + void Visit(void*, const regexp::UnboundedRegExp& regexp) const; + + static const ToAutomaton TO_AUTOMATON; +}; + +} /* namespace convert */ + +} /* namespace regexp */ + +#endif /* REG_EXP_TO_AUTOMATON_H_ */ diff --git a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp index 7f25196efd..fb75db1789 100644 --- a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp +++ b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp @@ -83,6 +83,11 @@ automaton::NFA ToAutomatonGlushkov::convert(const regexp::UnboundedRegExp& regex return automaton; } +automaton::NFA ToAutomatonGlushkov::convert(const regexp::FormalRegExp& regexp) +{ + throw exception::AlibException("Glushkov: Converting FormalRegExp NYI"); // TODO +} + void ToAutomatonGlushkov::Visit(void* userData, const regexp::FormalRegExp& regexp) const { /* diff --git a/alib2algo/src/regexp/convert/ToGrammar.cpp b/alib2algo/src/regexp/convert/ToGrammar.cpp new file mode 100644 index 0000000000..0eb7d88c9b --- /dev/null +++ b/alib2algo/src/regexp/convert/ToGrammar.cpp @@ -0,0 +1,41 @@ +/* + * ToGrammar.cpp + * + * Created on: 6. 3. 2014 + * Author: Jan Travnicek + */ + +#include "ToGrammar.h" +#include "ToGrammarRightRGGlushkov.h" +#include <exception/AlibException.h> + +namespace regexp { + +namespace convert { + +grammar::Grammar ToGrammar::convert(const regexp::RegExp& regexp) +{ + grammar::Grammar* out = NULL; + regexp.getData().Accept((void*) &out, ToGrammar::TO_GRAMMAR); + grammar::Grammar res = std::move(*out); + delete out; + return res; +} + +void ToGrammar::Visit(void* userData, const regexp::FormalRegExp& regexp) const +{ + grammar::Grammar* &out = *((grammar::Grammar**) userData); + out = new grammar::Grammar(ToGrammarRightRGGlushkov::convert(regexp)); +} + +void ToGrammar::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const +{ + grammar::Grammar* &out = *((grammar::Grammar**) userData); + out = new grammar::Grammar(ToGrammarRightRGGlushkov::convert(regexp)); +} + +const ToGrammar ToGrammar::TO_GRAMMAR; + +} /* namespace convert */ + +} /* namespace regexp */ diff --git a/alib2algo/src/regexp/convert/ToGrammar.h b/alib2algo/src/regexp/convert/ToGrammar.h new file mode 100644 index 0000000000..de8438c541 --- /dev/null +++ b/alib2algo/src/regexp/convert/ToGrammar.h @@ -0,0 +1,38 @@ +/* + * ToGrammar.h + * + * Created on: 6. 3. 2014 + * Author: Jan Travnicek + */ + +#ifndef REG_EXP_TO_GRAMMAR_H_ +#define REG_EXP_TO_GRAMMAR_H_ + +#include <grammar/Grammar.h> +#include <regexp/RegExp.h> + +namespace regexp { + +namespace convert { + +class ToGrammar : public regexp::VisitableRegExpBase::const_visitor_type +{ +public: + /** + * Performs conversion. + * @return right regular grammar equivalent to source regexp. + */ + static grammar::Grammar convert(const regexp::RegExp& regexp); + +private: + void Visit(void*, const regexp::FormalRegExp& regexp) const; + void Visit(void*, const regexp::UnboundedRegExp& regexp) const; + + static const ToGrammar TO_GRAMMAR; +}; + +} /* namespace convert */ + +} /* namespace regexp */ + +#endif /* REG_EXP_TO_GRAMMAR_H_ */ diff --git a/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp index 1268ed6f7e..1f9106c2a9 100644 --- a/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp +++ b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp @@ -2,7 +2,7 @@ * ToGrammarRightRGDerivation.cpp * * Created on: 6. 3. 2014 - * Author: tomas + * Author: Tomas Pecka */ #include "ToGrammarRightRGDerivation.h" diff --git a/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp index d60fa098d1..cb1ba5388b 100644 --- a/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp +++ b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp @@ -93,6 +93,9 @@ grammar::RightRG ToGrammarRightRGGlushkov::convert(const regexp::UnboundedRegExp return grammar; } +grammar::RightRG ToGrammarRightRGGlushkov::convert(const regexp::FormalRegExp& regexp) { + throw exception::AlibException("Glushkov: Converting FormalRegExp NYI"); // TODO +} void ToGrammarRightRGGlushkov::Visit(void* userData, const regexp::FormalRegExp& regexp) const { -- GitLab