diff --git a/aepsilon2/src/aepsilon.cpp b/aepsilon2/src/aepsilon.cpp index 3c8cf8f8c712958a522135bf9a4377c7f1875c3d..2baf53dc82a8e98287a078c6d89316368a4db80d 100644 --- a/aepsilon2/src/aepsilon.cpp +++ b/aepsilon2/src/aepsilon.cpp @@ -3,7 +3,6 @@ // Author : Tomas Pecka //============================================================================ - #include <iostream> #include <factory/DataFactory.hpp> @@ -12,50 +11,26 @@ #include "epsilon/fsm/FSMEpsilonRemover.h" int main(int argc, char** argv) { - int fileParameterIndex = -1; try { - if( argc > 1 ) - { - for( int i = 1; i < argc; i++ ) - { - if( std::string( "-h" ).compare( argv[i] ) == 0 ) - { - std::cout << "Removes eps transitions from NFA." << std::endl; - std::cout << "Usage: aepsilon [automaton.xml]" << std::endl; - return 1; - } - else - { - if(fileParameterIndex == -1) - fileParameterIndex = i; - else - throw exception::AlibException("Only one file can be passed as parameter - " + std::string(argv[i]) + " " + std::string(argv[fileParameterIndex])); - } - } - } - - std::list<sax::Token> tokens; - - if(fileParameterIndex != -1) { - sax::SaxParseInterface::parseFile(argv[fileParameterIndex], tokens); + if (argc == 2 && std::string("-h").compare(argv[1]) == 0) { + std::cout << "Remove epsilon transitions from automaton." << std::endl << "Usage: aepsilon [automaton.xml]" << std::endl; + return -1; + } else if (argc == 1 || (argc == 2 && std::string("--").compare(argv[1]) == 0)) { + alib::DataFactory::toStdout(epsilon::FSMEpsilonRemover::remove(alib::DataFactory::fromStdin<automaton::Automaton>())); + } else if (argc == 2) { + alib::DataFactory::toStdout(epsilon::FSMEpsilonRemover::remove(alib::DataFactory::fromStdin<automaton::Automaton>())); } else { - sax::SaxParseInterface::parseStdin(tokens); + std::cout << "Automaton minimize require deterministic finite automaton" << std::endl; + return 1; } - if(alib::FromXMLParsers::automatonParser.first(tokens)) { - std::string xmlMark = tokens.front( ).getData( ); - automaton::Automaton automaton = alib::DataFactory::fromTokens<automaton::Automaton>(tokens); - automaton::Automaton res = epsilon::FSMEpsilonRemover::remove( automaton ); - alib::DataFactory::toStdout(res); - } else { - throw exception::AlibException("Invalid argument expected Epsilon NFA."); - } + return 0; } catch (const exception::AlibException& exception) { alib::DataFactory::toStdout(exception); return 1; - } catch (...) { + } catch(...) { return 127; } } diff --git a/alib2algo/src/conversions/re2fa/Thompson.cpp b/alib2algo/src/conversions/re2fa/Thompson.cpp index 092f08422bca7f81f5307295558d739aeb3f46b9..e61a87b637614a452c0a5effda3e9b5afcc6e943 100644 --- a/alib2algo/src/conversions/re2fa/Thompson.cpp +++ b/alib2algo/src/conversions/re2fa/Thompson.cpp @@ -13,11 +13,11 @@ namespace conversions namespace re2fa { -automaton::EpsilonNFA Thompson::convert(const regexp::RegExp& regexp) +automaton::Automaton Thompson::convert(const regexp::RegExp& regexp) { - automaton::EpsilonNFA* out = NULL; + automaton::Automaton* out = NULL; regexp.getData().Accept((void*) &out, Thompson::THOMPSON); - automaton::EpsilonNFA res = std::move(*out); + automaton::Automaton res = std::move(*out); delete out; return res; } @@ -42,14 +42,14 @@ automaton::EpsilonNFA Thompson::convert(const T& regexp) void Thompson::Visit(void* userData, const regexp::FormalRegExp& regexp) const { - automaton::EpsilonNFA* & out = *((automaton::EpsilonNFA**) userData); - out = new automaton::EpsilonNFA(this->convert(regexp)); + automaton::Automaton* & out = *((automaton::Automaton**) userData); + out = new automaton::Automaton(this->convert(regexp)); } void Thompson::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const { - automaton::EpsilonNFA* & out = *((automaton::EpsilonNFA**) userData); - out = new automaton::EpsilonNFA(this->convert(regexp)); + automaton::Automaton* & out = *((automaton::Automaton**) userData); + out = new automaton::Automaton(this->convert(regexp)); } // ---------------------------------------------------------------------------- diff --git a/alib2algo/src/conversions/re2fa/Thompson.h b/alib2algo/src/conversions/re2fa/Thompson.h index d3365ec0b9361485831ea03101ad96bc09f416d5..e127f07f54e53f48e9691986e9f04e6d0af0f312 100644 --- a/alib2algo/src/conversions/re2fa/Thompson.h +++ b/alib2algo/src/conversions/re2fa/Thompson.h @@ -11,6 +11,7 @@ #include <regexp/RegExp.h> #include <regexp/formal/FormalRegExpElements.h> #include <regexp/unbounded/UnboundedRegExpElements.h> +#include <automaton/Automaton.h> #include <automaton/FSM/EpsilonNFA.h> namespace conversions @@ -35,7 +36,7 @@ public: * @param regexp regexp to convert * @return nondeterministic finite automaton with epsilon transitions accepting language described by the regexp */ - static automaton::EpsilonNFA convert(const regexp::RegExp& regexp); + static automaton::Automaton convert(const regexp::RegExp& regexp); template<class T> static automaton::EpsilonNFA convert(const T& regexp); diff --git a/alib2algo/src/determinize/nfa/NFADeterminizer.cpp b/alib2algo/src/determinize/nfa/NFADeterminizer.cpp index 9af97b5284203cb2908e7ac182fb58c2e93a72e9..c95aae328fe05a9880d462fdb8516bf9b9f31caa 100644 --- a/alib2algo/src/determinize/nfa/NFADeterminizer.cpp +++ b/alib2algo/src/determinize/nfa/NFADeterminizer.cpp @@ -13,6 +13,13 @@ namespace determinize { +automaton::Automaton NFADeterminizer::determinize(const automaton::Automaton& automaton) { + automaton::Automaton* out = NULL; + automaton.getData().Accept((void*) &out, NFADeterminizer::NFA_DETERMINIZER); + automaton::Automaton res = std::move(*out); + delete out; + return res; +} automaton::State NFADeterminizer::createDFAState(const std::set<automaton::State>& nfaStates) { std::set<label::Label> labelSet; @@ -77,4 +84,59 @@ automaton::DFA NFADeterminizer::determinize(const automaton::NFA& nfa) { return res; } +void NFADeterminizer::Visit(void*, const automaton::UnknownAutomaton&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + +void NFADeterminizer::Visit(void*, const automaton::EpsilonNFA&) const { + throw exception::AlibException("Unsupported automaton type EpsilonNFA"); +} + +void NFADeterminizer::Visit(void* data, const automaton::NFA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->determinize(automaton)); +} + +void NFADeterminizer::Visit(void*, const automaton::DFA&) const { + throw exception::AlibException("Unsupported automaton type DFA"); +} + +void NFADeterminizer::Visit(void*, const automaton::ExtendedNFA& ) const { + throw exception::AlibException("Unsupported automaton type ExtendedNFA"); +} + +void NFADeterminizer::Visit(void*, const automaton::CompactNFA& ) const { + throw exception::AlibException("Unsupported automaton type CompactNFA"); +} + +void NFADeterminizer::Visit(void*, const automaton::DPDA&) const { + throw exception::AlibException("Unsupported automaton type DPDA"); +} + +void NFADeterminizer::Visit(void*, const automaton::SinglePopDPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); +} + +void NFADeterminizer::Visit(void*, const automaton::InputDrivenNPDA&) const { + throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); +} + +void NFADeterminizer::Visit(void*, const automaton::VisiblyPushdownNPDA&) const { + throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); +} + +void NFADeterminizer::Visit(void*, const automaton::NPDA&) const { + throw exception::AlibException("Unsupported automaton type NPDA"); +} + +void NFADeterminizer::Visit(void*, const automaton::SinglePopNPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +} + +void NFADeterminizer::Visit(void*, const automaton::OneTapeDTM&) const { + throw exception::AlibException("Unsupported automaton type OneTapeDTM"); +} + +const NFADeterminizer NFADeterminizer::NFA_DETERMINIZER; + } diff --git a/alib2algo/src/determinize/nfa/NFADeterminizer.h b/alib2algo/src/determinize/nfa/NFADeterminizer.h index b0a7697fa009ed4d57911cc481aa8afabe286ddd..b5476588710876243a50e7708970eb9958124b9a 100644 --- a/alib2algo/src/determinize/nfa/NFADeterminizer.h +++ b/alib2algo/src/determinize/nfa/NFADeterminizer.h @@ -10,16 +10,19 @@ #include <set> -#include "automaton/common/State.h" -#include "automaton/FSM/NFA.h" -#include "automaton/FSM/DFA.h" +#include <automaton/common/State.h> +#include <automaton/Automaton.h> +#include <automaton/FSM/NFA.h> +#include <automaton/FSM/DFA.h> + +#include <exception/AlibException.h> namespace determinize { /** * Class for running determinization algorithm on fsm. */ -class NFADeterminizer { +class NFADeterminizer : public automaton::VisitableAutomatonBase::const_visitor_type { private: @@ -41,14 +44,33 @@ private: * @return set of states from nondeterministic fsm */ static std::set<automaton::State> recreateNFAStates(const automaton::State& dfaState); + + void Visit(void*, const automaton::UnknownAutomaton& automaton) const; + void Visit(void*, const automaton::EpsilonNFA& automaton) const; + void Visit(void*, const automaton::NFA& automaton) const; + void Visit(void*, const automaton::DFA& automaton) const; + void Visit(void*, const automaton::ExtendedNFA& automaton) const; + void Visit(void*, const automaton::CompactNFA& automaton) const; + void Visit(void*, const automaton::DPDA& automaton) const; + void Visit(void*, const automaton::SinglePopDPDA& automaton) const; + void Visit(void*, const automaton::InputDrivenNPDA& automaton) const; + void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const; + void Visit(void*, const automaton::NPDA& automaton) const; + void Visit(void*, const automaton::SinglePopNPDA& automaton) const; + void Visit(void*, const automaton::OneTapeDTM& automaton) const; + + static const NFADeterminizer NFA_DETERMINIZER; + public: /** * @param nfsm nondeterministic final-state machine given for determinization + * @return DFA * Runs determinization algorithm on nondeterministic fsm given in constructor. */ - static automaton::DFA determinize(const automaton::NFA& nfa); + static automaton::Automaton determinize(const automaton::Automaton& nfa); + static automaton::DFA determinize(const automaton::NFA& nfa); }; } /* namespace determinize */ diff --git a/alib2algo/src/minimize/dfa/MinimizeDFA.cpp b/alib2algo/src/minimize/dfa/MinimizeDFA.cpp index 9840a5e8c94fbd3e9ccb5ded0975c6fac726c17b..9eefeb1c975afa487773aa948c076aab0740fcfc 100644 --- a/alib2algo/src/minimize/dfa/MinimizeDFA.cpp +++ b/alib2algo/src/minimize/dfa/MinimizeDFA.cpp @@ -12,13 +12,23 @@ #include <sstream> #include <iostream> -#include "alphabet/Symbol.h" -#include "label/IntegerLabel.h" +#include <alphabet/Symbol.h> +#include <label/IntegerLabel.h> -#include "automaton/Automaton.h" +#include <exception/AlibException.h> + +#include <automaton/Automaton.h> namespace minimize { +automaton::Automaton MinimizeDFA::minimize(const automaton::Automaton& automaton) { + automaton::Automaton* out = NULL; + automaton.getData().Accept((void*) &out, MinimizeDFA::MINIMIZE_DFA); + automaton::Automaton res = std::move(*out); + delete out; + return res; +} + automaton::DFA MinimizeDFA::minimize(const automaton::DFA& dfa) { if(dfa.getFinalStates().size() == 0) { automaton::DFA result(automaton::State(0)); @@ -131,4 +141,59 @@ automaton::DFA MinimizeDFA::minimize(const automaton::DFA& dfa) { return result; } +void MinimizeDFA::Visit(void*, const automaton::UnknownAutomaton&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + +void MinimizeDFA::Visit(void*, const automaton::EpsilonNFA&) const { + throw exception::AlibException("Unsupported automaton type EpsilonNFA"); +} + +void MinimizeDFA::Visit(void* data, const automaton::DFA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->minimize(automaton)); +} + +void MinimizeDFA::Visit(void*, const automaton::NFA&) const { + throw exception::AlibException("Unsupported automaton type DFA"); +} + +void MinimizeDFA::Visit(void*, const automaton::ExtendedNFA& ) const { + throw exception::AlibException("Unsupported automaton type ExtendedNFA"); +} + +void MinimizeDFA::Visit(void*, const automaton::CompactNFA& ) const { + throw exception::AlibException("Unsupported automaton type CompactNFA"); +} + +void MinimizeDFA::Visit(void*, const automaton::DPDA&) const { + throw exception::AlibException("Unsupported automaton type DPDA"); +} + +void MinimizeDFA::Visit(void*, const automaton::SinglePopDPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); +} + +void MinimizeDFA::Visit(void*, const automaton::InputDrivenNPDA&) const { + throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); +} + +void MinimizeDFA::Visit(void*, const automaton::VisiblyPushdownNPDA&) const { + throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); +} + +void MinimizeDFA::Visit(void*, const automaton::NPDA&) const { + throw exception::AlibException("Unsupported automaton type NPDA"); +} + +void MinimizeDFA::Visit(void*, const automaton::SinglePopNPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +} + +void MinimizeDFA::Visit(void*, const automaton::OneTapeDTM&) const { + throw exception::AlibException("Unsupported automaton type OneTapeDTM"); +} + +const MinimizeDFA MinimizeDFA::MINIMIZE_DFA; + } /* namespace minimize */ diff --git a/alib2algo/src/minimize/dfa/MinimizeDFA.h b/alib2algo/src/minimize/dfa/MinimizeDFA.h index 056914756a99a3c9aa4cae6c487df17ed8a88128..ea20405e8ab17e34c91a20c6740e309f44cd2549 100644 --- a/alib2algo/src/minimize/dfa/MinimizeDFA.h +++ b/alib2algo/src/minimize/dfa/MinimizeDFA.h @@ -8,14 +8,36 @@ #ifndef MINIMIZE_DFA_H_ #define MINIMIZE_DFA_H_ -#include "automaton/FSM/DFA.h" +#include <automaton/Automaton.h> +#include <automaton/FSM/DFA.h> namespace minimize { -class MinimizeDFA { +class MinimizeDFA : public automaton::VisitableAutomatonBase::const_visitor_type { public: + /** + * @param dfa automaton to minimize + */ + static automaton::Automaton minimize(const automaton::Automaton& dfa); + static automaton::DFA minimize(const automaton::DFA& dfa); +protected: + void Visit(void*, const automaton::UnknownAutomaton& automaton) const; + void Visit(void*, const automaton::EpsilonNFA& automaton) const; + void Visit(void*, const automaton::NFA& automaton) const; + void Visit(void*, const automaton::DFA& automaton) const; + void Visit(void*, const automaton::ExtendedNFA& automaton) const; + void Visit(void*, const automaton::CompactNFA& automaton) const; + void Visit(void*, const automaton::DPDA& automaton) const; + void Visit(void*, const automaton::SinglePopDPDA& automaton) const; + void Visit(void*, const automaton::InputDrivenNPDA& automaton) const; + void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const; + void Visit(void*, const automaton::NPDA& automaton) const; + void Visit(void*, const automaton::SinglePopNPDA& automaton) const; + void Visit(void*, const automaton::OneTapeDTM& automaton) const; + + static const MinimizeDFA MINIMIZE_DFA; }; } diff --git a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp b/alib2algo/test-src/conversions/re2fa/re2faTest.cpp index 4806de5eb3591f0f92beeb2f5de3ff19ed3767c4..9adb79a4c57b375ed7e1360c009cec27ed8b8a02 100644 --- a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp +++ b/alib2algo/test-src/conversions/re2fa/re2faTest.cpp @@ -31,22 +31,20 @@ void re2faTest::testThompson() { regexp::RegExpFromStringParser parser(inputs); regexp::RegExp regexp1( parser.parseValue() ); - conversions::re2fa::Thompson thompson1; - automaton::EpsilonNFA enfa1 = thompson1.convert(regexp1); + automaton::Automaton enfa1 = conversions::re2fa::Thompson::convert(regexp1); regexp::RegExp regexp2( conversions::fa2re::Algebraic::convert(enfa1) ); - conversions::re2fa::Thompson thompson2; - automaton::EpsilonNFA enfa2 = thompson2.convert(regexp2); + automaton::Automaton enfa2 = conversions::re2fa::Thompson::convert(regexp2); - automaton::NFA nfa1 = epsilon::FSMEpsilonRemover::remove(enfa1); - automaton::NFA nfa2 = epsilon::FSMEpsilonRemover::remove(enfa2); + automaton::Automaton nfa1 = epsilon::FSMEpsilonRemover::remove(enfa1); + automaton::Automaton nfa2 = epsilon::FSMEpsilonRemover::remove(enfa2); - automaton::DFA dfa1 = determinize::NFADeterminizer::determinize(nfa1); - automaton::DFA dfa2 = determinize::NFADeterminizer::determinize(nfa2); + automaton::Automaton dfa1 = determinize::NFADeterminizer::determinize(nfa1); + automaton::Automaton dfa2 = determinize::NFADeterminizer::determinize(nfa2); - automaton::DFA mdfa1 = minimize::MinimizeDFA::minimize(dfa1); - automaton::DFA mdfa2 = minimize::MinimizeDFA::minimize(dfa2); + automaton::Automaton mdfa1 = minimize::MinimizeDFA::minimize(dfa1); + automaton::Automaton mdfa2 = minimize::MinimizeDFA::minimize(dfa2); CPPUNIT_ASSERT( mdfa1 == mdfa2); } diff --git a/aminimize2/src/aminimize.cpp b/aminimize2/src/aminimize.cpp index d43b6430c060664998ef0b821d742cff16d2a7c2..b2c963e5e4ba9d0055b2da791c8ed2b4b87a1719 100644 --- a/aminimize2/src/aminimize.cpp +++ b/aminimize2/src/aminimize.cpp @@ -4,35 +4,26 @@ //============================================================================ #include <iostream> -#include <string> -#include <set> -#include "exception/AlibException.h" -#include "factory/DataFactory.hpp" +#include <exception/AlibException.h> +#include <factory/DataFactory.hpp> + #include "minimize/dfa/MinimizeDFA.h" int main(int argc, char** argv) { try { - - automaton::DFA* automatonPointer = NULL; - if (argc == 2 && std::string("-h").compare(argv[1]) == 0) { std::cout << "Automaton minimize." << std::endl << "Usage: aminimize automaton.xml" << std::endl; return -1; } else if (argc == 1 || (argc == 2 && std::string("--").compare(argv[1]) == 0)) { - automatonPointer = static_cast<automaton::DFA*>(std::move(alib::DataFactory::fromStdin<automaton::DFA>()).plunder()); + alib::DataFactory::toStdout(minimize::MinimizeDFA::minimize(alib::DataFactory::fromStdin<automaton::Automaton>())); } else if (argc == 2) { - automatonPointer = static_cast<automaton::DFA*>(std::move(alib::DataFactory::fromFile<automaton::DFA>(argv[1])).plunder()); + alib::DataFactory::toStdout(minimize::MinimizeDFA::minimize(alib::DataFactory::fromStdin<automaton::Automaton>())); } else { std::cout << "Automaton minimize require deterministic finite automaton" << std::endl; return 1; } - - automaton::DFA res = minimize::MinimizeDFA::minimize(*automatonPointer); - alib::DataFactory::toStdout(res); - - delete automatonPointer; return 0;