diff --git a/alib2data/src/automaton/FSM/CompactNFA.cpp b/alib2data/src/automaton/FSM/CompactNFA.cpp index a0bc6fc195a42da21be8331999d3f8e431ef7885..5e3a22d065249f1bdd5daead68c271ff22f13fed 100644 --- a/alib2data/src/automaton/FSM/CompactNFA.cpp +++ b/alib2data/src/automaton/FSM/CompactNFA.cpp @@ -8,6 +8,7 @@ #include "CompactNFA.h" #include "../../std/map.hpp" #include "../AutomatonException.h" +#include "../../string/StringAlphabetGetter.h" #include <ostream> #include <algorithm> @@ -41,7 +42,7 @@ bool CompactNFA::removeState(const State& state) { bool CompactNFA::removeInputSymbol(const alphabet::Symbol& symbol) { for (std::map<std::pair<State, string::String>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end(); transition++) { - if (transition->first.second.getAlphabet().count(symbol) == 1) + if (string::StringAlphabetGetter::STRING_ALPHABET_GETTER.getAlphabet(transition->first.second).count(symbol) == 1) throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used."); } @@ -52,9 +53,11 @@ bool CompactNFA::addTransition(const State& from, const string::String& input, c if (states.find(from) == states.end()) throw AutomatonException("State \"" + (std::string) from.getName() + "\" doesn't exist."); - std::set<alphabet::Symbol> inputStringAlphabet; - std::set_difference(inputAlphabet.begin(), inputAlphabet.end(), input.getAlphabet().begin(), input.getAlphabet().end(), std::inserter(inputStringAlphabet, inputStringAlphabet.end())); - if (inputStringAlphabet.size() != 0) + std::set<alphabet::Symbol> inputStringAlphabetDiff; + std::set<alphabet::Symbol> inputStringAlphabet = string::StringAlphabetGetter::STRING_ALPHABET_GETTER.getAlphabet(input); + + std::set_difference(inputAlphabet.begin(), inputAlphabet.end(), inputStringAlphabet.begin(), inputStringAlphabet.end(), std::inserter(inputStringAlphabetDiff, inputStringAlphabetDiff.end())); + if (inputStringAlphabetDiff.size() != 0) throw AutomatonException("Input string is over different alphabet than automaton"); if (states.find(to) == states.end()) diff --git a/alib2data/src/string/CyclicString.cpp b/alib2data/src/string/CyclicString.cpp index c23e9414c35739019249433b7d8e5eeb6ce3570c..0985c6c2f34f088418710d0e7e940642dd2a265c 100644 --- a/alib2data/src/string/CyclicString.cpp +++ b/alib2data/src/string/CyclicString.cpp @@ -6,6 +6,8 @@ */ #include "CyclicString.h" +#include "../exception/AlibException.h" + #include <cassert> #include <sstream> #include <algorithm> @@ -15,20 +17,24 @@ namespace string { -CyclicString::CyclicString(const std::vector<alphabet::Symbol>& data) : m_Data(data) { +CyclicString::CyclicString() { } -CyclicString::CyclicString(std::vector<alphabet::Symbol>&& data) : m_Data(std::move(data)) { +CyclicString::CyclicString(const std::set<alphabet::Symbol>& alphabet, const std::vector<alphabet::Symbol>& data) : alphabet(alphabet) { + setContent(data); +} +CyclicString::CyclicString(std::set<alphabet::Symbol>&& alphabet, std::vector<alphabet::Symbol>&& data) : alphabet(std::move(alphabet)) { + setContent(std::move(data)); } -bool CyclicString::testSymbol( const alphabet::Symbol & symbol ) const { - return std::any_of(m_Data.begin(), m_Data.end(), [&](const alphabet::Symbol & s) { return s == symbol; } ); +CyclicString::CyclicString(const std::vector<alphabet::Symbol>& data) : alphabet(data.begin(), data.end()) { + m_Data = data; } -void CyclicString::computeMinimalAlphabet(std::set<alphabet::Symbol>& alphabet) const { - alphabet.insert(m_Data.begin(), m_Data.end()); +CyclicString::CyclicString(std::vector<alphabet::Symbol>&& data) : alphabet(data.begin(), data.end()) { + m_Data = std::move(data); } StringBase* CyclicString::clone() const { @@ -39,6 +45,32 @@ StringBase* CyclicString::plunder() && { return new CyclicString(std::move(*this)); } +const std::set<alphabet::Symbol>& CyclicString::getAlphabet() const { + return alphabet; +} + +bool CyclicString::addSymbolToAlphabet(const alphabet::Symbol & symbol) { + return alphabet.insert(symbol).second; +} + +void CyclicString::setAlphabet(const std::set<alphabet::Symbol> & symbols) { + std::set<alphabet::Symbol> minimalAlphabet(m_Data.begin(), m_Data.end()); + std::set<alphabet::Symbol> removedSymbols; + std::set_difference(minimalAlphabet.begin(), minimalAlphabet.end(), symbols.begin(), symbols.end(), std::inserter(removedSymbols, removedSymbols.end())); + + if(removedSymbols.size() > 0) + throw exception::AlibException("Input symbols are used."); + + this->alphabet = symbols; +} + +bool CyclicString::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) { + if(std::any_of(m_Data.begin(), m_Data.end(), [&](const alphabet::Symbol & s) { return s == symbol; } ) ) + throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is used."); + + return alphabet.erase(symbol); +} + bool CyclicString::operator <(const StringBase& other) const { return other > *this; } @@ -55,6 +87,28 @@ const std::vector<alphabet::Symbol>& CyclicString::getContent() const { return this->m_Data; } +void CyclicString::setContent(const std::vector<alphabet::Symbol>& data) { + std::set<alphabet::Symbol> minimalAlphabet(data.begin(), data.end()); + std::set<alphabet::Symbol> unknownSymbols; + std::set_difference(minimalAlphabet.begin(), minimalAlphabet.end(), alphabet.begin(), alphabet.end(), std::inserter(unknownSymbols, unknownSymbols.end())); + + if(unknownSymbols.size() > 0) + throw exception::AlibException("Input symbols not in the alphabet."); + + this->m_Data = data; +} + +void CyclicString::setContent(std::vector<alphabet::Symbol>&& data) { + std::set<alphabet::Symbol> minimalAlphabet(data.begin(), data.end()); + std::set<alphabet::Symbol> unknownSymbols; + std::set_difference(minimalAlphabet.begin(), minimalAlphabet.end(), alphabet.begin(), alphabet.end(), std::inserter(unknownSymbols, unknownSymbols.end())); + + if(unknownSymbols.size() > 0) + throw exception::AlibException("Input symbols not in the alphabet."); + + this->m_Data = std::move(data); +} + bool CyclicString::isEmpty() const { return this->m_Data.size() == 0; } diff --git a/alib2data/src/string/CyclicString.h b/alib2data/src/string/CyclicString.h index 731d8f13e07fd9ce2482dcfbfb15f6e0908cb510..0bc8247f6673575b82431fb5e73a376c71bcc470 100644 --- a/alib2data/src/string/CyclicString.h +++ b/alib2data/src/string/CyclicString.h @@ -23,18 +23,23 @@ namespace string { * as a tree of CyclicStringElement. */ class CyclicString : public std::element<CyclicString, StringBase> { -protected: + std::set<alphabet::Symbol> alphabet; std::vector<alphabet::Symbol> m_Data; - - virtual bool testSymbol( const alphabet::Symbol & symbol ) const; - virtual void computeMinimalAlphabet(std::set<alphabet::Symbol>&) const; public: + CyclicString(); + explicit CyclicString(const std::set<alphabet::Symbol>& alphabet, const std::vector<alphabet::Symbol>& data); + explicit CyclicString(std::set<alphabet::Symbol>&& alphabet, std::vector<alphabet::Symbol>&& data); explicit CyclicString(const std::vector<alphabet::Symbol>& data); explicit CyclicString(std::vector<alphabet::Symbol>&& data); virtual StringBase* clone() const; virtual StringBase* plunder() &&; + const std::set<alphabet::Symbol>& getAlphabet() const; + bool addSymbolToAlphabet(const alphabet::Symbol & symbol); + void setAlphabet(const std::set<alphabet::Symbol>& alphabet); + bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol); + virtual bool operator <(const StringBase& other) const; virtual bool operator ==(const StringBase& other) const; virtual bool operator >(const StringBase& other) const; @@ -44,6 +49,10 @@ public: */ const std::vector<alphabet::Symbol>& getContent() const; + void setContent(const std::vector<alphabet::Symbol>& data); + + void setContent(std::vector<alphabet::Symbol>&& data); + /** * @return true if string is an empty word (vector length is 0) */ diff --git a/alib2data/src/string/Epsilon.cpp b/alib2data/src/string/Epsilon.cpp index 60aaa1a7b6275322723caa93a3d66826699a233a..9fd1af518c0f1e3b017c895685c006ec4f4bca35 100644 --- a/alib2data/src/string/Epsilon.cpp +++ b/alib2data/src/string/Epsilon.cpp @@ -17,20 +17,28 @@ Epsilon::Epsilon() { } -bool Epsilon::testSymbol( const alphabet::Symbol & ) const { - return false; +StringBase* Epsilon::clone() const { + return new Epsilon(*this); } -void Epsilon::computeMinimalAlphabet(std::set<alphabet::Symbol>&) const { +StringBase* Epsilon::plunder() && { + return new Epsilon(std::move(*this)); +} +const std::set<alphabet::Symbol>& Epsilon::getAlphabet() const { + return alphabet; } -StringBase* Epsilon::clone() const { - return new Epsilon(*this); +bool Epsilon::addSymbolToAlphabet(const alphabet::Symbol & symbol) { + return alphabet.insert(symbol).second; } -StringBase* Epsilon::plunder() && { - return new Epsilon(std::move(*this)); +void Epsilon::setAlphabet(const std::set<alphabet::Symbol> & symbols) { + this->alphabet = symbols; +} + +bool Epsilon::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) { + return alphabet.erase(symbol); } bool Epsilon::operator<(const StringBase& other) const { @@ -54,15 +62,15 @@ bool Epsilon::isEmpty() const { } bool Epsilon::operator<(const Epsilon&) const { - return false; + return false; } bool Epsilon::operator<(const LinearString& other) const { - return LinearString({}) < other; + return LinearString {} < other; } bool Epsilon::operator<(const CyclicString& other) const { - return CyclicString({}) < other; + return CyclicString {} < other; } bool Epsilon::operator==(const Epsilon&) const { @@ -70,11 +78,11 @@ bool Epsilon::operator==(const Epsilon&) const { } bool Epsilon::operator==(const LinearString& other) const { - return LinearString({}) == other; + return LinearString {} == other; } bool Epsilon::operator==(const CyclicString& other) const { - return CyclicString({}) == other; + return CyclicString {} == other; } void Epsilon::operator>>(std::ostream& out) const { diff --git a/alib2data/src/string/Epsilon.h b/alib2data/src/string/Epsilon.h index 5842f9358a723c3f35a0bbc09297f19114e69193..f7d2f467e088af5c324a70c88a4086fcd391c2ea 100644 --- a/alib2data/src/string/Epsilon.h +++ b/alib2data/src/string/Epsilon.h @@ -23,16 +23,18 @@ namespace string { * as a tree of EpsilonElement. */ class Epsilon : public std::element<Epsilon, StringBase> { -protected: - - virtual bool testSymbol( const alphabet::Symbol & symbol ) const; - virtual void computeMinimalAlphabet(std::set<alphabet::Symbol>&) const; + std::set<alphabet::Symbol> alphabet; public: Epsilon(); virtual StringBase* clone() const; virtual StringBase* plunder() &&; + const std::set<alphabet::Symbol>& getAlphabet() const; + bool addSymbolToAlphabet(const alphabet::Symbol & symbol); + void setAlphabet(const std::set<alphabet::Symbol>& alphabet); + bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol); + virtual bool operator <(const StringBase& other) const; virtual bool operator ==(const StringBase& other) const; virtual bool operator >(const StringBase& other) const; diff --git a/alib2data/src/string/LinearString.cpp b/alib2data/src/string/LinearString.cpp index e5384e17d5e5b145acbab4c3d56769dda1941133..989e0cf81ed7f30e7e2223ef3188ee32efce0572 100644 --- a/alib2data/src/string/LinearString.cpp +++ b/alib2data/src/string/LinearString.cpp @@ -6,6 +6,8 @@ */ #include "LinearString.h" +#include "../exception/AlibException.h" + #include <cassert> #include <sstream> #include <algorithm> @@ -15,20 +17,24 @@ namespace string { -LinearString::LinearString(const std::vector<alphabet::Symbol>& data) : m_Data(data) { +LinearString::LinearString() { } -LinearString::LinearString(std::vector<alphabet::Symbol>&& data) : m_Data(std::move(data)) { +LinearString::LinearString(const std::set<alphabet::Symbol>& alphabet, const std::vector<alphabet::Symbol>& data) : alphabet(alphabet) { + setContent(data); +} +LinearString::LinearString(std::set<alphabet::Symbol>&& alphabet, std::vector<alphabet::Symbol>&& data) : alphabet(std::move(alphabet)) { + setContent(std::move(data)); } -bool LinearString::testSymbol( const alphabet::Symbol & symbol ) const { - return std::any_of(m_Data.begin(), m_Data.end(), [&](const alphabet::Symbol & s) { return s == symbol; } ); +LinearString::LinearString(const std::vector<alphabet::Symbol>& data) : alphabet(data.begin(), data.end()) { + m_Data = data; } -void LinearString::computeMinimalAlphabet(std::set<alphabet::Symbol>& alphabet) const { - alphabet.insert(m_Data.begin(), m_Data.end()); +LinearString::LinearString(std::vector<alphabet::Symbol>&& data) : alphabet(data.begin(), data.end()) { + m_Data = std::move(data); } StringBase* LinearString::clone() const { @@ -39,6 +45,44 @@ StringBase* LinearString::plunder() && { return new LinearString(std::move(*this)); } +const std::set<alphabet::Symbol>& LinearString::getAlphabet() const { + return alphabet; +} + +bool LinearString::addSymbolToAlphabet(const alphabet::Symbol & symbol) { + return alphabet.insert(symbol).second; +} + +void LinearString::setAlphabet(const std::set<alphabet::Symbol> & symbols) { + std::set<alphabet::Symbol> minimalAlphabet(m_Data.begin(), m_Data.end()); + std::set<alphabet::Symbol> removedSymbols; + std::set_difference(minimalAlphabet.begin(), minimalAlphabet.end(), symbols.begin(), symbols.end(), std::inserter(removedSymbols, removedSymbols.end())); + + if(removedSymbols.size() > 0) + throw exception::AlibException("Input symbols are used."); + + this->alphabet = symbols; +} + +bool LinearString::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) { + if(std::any_of(m_Data.begin(), m_Data.end(), [&](const alphabet::Symbol & s) { return s == symbol; } ) ) + throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is used."); + + return alphabet.erase(symbol); +} + +void LinearString::appendSymbol(const alphabet::Symbol& symbol) { + if(alphabet.count(symbol) == 0) + throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" not in the alphabet."); + m_Data.push_back(symbol); +} + +void LinearString::appendSymbol(alphabet::Symbol&& symbol) { + if(alphabet.count(symbol) == 0) + throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" not in the alphabet."); + m_Data.push_back(std::move(symbol)); +} + bool LinearString::operator<(const StringBase& other) const { return other > *this; } @@ -55,6 +99,28 @@ const std::vector<alphabet::Symbol>& LinearString::getContent() const { return this->m_Data; } +void LinearString::setContent(const std::vector<alphabet::Symbol>& data) { + std::set<alphabet::Symbol> minimalAlphabet(data.begin(), data.end()); + std::set<alphabet::Symbol> unknownSymbols; + std::set_difference(minimalAlphabet.begin(), minimalAlphabet.end(), alphabet.begin(), alphabet.end(), std::inserter(unknownSymbols, unknownSymbols.end())); + + if(unknownSymbols.size() > 0) + throw exception::AlibException("Input symbols not in the alphabet."); + + this->m_Data = data; +} + +void LinearString::setContent(std::vector<alphabet::Symbol>&& data) { + std::set<alphabet::Symbol> minimalAlphabet(data.begin(), data.end()); + std::set<alphabet::Symbol> unknownSymbols; + std::set_difference(minimalAlphabet.begin(), minimalAlphabet.end(), alphabet.begin(), alphabet.end(), std::inserter(unknownSymbols, unknownSymbols.end())); + + if(unknownSymbols.size() > 0) + throw exception::AlibException("Input symbols not in the alphabet."); + + this->m_Data = std::move(data); +} + bool LinearString::isEmpty() const { return this->m_Data.size() == 0; } @@ -74,7 +140,7 @@ bool LinearString::operator<(const Epsilon& other) const { } bool LinearString::operator==(const LinearString& other) const { - return m_Data == other.m_Data; + return m_Data == other.m_Data && alphabet == other.alphabet; } bool LinearString::operator==(const CyclicString& other) const { diff --git a/alib2data/src/string/LinearString.h b/alib2data/src/string/LinearString.h index 359c57af808b26e797bfa6aa9487ca6f1e39277a..89b33a2f3daa3bb8a2f74ffd6a3cfcdef8bc882b 100644 --- a/alib2data/src/string/LinearString.h +++ b/alib2data/src/string/LinearString.h @@ -23,18 +23,31 @@ namespace string { * as a tree of LinearStringElement. */ class LinearString : public std::element<LinearString, StringBase> { -protected: + std::set<alphabet::Symbol> alphabet; std::vector<alphabet::Symbol> m_Data; - virtual bool testSymbol( const alphabet::Symbol & symbol ) const; - virtual void computeMinimalAlphabet(std::set<alphabet::Symbol>&) const; public: + LinearString(); + explicit LinearString(const std::set<alphabet::Symbol>& alphabet, const std::vector<alphabet::Symbol>& data); + explicit LinearString(std::set<alphabet::Symbol>&& alphabet, std::vector<alphabet::Symbol>&& data); explicit LinearString(const std::vector<alphabet::Symbol>& data); explicit LinearString(std::vector<alphabet::Symbol>&& data); virtual StringBase* clone() const; virtual StringBase* plunder() &&; + const std::set<alphabet::Symbol>& getAlphabet() const; + bool addSymbolToAlphabet(const alphabet::Symbol & symbol); + void setAlphabet(const std::set<alphabet::Symbol>& alphabet); + bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol); + + /** + * @param element to append + */ + void appendSymbol(const alphabet::Symbol& symbol); + + void appendSymbol(alphabet::Symbol&& symbol); + virtual bool operator <(const StringBase& other) const; virtual bool operator ==(const StringBase& other) const; virtual bool operator >(const StringBase& other) const; @@ -44,6 +57,10 @@ public: */ const std::vector<alphabet::Symbol>& getContent() const; + void setContent(const std::vector<alphabet::Symbol>& data); + + void setContent(std::vector<alphabet::Symbol>&& data); + /** * @return true if string is an empty word (vector length is 0) */ diff --git a/alib2data/src/string/MutableString.cpp b/alib2data/src/string/MutableString.cpp deleted file mode 100644 index c1a5a61997be0cad3a3126a07a79e44302175553..0000000000000000000000000000000000000000 --- a/alib2data/src/string/MutableString.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* - * MutableString.cpp - * - * Created on: Nov 23, 2013 - * Author: Jan Travnicek - */ - -#include "MutableString.h" - -namespace string { - -void MutableString::appendSymbol(alphabet::Symbol&& symbol) { - this->m_Data.push_back(std::move(symbol)); -} - -void MutableString::appendSymbol(const alphabet::Symbol& symbol) { - this->m_Data.push_back(symbol); -} - -} /* namespace string */ diff --git a/alib2data/src/string/MutableString.h b/alib2data/src/string/MutableString.h deleted file mode 100644 index 99f2473c7ef6564f0ad8a54d2262db998a9f1f61..0000000000000000000000000000000000000000 --- a/alib2data/src/string/MutableString.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * MutableString.h - * - * Created on: Nov 23, 2013 - * Author: Jan Travnicek - */ - -#ifndef MUTABLE_STRING_H_ -#define MUTABLE_STRING_H_ - -#include <iostream> - -#include "LinearString.h" - -namespace string { - -/** - * Represents regular expression parsed from the XML. Regular expression is stored - * as a tree of StringElement. - */ -class MutableString : public LinearString { -public: - /** - * @param symbol to append - */ - void appendSymbol(alphabet::Symbol&& symbol); - - /** - * @param symbol to append - */ - void appendSymbol(const alphabet::Symbol& symbol); - -}; - -} /* namespace string */ - -#endif /* MUTABLE_STRING_H_ */ diff --git a/alib2data/src/string/String.cpp b/alib2data/src/string/String.cpp index acbff3d6b79f51323f618381c347f7db5f3b2cff..21a97e3b2c1261c44792cfea6129cd7dc244dff7 100644 --- a/alib2data/src/string/String.cpp +++ b/alib2data/src/string/String.cpp @@ -16,30 +16,19 @@ String::String() : string(NULL) { setString(Epsilon()); } -String::String(const std::set<alphabet::Symbol>& alphabet, const StringBase& string) : string(NULL), alphabet(alphabet) { - setString(string); -} - -String::String(std::set<alphabet::Symbol>&& alphabet, StringBase&& string) : string(NULL), alphabet(alphabet) { - setString(std::move(string)); -} - String::String(const StringBase& string) : string(NULL) { - string.computeMinimalAlphabet(alphabet); setString(string); } String::String(StringBase&& string) : string(NULL) { - string.computeMinimalAlphabet(alphabet); - setString(string); + setString(std::move(string)); } -String::String(const String& other) : string(other.getString().clone()), alphabet(other.alphabet) { - this->string->attachString(this); +String::String(const String& other) : string(other.getString().clone()) { + } -String::String(String&& other) noexcept : string(other.string), alphabet(std::move(other.alphabet)) { - this->string->attachString(this); +String::String(String&& other) noexcept : string(other.string) { other.string = NULL; } @@ -53,7 +42,7 @@ String& String::operator=(const String& other) { String& String::operator=(String&& other) noexcept { std::swap(this->string, other.string); - std::swap(this->alphabet, other.alphabet); + return *this; } @@ -72,54 +61,15 @@ StringBase& String::getString() { void String::setString(const StringBase& string) { delete this->string; this->string = string.clone(); - - if(!this->string->attachString(this)) - throw exception::AlibException("String symbols not in the alphabet"); } void String::setString(StringBase&& string) { delete this->string; this->string = std::move(string).plunder(); - - if(!this->string->attachString(this)) - throw exception::AlibException("String symbols not in the alphabet"); -} - -const std::set<alphabet::Symbol>& String::getAlphabet() const { - return alphabet; -} - -bool String::addSymbolToAlphabet(const alphabet::Symbol & symbol) { - return alphabet.insert(symbol).second; -} - -void String::setAlphabet(const std::set<alphabet::Symbol> & symbols) { - std::set<alphabet::Symbol> minimalAlphabet; - this->string->computeMinimalAlphabet(minimalAlphabet); - std::set<alphabet::Symbol> removedSymbols; - std::set_difference(minimalAlphabet.begin(), minimalAlphabet.end(), symbols.begin(), symbols.end(), std::inserter(removedSymbols, removedSymbols.end())); - - if(removedSymbols.size() > 0) - throw exception::AlibException("Input symbols are used."); - - this->alphabet = symbols; -} - -bool String::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) { - if(this->string->testSymbol(symbol)) - throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is used."); - - return alphabet.erase(symbol); } bool String::operator<(const String& other) const { - if(*(this->string) < *(other.string)) { - return true; - } else if(*(this->string) > *(other.string)) { - return false; - } else { - return this->alphabet < other.alphabet; - } + return *(this->string) < *(other.string); } bool String::operator!=(const String& other) const { @@ -127,7 +77,7 @@ bool String::operator!=(const String& other) const { } bool String::operator==(const String& other) const { - return *string == *other.string && alphabet == other.alphabet; + return *string == *other.string; } std::ostream& operator<<(std::ostream& os, const String& string) { diff --git a/alib2data/src/string/String.h b/alib2data/src/string/String.h index 668f1994f6379b0b835a9590f3e6f4eee64d2ccc..4a653732ac673db78681d1d8719f7968f2cf8dc0 100644 --- a/alib2data/src/string/String.h +++ b/alib2data/src/string/String.h @@ -23,12 +23,9 @@ class StringBase; class String { protected: StringBase* string; - std::set<alphabet::Symbol> alphabet; public: explicit String(); - explicit String(const std::set<alphabet::Symbol>& alphabet, const StringBase& string); explicit String(const StringBase& string); - explicit String(std::set<alphabet::Symbol>&& alphabet, StringBase&& string); explicit String(StringBase&& string); String(const String& other); String(String&&) noexcept; @@ -42,11 +39,6 @@ public: void setString(const StringBase& string); void setString(StringBase&& string); - const std::set<alphabet::Symbol>& getAlphabet() const; - bool addSymbolToAlphabet(const alphabet::Symbol & symbol); - void setAlphabet(const std::set<alphabet::Symbol>& alphabet); - bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol); - bool operator<(const String& other) const; bool operator!=(const String& other) const; diff --git a/alib2data/src/string/StringAlphabetGetter.cpp b/alib2data/src/string/StringAlphabetGetter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8fb6656d541e5915bd63bae453170799297854c4 --- /dev/null +++ b/alib2data/src/string/StringAlphabetGetter.cpp @@ -0,0 +1,43 @@ +/* + * StringAlphabetGetter.cpp + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#include "StringAlphabetGetter.h" + +namespace string { + +void StringAlphabetGetter::Visit(void* userData, const String& string) const { + string.getString().Accept(userData, *this); +} + +void StringAlphabetGetter::Visit(void* userData, const StringBase::element_type& element) const { + element.Accept(userData, *this); +} + +void StringAlphabetGetter::Visit(void* userData, const CyclicString& string) const { + std::set<alphabet::Symbol> &res = *((std::set<alphabet::Symbol>*) userData); + res = string.getAlphabet(); +} + +void StringAlphabetGetter::Visit(void* userData, const Epsilon& string) const { + std::set<alphabet::Symbol> &res = *((std::set<alphabet::Symbol>*) userData); + res = string.getAlphabet(); +} + +void StringAlphabetGetter::Visit(void* userData, const LinearString& string) const { + std::set<alphabet::Symbol> &res = *((std::set<alphabet::Symbol>*) userData); + res = string.getAlphabet(); +} + +std::set<alphabet::Symbol> StringAlphabetGetter::getAlphabet(const String& string) const { + std::set<alphabet::Symbol> res; + string.getString().Accept((void*) &res, *this); + return std::move(res); +} + +const StringAlphabetGetter StringAlphabetGetter::STRING_ALPHABET_GETTER; + +} /* namespace string */ diff --git a/alib2data/src/string/StringAlphabetGetter.h b/alib2data/src/string/StringAlphabetGetter.h new file mode 100644 index 0000000000000000000000000000000000000000..21b72c9274159656705af57a71c913e34a28591d --- /dev/null +++ b/alib2data/src/string/StringAlphabetGetter.h @@ -0,0 +1,42 @@ +/* + * StringAlphabetGetter.h + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#ifndef STRING_ALPHABET_GETTER_H_ +#define STRING_ALPHABET_GETTER_H_ + +#include <set> +#include "String.h" +#include "../alphabet/Symbol.h" +#include "CyclicString.h" +#include "LinearString.h" +#include "Epsilon.h" + +namespace string { + +class StringAlphabetGetter : public StringBase::const_visitor_type { + void Visit(void*, const CyclicString& empty) const; + void Visit(void*, const Epsilon& empty) const; + void Visit(void*, const LinearString& empty) const; + + void Visit(void*, const StringBase::element_type& element) const; + + void Visit(void*, const String& empty) const; + +public: + /** + * Composes string representation of String. + * @param string String to print + * @returns string representation of string + */ + std::set<alphabet::Symbol> getAlphabet(const String& string) const; + + static const StringAlphabetGetter STRING_ALPHABET_GETTER; +}; + +} /* namespace string */ + +#endif /* STRING_ALPHABET_GETTER_H_ */ diff --git a/alib2data/src/string/StringBase.cpp b/alib2data/src/string/StringBase.cpp index e4a71a536c8e4fb9ebc86ffcbad4281f06a5545b..6b1f462c37efe0f3e1ac012a2994d1935a8a5e5c 100644 --- a/alib2data/src/string/StringBase.cpp +++ b/alib2data/src/string/StringBase.cpp @@ -15,7 +15,7 @@ namespace string { -StringBase::StringBase() : parentString(NULL) { +StringBase::StringBase() { } @@ -23,19 +23,6 @@ StringBase::~StringBase() noexcept { } -bool StringBase::attachString ( const String * string ) { - if(this->parentString == string) return true; - this->parentString = string; - if(string == NULL) return true; - - std::set<alphabet::Symbol> minimalAlphabet; - this->computeMinimalAlphabet(minimalAlphabet); - std::set<alphabet::Symbol> unavailableSymbols; - std::set_difference(minimalAlphabet.begin(), minimalAlphabet.end(), this->parentString->getAlphabet().begin(), this->parentString->getAlphabet().end(), std::inserter(unavailableSymbols, unavailableSymbols.end())); - - return unavailableSymbols.empty(); -} - bool StringBase::operator !=(const StringBase& other) const { return !(*this == other); } diff --git a/alib2data/src/string/StringBase.h b/alib2data/src/string/StringBase.h index 72979c3508de9a0b5ef3539c51e3e36388543ac8..b9ff980f05925f5e088f1f1f9747165ff86c1c09 100644 --- a/alib2data/src/string/StringBase.h +++ b/alib2data/src/string/StringBase.h @@ -26,31 +26,6 @@ class Epsilon; * Represents string in an alphabet. */ class StringBase : public std::elementBase<Epsilon, LinearString, CyclicString> { -protected: - const String* parentString; - - /** - * Traverses the string tree looking wheter a particular Symbol is used in the string. - * - * @param symbol to test wheter used in string - * @return true if symbol is used by the element and its successor - */ - virtual bool testSymbol( const alphabet::Symbol & symbol ) const = 0; - - /** - * Attaches the string to this instance - * @param string parent string to attach as parent - * @return true if symbols used in string are in the regexp's alphabet - */ - bool attachString ( const String * string ); - - /** - * Traverses the string tree computing minimal alphabet needed by the string - * - * @param alphabet All alphabet symbols encountered are added into this set - * @return true if symbol is used by the element and its successor - */ - virtual void computeMinimalAlphabet(std::set<alphabet::Symbol>&) const = 0; public: StringBase(); virtual ~StringBase() noexcept; diff --git a/alib2data/src/string/StringFromXMLParser.cpp b/alib2data/src/string/StringFromXMLParser.cpp index 02f306c3b62f46a29cb09db1af4aacca0d89ccdc..8d14f73ee1f1f54a3f162cea7025e329b743487a 100644 --- a/alib2data/src/string/StringFromXMLParser.cpp +++ b/alib2data/src/string/StringFromXMLParser.cpp @@ -20,13 +20,8 @@ String StringFromXMLParser::parse(std::list<sax::Token>& input) const { } String StringFromXMLParser::parse(std::list<sax::Token>& input, const std::set<FEATURES>& features) const { - popToken(input, sax::Token::TokenType::START_ELEMENT, "string"); - String string; - parseAlphabet(input, string); parseContent(input, string, features); - - popToken(input, sax::Token::TokenType::END_ELEMENT, "string"); return string; } @@ -35,31 +30,52 @@ void StringFromXMLParser::parseContent(std::list<sax::Token>& input, String& str if(isToken(input, sax::Token::TokenType::START_ELEMENT, "Epsilon")) { if(!features.count(FEATURES::EPSILON)) throw exception::AlibException(); popToken(input, sax::Token::TokenType::START_ELEMENT, "Epsilon"); + + Epsilon epsilon; + std::set<alphabet::Symbol> alphabet = parseAlphabet(input); + epsilon.setAlphabet(alphabet); + popToken(input, sax::Token::TokenType::END_ELEMENT, "Epsilon"); - string.setString(Epsilon()); + string.setString(epsilon); } else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "LinearString")) { if(!features.count(FEATURES::LINEAR)) throw exception::AlibException(); popToken(input, sax::Token::TokenType::START_ELEMENT, "LinearString"); + + LinearString linearString; + std::set<alphabet::Symbol> alphabet = parseAlphabet(input); + linearString.setAlphabet(alphabet); + std::vector<alphabet::Symbol> data = parseContentData(input); + linearString.setContent(data); + popToken(input, sax::Token::TokenType::END_ELEMENT, "LinearString"); - string.setString(LinearString(data)); + string.setString(linearString); } else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "CyclicString")) { if(!features.count(FEATURES::CYCLIC)) throw exception::AlibException(); popToken(input, sax::Token::TokenType::START_ELEMENT, "CyclicString"); + + CyclicString cyclicString; + std::set<alphabet::Symbol> alphabet = parseAlphabet(input); + cyclicString.setAlphabet(alphabet); + std::vector<alphabet::Symbol> data = parseContentData(input); + cyclicString.setContent(data); + + string.setString(cyclicString); popToken(input, sax::Token::TokenType::END_ELEMENT, "CyclicString"); - string.setString(CyclicString(data)); } else { throw sax::ParserException(sax::Token("Epsilon, LinearString, CyclicString", sax::Token::TokenType::START_ELEMENT), input.front()); } } -void StringFromXMLParser::parseAlphabet(std::list<sax::Token> &input, String& string) const { +std::set<alphabet::Symbol> StringFromXMLParser::parseAlphabet(std::list<sax::Token> &input) const { + std::set<alphabet::Symbol> alphabet; popToken(input, sax::Token::TokenType::START_ELEMENT, "alphabet"); while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { - string.addSymbolToAlphabet(alib::FromXMLParsers::symbolParser.parse(input)); + alphabet.insert(alib::FromXMLParsers::symbolParser.parse(input)); } popToken(input, sax::Token::TokenType::END_ELEMENT, "alphabet"); + return alphabet; } bool StringFromXMLParser::first(std::list<sax::Token>& input) const { diff --git a/alib2data/src/string/StringFromXMLParser.h b/alib2data/src/string/StringFromXMLParser.h index abd34b58ff68e56a3eef7cd80cf862d90571f336..a1eb7fcc1ea9584ef064f69f3eb05e59b2f83981 100644 --- a/alib2data/src/string/StringFromXMLParser.h +++ b/alib2data/src/string/StringFromXMLParser.h @@ -30,7 +30,7 @@ namespace string { class StringFromXMLParser : public alib::FromXMLParser<String, FEATURES> { void parseContent(std::list<sax::Token>& input, String& string, const std::set<FEATURES>& features) const; std::vector<alphabet::Symbol> parseContentData(std::list<sax::Token>& input) const; - void parseAlphabet(std::list<sax::Token> &input, String& string) const; + std::set<alphabet::Symbol> parseAlphabet(std::list<sax::Token> &input) const; virtual String parse(std::list<sax::Token>& input) const; virtual String parse(std::list<sax::Token>& input, const std::set<FEATURES>& features) const; diff --git a/alib2data/src/string/StringToXMLComposer.cpp b/alib2data/src/string/StringToXMLComposer.cpp index dd2dc52d714b0001f7663cf65fdd94ba14543fc8..9a7278356bee4999ad442a162e89aaaf947afcae 100644 --- a/alib2data/src/string/StringToXMLComposer.cpp +++ b/alib2data/src/string/StringToXMLComposer.cpp @@ -14,10 +14,15 @@ namespace string { -void StringToXMLComposer::Visit(void* userData, const Epsilon&) const { +void StringToXMLComposer::Visit(void* userData, const Epsilon& string) const { std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); out.push_back(sax::Token("Epsilon", sax::Token::TokenType::START_ELEMENT)); + out.push_back(sax::Token("alphabet", sax::Token::TokenType::START_ELEMENT)); + for (const auto& symbol: string.getAlphabet()) { + out.splice(out.end(), alib::ToXMLComposers::symbolComposer.compose(symbol)); + } + out.push_back(sax::Token("alphabet", sax::Token::TokenType::END_ELEMENT)); out.push_back(sax::Token("Epsilon", sax::Token::TokenType::END_ELEMENT)); } @@ -25,6 +30,12 @@ void StringToXMLComposer::Visit(void* userData, const CyclicString& string) cons std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); out.push_back(sax::Token("CyclicString", sax::Token::TokenType::START_ELEMENT)); + out.push_back(sax::Token("alphabet", sax::Token::TokenType::START_ELEMENT)); + for (const auto& symbol: string.getAlphabet()) { + out.splice(out.end(), alib::ToXMLComposers::symbolComposer.compose(symbol)); + } + out.push_back(sax::Token("alphabet", sax::Token::TokenType::END_ELEMENT)); + for(const auto& symbol : string.getContent()) { out.splice(out.end(), alib::ToXMLComposers::symbolComposer.compose(symbol)); } @@ -35,6 +46,12 @@ void StringToXMLComposer::Visit(void* userData, const LinearString& string) cons std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); out.push_back(sax::Token("LinearString", sax::Token::TokenType::START_ELEMENT)); + out.push_back(sax::Token("alphabet", sax::Token::TokenType::START_ELEMENT)); + for (const auto& symbol: string.getAlphabet()) { + out.splice(out.end(), alib::ToXMLComposers::symbolComposer.compose(symbol)); + } + out.push_back(sax::Token("alphabet", sax::Token::TokenType::END_ELEMENT)); + for(const auto& symbol : string.getContent()) { out.splice(out.end(), alib::ToXMLComposers::symbolComposer.compose(symbol)); } @@ -42,18 +59,7 @@ void StringToXMLComposer::Visit(void* userData, const LinearString& string) cons } void StringToXMLComposer::Visit(void* userData, const String& string) const { - std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); - - out.push_back(sax::Token("string", sax::Token::TokenType::START_ELEMENT)); - { - out.push_back(sax::Token("alphabet", sax::Token::TokenType::START_ELEMENT)); - for (const auto& symbol: string.getAlphabet()) { - out.splice(out.end(), alib::ToXMLComposers::symbolComposer.compose(symbol)); - } - out.push_back(sax::Token("alphabet", sax::Token::TokenType::END_ELEMENT)); - } string.getString().Accept(userData, *this); - out.push_back(sax::Token("string", sax::Token::TokenType::END_ELEMENT)); } std::list<sax::Token> StringToXMLComposer::compose(const String& string) const { diff --git a/alib2data/test-src/string/StringTest.cpp b/alib2data/test-src/string/StringTest.cpp index 97ef77ab6653a718a66b96fbffa01d723a606747..d3f2a72e9edfaacfb90ded18ae669c8823997cdd 100644 --- a/alib2data/test-src/string/StringTest.cpp +++ b/alib2data/test-src/string/StringTest.cpp @@ -32,14 +32,14 @@ void StringTest::tearDown() { } void StringTest::testCopyConstruct() { - string::String string; - string.setAlphabet({alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("3"))))}); - string.setString(string::LinearString({ + string::LinearString linearString; + linearString.setAlphabet({alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("3"))))}); + linearString.setContent({ alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))) - })); - + }); + string::String string(linearString); string::String string2(string); CPPUNIT_ASSERT( string == string2 ); @@ -108,14 +108,14 @@ void StringTest::testEqual() { void StringTest::testXMLParser() { - string::String string; - string.setAlphabet({alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("3"))))}); - string.setString(string::LinearString({alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))), + string::LinearString linearString; + linearString.setAlphabet({alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("3"))))}); + linearString.setContent({alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1"))))} - ) - ); + ); + string::String string(linearString); { string::StringToXMLComposer composer; std::list<sax::Token> tokens = composer.compose(string); @@ -138,9 +138,9 @@ void StringTest::testXMLParser() { } void StringTest::testCompare() { - string::String linear({}, string::LinearString({})); - string::String cyclic({}, string::CyclicString({})); - string::String epsilon({}, string::Epsilon({})); + string::String linear(string::LinearString {}); + string::String cyclic(string::CyclicString {}); + string::String epsilon(string::Epsilon {}); CPPUNIT_ASSERT(linear == epsilon); CPPUNIT_ASSERT(cyclic == epsilon);