diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.cpp b/alib2data/src/automaton/FSM/ExtendedNFA.cpp index a9e6258b357acf6986fabc4961799831bb7e3d02..c21145a5d5190eab5740da25d489c030eefc11a8 100644 --- a/alib2data/src/automaton/FSM/ExtendedNFA.cpp +++ b/alib2data/src/automaton/FSM/ExtendedNFA.cpp @@ -10,6 +10,7 @@ #include "../AutomatonException.h" #include <ostream> #include <algorithm> +#include "../../regexp/RegExpAlphabetGetter.h" namespace automaton { @@ -41,7 +42,7 @@ bool ExtendedNFA::removeState(const State& state) { bool ExtendedNFA::removeInputSymbol(const alphabet::Symbol& symbol) { for (std::map<std::pair<State, regexp::RegExp>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end(); transition++) { - if (transition->first.second.getAlphabet().count(symbol) == 1) + if (regexp::RegExpAlphabetGetter::REG_EXP_ALPHABET_GETTER.getAlphabet(transition->first.second).count(symbol) == 1) throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used."); } @@ -52,9 +53,11 @@ bool ExtendedNFA::addTransition(const State& from, const regexp::RegExp& input, if (states.find(from) == states.end()) throw AutomatonException("State \"" + (std::string) from.getName() + "\" doesn't exist."); - std::set<alphabet::Symbol> inputRegExpAlphabet; - std::set_difference(inputAlphabet.begin(), inputAlphabet.end(), input.getAlphabet().begin(), input.getAlphabet().end(), std::inserter(inputRegExpAlphabet, inputRegExpAlphabet.end())); - if (inputRegExpAlphabet.size() != 0) + std::set<alphabet::Symbol> inputRegExpAlphabetDiff; + std::set<alphabet::Symbol> inputRegExpAlphabet = regexp::RegExpAlphabetGetter::REG_EXP_ALPHABET_GETTER.getAlphabet(input); + + std::set_difference(inputAlphabet.begin(), inputAlphabet.end(), inputRegExpAlphabet.begin(), inputRegExpAlphabet.end(), std::inserter(inputRegExpAlphabetDiff, inputRegExpAlphabetDiff.end())); + if (inputRegExpAlphabetDiff.size() != 0) throw AutomatonException("Input string is over different alphabet than automaton"); if (states.find(to) == states.end()) diff --git a/alib2data/src/regexp/Alternation.cpp b/alib2data/src/regexp/Alternation.cpp deleted file mode 100644 index a31b08964d46728bb6f1b4c9e0bdb4945cd0be4a..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/Alternation.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Alternation.cpp - * - * Created on: Nov 23, 2013 - * Author: Martin Zak - */ - -#include "Alternation.h" -#include "../exception/AlibException.h" - -namespace regexp { - -Alternation::Alternation(RegExpElement&& left, RegExpElement&& right) { - appendElement(std::move(left)); - appendElement(std::move(right)); -} - -Alternation::Alternation(const RegExpElement& left, const RegExpElement& right) { - appendElement(left); - appendElement(right); -} - -Alternation::Alternation(const Alternation& other) { - for (const auto& element : other.elements) { - elements.push_back(element->clone()); - } -} - -Alternation::Alternation(Alternation&& other) noexcept : elements(std::move(other.elements)) { - other.elements.clear(); - this->attachRegExp(NULL); -} - -Alternation& Alternation::operator=(const Alternation& other) { - if (this == &other) { - return *this; - } - - *this = Alternation(other); - - return *this; -} - -Alternation& Alternation::operator=(Alternation&& other) { - std::swap(this->elements, other.elements); - std::swap(this->parentRegExp, other.parentRegExp); - - this->attachRegExp(other.parentRegExp); - - return *this; -} - -Alternation::~Alternation() noexcept { - for (auto element : elements) { - delete element; - } - elements.clear(); -} - -const std::vector<const RegExpElement*> & Alternation::getElements() const { - return * reinterpret_cast<const std::vector<const RegExpElement*> * > (&elements); -} - -const std::vector<RegExpElement*> & Alternation::getElements() { - return elements; -} - -void Alternation::appendElement(const RegExpElement& element) { - RegExpElement* elem = element.clone(); - if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) - throw exception::AlibException("Input symbols not in the alphabet."); - this->elements.push_back(elem); -} - -void Alternation::appendElement(RegExpElement&& element) { - RegExpElement* elem = std::move(element).plunder(); - if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) - throw exception::AlibException("Input symbols not in the alphabet."); - this->elements.push_back(elem); -} - -RegExpElement* Alternation::clone() const { - return new Alternation(*this); -} - -RegExpElement* Alternation::plunder() && { - return new Alternation(std::move(*this)); -} - -bool Alternation::operator<(const RegExpElement& other) const { - return other > *this; -} - -bool Alternation::operator==(const RegExpElement& other) const { - return other == *this; -} - -bool Alternation::operator>(const RegExpElement& other) const { - return other < *this; -} - - -bool Alternation::operator<(const Alternation& other) const { - int thisSize = this->elements.size(); - int otherSize = other.elements.size(); - if(thisSize < otherSize) return true; - if(thisSize > otherSize) return false; - - auto thisIter = this->elements.begin(); - auto otherIter = other.elements.begin(); - for(; thisIter != this->elements.end(); thisIter++, otherIter++) { - if(**thisIter != **otherIter) break; - } - if(thisIter == this->elements.end()) return false; - - return **thisIter < **otherIter; -} - -bool Alternation::operator==(const Alternation& other) const { - if(this->elements.size() != other.elements.size()) return false; - - auto thisIter = this->elements.begin(); - auto otherIter = other.elements.begin(); - for(; thisIter != this->elements.end(); thisIter++, otherIter++) { - if(**thisIter != **otherIter) return false; - } - - return true; -} - -void Alternation::operator>>(std::ostream& out) const { - out << "(Alternation"; - for(const auto& e : elements) - out << " " << *e; - - out << ")"; -} - -bool Alternation::testSymbol( const alphabet::Symbol & symbol ) const { - for(const auto& child : this->elements) - if(child->testSymbol(symbol)) return true; - return false; -} - -bool Alternation::attachRegExp(const RegExp * regexp ) { - if(this->parentRegExp == regexp) return true; - - this->parentRegExp = regexp; - for(const auto& child : this->elements) - if(!child->attachRegExp(regexp)) return false; - return true; -} - -void Alternation::computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const { - for(const auto& child : this->elements) - child->computeMinimalAlphabet(alphabet); -} - -bool Alternation::containsEmptyString() const { - for(const auto& e : elements) - if(e->containsEmptyString()) - return true; - - return false; // alternation of zero regexps is empty (this cannot happen) so by default it doesn't contain epsilon -} - -bool Alternation::isEmpty() const { - for(const auto& e : elements) - if(!e->isEmpty()) - return false; - - return true; // alternation of zero regexps is empty (this cannot happen) but by default it is empty -} - -} /* namespace regexp */ diff --git a/alib2data/src/regexp/Alternation.h b/alib2data/src/regexp/Alternation.h deleted file mode 100644 index 7a8dfcea7b6d81c327d20bd2a120e15a71b8122a..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/Alternation.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Alternation.h - * - * Created on: Nov 23, 2013 - * Author: Martin Zak - */ - -#ifndef ALTERNATION_H_ -#define ALTERNATION_H_ - -#include <vector> -#include "RegExpElement.h" - -namespace regexp { - -/** - * Represents alternation operator in the regular expression. Contains list of RegExpElement - * as operands of the operator. - */ -class Alternation: public std::element<Alternation, RegExpElement> { -protected: - /** - * @copydoc RegExpElement::clone() const - */ - virtual RegExpElement* clone() const; - - /** - * @copydoc RegExpElement::plunder() const - */ - virtual RegExpElement* plunder() &&; - - std::vector<RegExpElement*> elements; - - /** - * @copydoc RegExpElement::testSymbol() const - */ - virtual bool testSymbol( const alphabet::Symbol & symbol ) const; - - /** - * @copydoc RegExpElement::attachRegExp() - */ - virtual bool attachRegExp ( const RegExp * regexp ); - - /** - * @copydoc RegExpElement::computeMinimalAlphabet() - */ - virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; - -public: - explicit Alternation(RegExpElement&& left, RegExpElement&& right); - explicit Alternation(const RegExpElement& left, const RegExpElement& right); - - Alternation(const Alternation& other); - Alternation(Alternation&& other) noexcept; - Alternation& operator =(const Alternation& other); - Alternation& operator =(Alternation&& other); - virtual ~Alternation() noexcept; - - /** - * @return elements - */ - const std::vector<const RegExpElement*> & getElements() const; - - /** - * @return elements - */ - const std::vector<RegExpElement*> & getElements(); - - /** - * @param element to append - */ - void appendElement(const RegExpElement& element); - - /** - * @param element to append - */ - void appendElement(RegExpElement&& element); - - virtual bool operator<(const RegExpElement&) const; - virtual bool operator==(const RegExpElement&) const; - virtual bool operator>(const RegExpElement&) const; - - virtual bool operator<(const Alternation&) const; - virtual bool operator==(const Alternation&) const; - - /** - * @copydoc RegExpElement::operator>>() const - */ - virtual void operator>>(std::ostream& out) const; - - /** - * @copydoc RegExpElement::containsEmptyString() const - */ - virtual bool containsEmptyString() const; - - /** - * @copydoc RegExpElement::isEmpty() const - */ - virtual bool isEmpty() const; -}; - -} /* namespace regexp */ - -#endif /* ALTERNATION_H_ */ diff --git a/alib2data/src/regexp/Concatenation.cpp b/alib2data/src/regexp/Concatenation.cpp deleted file mode 100644 index c4a40827a27929906c475cf4bc09beeed84e12a1..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/Concatenation.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Concatenation.cpp - * - * Created on: Nov 27, 2013 - * Author: Martin Zak - */ - -#include "Concatenation.h" -#include "../exception/AlibException.h" - -namespace regexp { - -Concatenation::Concatenation(RegExpElement&& left, RegExpElement&& right) { - appendElement(std::move(left)); - appendElement(std::move(right)); -} - -Concatenation::Concatenation(const RegExpElement& left, const RegExpElement& right) { - appendElement(left); - appendElement(right); -} - -Concatenation::Concatenation(const Concatenation& other) { - for (auto element : other.elements) { - elements.push_back(element->clone()); - } -} - -Concatenation::Concatenation(Concatenation&& other) noexcept : elements(std::move(other.elements)) { - other.elements.clear(); - this->attachRegExp(NULL); -} - -Concatenation& Concatenation::operator=(const Concatenation& other) { - if(this == &other) { - return *this; - } - - *this = Concatenation(other); - - return *this; -} - -Concatenation& Concatenation::operator=(Concatenation&& other) { - std::swap(this->elements, other.elements); - std::swap(this->parentRegExp, other.parentRegExp); - - this->attachRegExp(other.parentRegExp); - - return *this; -} - -Concatenation::~Concatenation() noexcept { - for (auto element : elements) { - delete element; - } - elements.clear(); -} - -const std::vector<const RegExpElement*> & Concatenation::getElements() const { - return * reinterpret_cast<const std::vector<const RegExpElement*> * > (&elements); -} - -const std::vector<RegExpElement*> & Concatenation::getElements() { - return elements; -} - -void Concatenation::appendElement(const RegExpElement& element) { - RegExpElement* elem = element.clone(); - if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) - throw exception::AlibException("Input symbols not in the alphabet."); - this->elements.push_back(elem); -} - -void Concatenation::appendElement(RegExpElement&& element) { - RegExpElement* elem = std::move(element).plunder(); - if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) - throw exception::AlibException("Input symbols not in the alphabet."); - this->elements.push_back(elem); -} - -RegExpElement* Concatenation::clone() const { - return new Concatenation(*this); -} - -RegExpElement* Concatenation::plunder() && { - return new Concatenation(std::move(*this)); -} - -bool Concatenation::operator<(const RegExpElement& other) const { - return other > *this; -} - -bool Concatenation::operator==(const RegExpElement& other) const { - return other == *this; -} - -bool Concatenation::operator>(const RegExpElement& other) const { - return other < *this; -} - - -bool Concatenation::operator<(const Concatenation& other) const { - int thisSize = this->elements.size(); - int otherSize = other.elements.size(); - if(thisSize < otherSize) return true; - if(thisSize > otherSize) return false; - - auto thisIter = this->elements.begin(); - auto otherIter = other.elements.begin(); - for(; thisIter != this->elements.end(); thisIter++, otherIter++) { - if(**thisIter != **otherIter) break; - } - if(thisIter == this->elements.end()) return false; - - return **thisIter < **otherIter; -} - -bool Concatenation::operator==(const Concatenation& other) const { - if(this->elements.size() != other.elements.size()) return false; - - auto thisIter = this->elements.begin(); - auto otherIter = other.elements.begin(); - for(; thisIter != this->elements.end(); thisIter++, otherIter++) { - if(**thisIter != **otherIter) return false; - } - - return true; -} - -void Concatenation::operator>>(std::ostream& out) const { - out << "(Concatenation"; - for(const auto& e : elements) - out << " " << *e; - - out << ")"; -} - -bool Concatenation::testSymbol( const alphabet::Symbol & symbol ) const { - for(const auto& child : this->elements) - if(child->testSymbol(symbol)) return true; - return false; -} - -bool Concatenation::attachRegExp(const RegExp * regexp ) { - if(this->parentRegExp == regexp) return true; - - this->parentRegExp = regexp; - for(const auto& child : this->elements) - if(!child->attachRegExp(regexp)) return false; - return true; -} - -void Concatenation::computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const { - for(const auto& child : this->elements) - child->computeMinimalAlphabet(alphabet); -} - -bool Concatenation::containsEmptyString() const { - for(const auto& e : elements) - if( ! e->containsEmptyString()) - return false; - - return true; // concatenation of zero regexps is epsilon (this cannot happen) so by default it does contain epsilon -} - -bool Concatenation::isEmpty() const { - for(const auto& e : elements) - if(e->isEmpty()) - return true; - - return false; // concatenation of zero regexps is epsilon (this cannot happen) but by default it isn't empty -} - -} /* namespace regexp */ diff --git a/alib2data/src/regexp/Concatenation.h b/alib2data/src/regexp/Concatenation.h deleted file mode 100644 index fd78e94269ca9f583b792b4de77c19f7b42a849c..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/Concatenation.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Concatenation.h - * - * Created on: Nov 27, 2013 - * Author: Martin Zak - */ - -#ifndef CONCATENATION_H_ -#define CONCATENATION_H_ - -#include <vector> -#include "RegExpElement.h" - -namespace regexp { - -/** - * Represents concatenation operator in the regular expression. Contains list of RegExpElement - * as operands of the operator. - */ -class Concatenation: public std::element<Concatenation, RegExpElement> { -protected: - /** - * @copydoc RegExpElement::clone() const - */ - virtual RegExpElement* clone() const; - - virtual RegExpElement* plunder() &&; - - std::vector<RegExpElement*> elements; - - /** - * @copydoc RegExpElement::testSymbol() const - */ - virtual bool testSymbol( const alphabet::Symbol & symbol ) const; - - /** - * @copydoc RegExpElement::attachRegExp() - */ - virtual bool attachRegExp ( const RegExp * regexp ); - - /** - * @copydoc RegExpElement::computeMinimalAlphabet() - */ - virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; - -public: - explicit Concatenation(RegExpElement&& left, RegExpElement&& right); - explicit Concatenation(const RegExpElement& left, const RegExpElement& right); - - Concatenation(const Concatenation& other); - Concatenation(Concatenation&& other) noexcept; - Concatenation& operator =(const Concatenation& other); - Concatenation& operator =(Concatenation&& other); - virtual ~Concatenation() noexcept; - - /** - * @return elements - */ - const std::vector<const RegExpElement*> & getElements() const; - - /** - * @return elements - */ - const std::vector<RegExpElement*> & getElements(); - - /** - * @param element to append - */ - void appendElement(const RegExpElement& element); - - void appendElement(RegExpElement&& element); - - virtual bool operator<(const RegExpElement&) const; - virtual bool operator==(const RegExpElement&) const; - virtual bool operator>(const RegExpElement&) const; - - virtual bool operator<(const Concatenation&) const; - virtual bool operator==(const Concatenation&) const; - - /** - * @copydoc RegExpElement::operator>>() const - */ - virtual void operator>>(std::ostream& out) const; - - /** - * @copydoc RegExpElement::containsEmptyString() const - */ - virtual bool containsEmptyString() const; - - /** - * @copydoc RegExpElement::isEmpty() const - */ - virtual bool isEmpty() const; -}; - -} /* namespace regexp */ - -#endif /* CONCATENATION_H_ */ diff --git a/alib2data/src/regexp/Iteration.cpp b/alib2data/src/regexp/Iteration.cpp deleted file mode 100644 index 8f806518173a86ad2c60d5214094bdfcc1cde9f9..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/Iteration.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Iteration.cpp - * - * Created on: Nov 23, 2013 - * Author: Martin Zak - */ - -#include "Iteration.h" -#include "../exception/AlibException.h" - -namespace regexp { - -Iteration::Iteration(RegExpElement&& element) : element( NULL ) { - this->setElement(std::move(element)); -} - -Iteration::Iteration(const RegExpElement& element) : element( NULL ) { - this->setElement(element); -} - - -Iteration::Iteration(const Iteration& other) : element(other.element->clone()) { - -} - -Iteration::Iteration(Iteration&& other) noexcept : element(other.element) { - other.element = NULL; - this->attachRegExp(NULL); -} - -Iteration& Iteration::operator=(const Iteration& other) { - if (this == &other) { - return *this; - } - - *this = Iteration(other); - - return *this; -} - -Iteration& Iteration::operator=(Iteration&& other) { - std::swap(this->element, other.element); - std::swap(this->parentRegExp, other.parentRegExp); - - this->attachRegExp(other.parentRegExp); - - return *this; -} - -regexp::Iteration::~Iteration() noexcept { - delete element; -} - -const RegExpElement & Iteration::getElement() const { - return *element; -} - -RegExpElement & Iteration::getElement() { - return *element; -} - -void Iteration::setElement(const RegExpElement& element) { - RegExpElement* elem = element.clone(); - if(this->parentRegExp && !this->element->attachRegExp(this->parentRegExp)) - throw exception::AlibException("Input symbols not in the alphabet."); - delete this->element; - this->element = elem; -} - -void Iteration::setElement(RegExpElement&& element) { - RegExpElement* elem = std::move(element).plunder(); - if(this->parentRegExp && !this->element->attachRegExp(this->parentRegExp)) - throw exception::AlibException("Input symbols not in the alphabet."); - delete this->element; - this->element = elem; -} - -RegExpElement* Iteration::clone() const { - return new Iteration(*this); -} - -RegExpElement* Iteration::plunder() && { - return new Iteration(std::move(*this)); -} - -bool Iteration::operator<(const RegExpElement& other) const { - return other > *this; -} - -bool Iteration::operator==(const RegExpElement& other) const { - return other == *this; -} - -bool Iteration::operator>(const RegExpElement& other) const { - return other < *this; -} - -bool Iteration::operator<(const Iteration& other) const { - return *(this->element) < *(other.element); -} - -bool Iteration::operator==(const Iteration& other) const { - return *(this->element) == *(other.element); -} - -void Iteration::operator>>(std::ostream& out) const { - out << "(RegExpIteration " << *element << ")"; -} - -bool Iteration::testSymbol( const alphabet::Symbol & symbol ) const { - return element->testSymbol( symbol ); -} - -bool Iteration::attachRegExp(const RegExp * regexp ) { - if(this->parentRegExp == regexp) return true; - this->parentRegExp = regexp; - return this->element->attachRegExp(regexp); -} - -void Iteration::computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const { - element->computeMinimalAlphabet(alphabet); -} - -bool Iteration::containsEmptyString() const { - return true; -} - -bool Iteration::isEmpty() const { - return false; -} - -} /* namespace regexp */ - diff --git a/alib2data/src/regexp/Iteration.h b/alib2data/src/regexp/Iteration.h deleted file mode 100644 index 68f59a740b52569f2d44d806fbec020ad9356dc3..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/Iteration.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Iteration.h - * - * Created on: Nov 23, 2013 - * Author: Martin Zak - */ - -#ifndef ITERATION_H_ -#define ITERATION_H_ - -#include "RegExpElement.h" -#include "RegExpEmpty.h" - -namespace regexp { - -/** - * Represents iteration operator in the regular expression. Contains one RegExpElement - * as operand. - */ -class Iteration: public std::element<Iteration, RegExpElement> { -protected: - RegExpElement* element; - - /** - * @copydoc RegExpElement::clone() const - */ - virtual RegExpElement* clone() const; - - virtual RegExpElement* plunder() &&; - - /** - * @copydoc RegExpElement::testSymbol() const - */ - virtual bool testSymbol( const alphabet::Symbol & symbol ) const; - - /** - * @copydoc RegExpElement::attachRegExp() - */ - virtual bool attachRegExp ( const RegExp * regexp ); - - /** - * @copydoc RegExpElement::computeMinimalAlphabet() - */ - virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; - -public: - explicit Iteration(RegExpElement&&); - explicit Iteration(const RegExpElement&); - - Iteration(const Iteration& other); - Iteration(Iteration&& other) noexcept; - Iteration& operator =(const Iteration& other); - Iteration& operator =(Iteration&& other); - virtual ~Iteration() noexcept; - - /** - * @return element - */ - const RegExpElement & getElement() const; - - /** - * @return element - */ - RegExpElement & getElement(); - - /** - * @param element to iterate - */ - void setElement(const RegExpElement& element); - - void setElement(RegExpElement&& element); - - virtual bool operator<(const RegExpElement&) const; - virtual bool operator==(const RegExpElement&) const; - virtual bool operator>(const RegExpElement&) const; - - virtual bool operator<(const Iteration&) const; - virtual bool operator==(const Iteration&) const; - - /** - * @copydoc RegExpElement::operator>>() const - */ - virtual void operator>>(std::ostream& out) const; - - /** - * @copydoc RegExpElement::containsEmptyString() const - */ - virtual bool containsEmptyString() const; - - /** - * @copydoc RegExpElement::isEmpty() const - */ - virtual bool isEmpty() const; -}; - -} /* namespace regexp */ - -#endif /* ITERATION_H_ */ diff --git a/alib2data/src/regexp/RegExp.cpp b/alib2data/src/regexp/RegExp.cpp index 2eb5b909b2a707342df86e4d52e915a0947b6aab..e38c87aa8902dac16212f71a2cd394ebdf5cbe33 100644 --- a/alib2data/src/regexp/RegExp.cpp +++ b/alib2data/src/regexp/RegExp.cpp @@ -1,167 +1,82 @@ /* * RegExp.cpp * - * Created on: Nov 23, 2013 + * Created on: Apr 16, 2013 * Author: Martin Zak */ #include "RegExp.h" -#include "../exception/AlibException.h" -#include "RegExpEmpty.h" -#include "RegExpSymbol.h" - -#include <iostream> -#include <algorithm> - -#include "../std/set.hpp" namespace regexp { -RegExp::RegExp() { - this->regExp = new RegExpEmpty(); -} +RegExp::RegExp(const RegExpBase& regExp) : regExp(regExp.clone()) { -RegExp::RegExp(const std::set<alphabet::Symbol>& alphabet, const RegExpElement& regExp) : alphabet(alphabet) { - this->regExp = NULL; - setRegExp(regExp); } -RegExp::RegExp(std::set<alphabet::Symbol>&& alphabet, RegExpElement&& regExp) : alphabet(std::move(alphabet)) { - this->regExp = NULL; - setRegExp(std::move(regExp)); -} +RegExp::RegExp(RegExpBase&& regExp) : regExp(std::move(regExp).plunder()) { -RegExp::RegExp(const RegExpElement& regExp) { - regExp.computeMinimalAlphabet(alphabet); - this->regExp = NULL; - setRegExp(regExp); } -RegExp::RegExp(RegExpElement&& regExp) { - regExp.computeMinimalAlphabet(alphabet); - this->regExp = NULL; - setRegExp(std::move(regExp)); -} +RegExp::RegExp(const RegExp& other) : regExp(other.getRegExp().clone()) { -RegExp::RegExp(const RegExp& other) : regExp(other.regExp->clone()), alphabet(other.alphabet) { - this->regExp->attachRegExp(this); } -RegExp::RegExp(RegExp&& other) noexcept : regExp(other.regExp), alphabet(std::move(other.alphabet) ) { - this->regExp->attachRegExp(this); +RegExp::RegExp(RegExp&& other) noexcept : regExp(std::move(other.getRegExp()).plunder()) { other.regExp = NULL; } RegExp& RegExp::operator=(const RegExp& other) { - if (this == &other) { - return *this; - } + if(this == &other) return *this; - *this = RegExp(other); + delete regExp; + regExp = other.getRegExp().clone(); return *this; } RegExp& RegExp::operator=(RegExp&& other) noexcept { std::swap(this->regExp, other.regExp); - std::swap(this->alphabet, other.alphabet); return *this; } -RegExp::~RegExp() noexcept { +RegExp::~RegExp() { delete regExp; } -const RegExpElement& RegExp::getRegExp() const { +const RegExpBase& RegExp::getRegExp() const { return *regExp; } -RegExpElement& RegExp::getRegExp() { +RegExpBase& RegExp::getRegExp() { return *regExp; } -void RegExp::setRegExp(const RegExpElement& regExp) { +void RegExp::setRegExp(const RegExpBase& regExp) { delete this->regExp; this->regExp = regExp.clone(); - if(!this->regExp->attachRegExp(this)) - throw exception::AlibException("Input symbols not in the alphabet."); } -void RegExp::setRegExp(RegExpElement&& regExp) { +void RegExp::setRegExp(RegExpBase&& regExp) { delete this->regExp; this->regExp = std::move(regExp).plunder(); - if(!this->regExp->attachRegExp(this)) - throw exception::AlibException("Input symbols not in the alphabet."); -} - -const std::set<alphabet::Symbol>& RegExp::getAlphabet() const { - return alphabet; -} - -bool RegExp::addSymbolToAlphabet(const alphabet::Symbol & symbol) { - return alphabet.insert(symbol).second; -} - -void RegExp::setAlphabet(const std::set<alphabet::Symbol> & symbols) { - std::set<alphabet::Symbol> minimalAlphabet; - this->regExp->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 RegExp::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) { - if(this->regExp->testSymbol(symbol)) - throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is used."); - - return alphabet.erase(symbol); -} - -bool RegExp::isEmpty() const { - return regExp->isEmpty(); -} - -bool RegExp::containsEmptyString() const { - return regExp->containsEmptyString(); -} - -std::ostream& operator <<(std::ostream& out, const RegExp& regExp) { - out << "(RegExp " << *(regExp.regExp) << ")"; - return out; } bool RegExp::operator<(const RegExp& other) const { - if(*(this->regExp) < *(other.regExp)) { - return true; - } else if(*(this->regExp) > *(other.regExp)) { - return false; - } else { - return this->alphabet < other.alphabet; - } -} - -bool RegExp::operator<=(const RegExp& other) const { - return !(other > *this); -} - -bool RegExp::operator==(const RegExp& other) const { - return *(this->regExp) == *(other.regExp) && this->alphabet == other.alphabet; + return this->getRegExp() < other.getRegExp(); } bool RegExp::operator!=(const RegExp& other) const { return !(*this == other); } -bool RegExp::operator>(const RegExp& other) const { - return other < *this; +bool RegExp::operator==(const RegExp& other) const { + return this->getRegExp() == other.getRegExp(); } -bool RegExp::operator>=(const RegExp& other) const { - return !(*this < other); +std::ostream& operator<<(std::ostream& os, const RegExp& regExp) { + os << regExp.getRegExp(); + return os; } } /* namespace regexp */ + diff --git a/alib2data/src/regexp/RegExp.h b/alib2data/src/regexp/RegExp.h index 32b55891cc6bd0fa980bccd342a3bfea4f3b87b0..8110de44b80739c30ba979b0d9b1262dd55de537 100644 --- a/alib2data/src/regexp/RegExp.h +++ b/alib2data/src/regexp/RegExp.h @@ -1,123 +1,48 @@ /* * RegExp.h * - * Created on: Nov 23, 2013 + * Created on: Apr 10, 2013 * Author: Martin Zak */ #ifndef REG_EXP_H_ #define REG_EXP_H_ -#include <vector> -#include <list> -#include <string> -#include <set> -#include "RegExpElement.h" #include "../std/visitor.hpp" +#include "RegExpBase.h" namespace regexp { - -class RegExpElement; /** - * Represents regular expression parsed from the XML. Regular expression is stored - * as a tree of RegExpElement. + * Wrapper around automata. */ class RegExp { protected: - RegExpElement* regExp; - - std::set<alphabet::Symbol> alphabet; - + RegExpBase* regExp; public: - RegExp(); - RegExp(const std::set<alphabet::Symbol>& alphabet, const RegExpElement& regExp); - RegExp(std::set<alphabet::Symbol>&& alphabet, RegExpElement&& regExp); - explicit RegExp(const RegExpElement& regExp); - explicit RegExp(RegExpElement&& regExp); - - /** - * Copy constructor. - * @param other RegExp to copy - */ + explicit RegExp(const RegExpBase& regExp); + explicit RegExp(RegExpBase&& regExp); RegExp(const RegExp& other); - RegExp(RegExp&& other) noexcept; - RegExp& operator =(const RegExp& other); - RegExp& operator =(RegExp&& other) noexcept; - ~RegExp() noexcept; + RegExp(RegExp&&) noexcept; + RegExp& operator=(const RegExp& other); + RegExp& operator=(RegExp&& other) noexcept; + virtual ~RegExp() noexcept; - /** - * @return Root node of the regular expression tree - */ - const RegExpElement& getRegExp() const; - - /** - * @return Root node of the regular expression tree - */ - RegExpElement& getRegExp(); + const RegExpBase& getRegExp() const; + RegExpBase& getRegExp(); - /** - * Sets the root node of the regular expression tree. Doesn't perform copy of the regExp param, - * just stores it! - * @param regExp root node to set - */ - void setRegExp(const RegExpElement& regExp); - - /** - * Sets the root node of the regular expression tree - * @param regExp root node to set - */ - void setRegExp(RegExpElement&& regExp); - - /** - * Gets alphabet symbols used in RegExp. - * @return set of alphabet symbols used in regexp. - */ - const std::set<alphabet::Symbol>& getAlphabet() const; - - /** - * Adds symbol to the alphabet available in the regular expression - * @param symbol new symbol added to the alphabet - */ - bool addSymbolToAlphabet(const alphabet::Symbol & symbol); + void setRegExp(const RegExpBase& regExp); + void setRegExp(RegExpBase&& regExp); - /** - * Sets the alphabet of the regular expression - * @param symbols new alphabet - */ - void setAlphabet(const std::set<alphabet::Symbol>& symbols); - - /** - * Removes symbol from the alphabet of symbol available in the regular expression - * @param symbol removed symbol from the alphabet - */ - bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol); - - /** - * @return true if regexp represents empty language - */ - bool isEmpty() const; + bool operator<(const RegExp& other) const; + bool operator!=(const RegExp& other) const; + bool operator==(const RegExp& other) const; - /** - * @return true if regexp matches empty string (epsilon) - */ - bool containsEmptyString() const; + friend std::ostream& operator<<(std::ostream& os, const RegExp& regExp); - /** - * Prints XML representation of the RegExp to the output stream. - * @param out output stream to which print the RegExp - * @param regexp RegExp to print - */ - friend std::ostream& operator<<(std::ostream& out, const RegExp& regexp); - - bool operator<(const RegExp&) const; - bool operator<=(const RegExp&) const; - bool operator==(const RegExp&) const; - bool operator!=(const RegExp&) const; - bool operator>(const RegExp&) const; - bool operator>=(const RegExp&) const; }; } /* namespace regexp */ #endif /* REG_EXP_H_ */ + diff --git a/alib2data/src/regexp/RegExpAlphabetGetter.cpp b/alib2data/src/regexp/RegExpAlphabetGetter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bab12b056ed0a30acc232f27fc1a3174c26afc71 --- /dev/null +++ b/alib2data/src/regexp/RegExpAlphabetGetter.cpp @@ -0,0 +1,38 @@ +/* + * RegExpAlphabetGetter.cpp + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#include "RegExpAlphabetGetter.h" + +namespace regexp { + +void RegExpAlphabetGetter::Visit(void* userData, const RegExp& regexp) const { + regexp.getRegExp().Accept(userData, *this); +} + +void RegExpAlphabetGetter::Visit(void* userData, const RegExpBase::element_type& element) const { + element.Accept(userData, *this); +} + +void RegExpAlphabetGetter::Visit(void* userData, const UnboundedRegExp& regexp) const { + std::set<alphabet::Symbol> &res = *((std::set<alphabet::Symbol>*) userData); + res = regexp.getAlphabet(); +} + +void RegExpAlphabetGetter::Visit(void* userData, const FormalRegExp& regexp) const { + std::set<alphabet::Symbol> &res = *((std::set<alphabet::Symbol>*) userData); + res = regexp.getAlphabet(); +} + +std::set<alphabet::Symbol> RegExpAlphabetGetter::getAlphabet(const RegExp& regexp) const { + std::set<alphabet::Symbol> res; + regexp.getRegExp().Accept((void*) &res, *this); + return std::move(res); +} + +const RegExpAlphabetGetter RegExpAlphabetGetter::REG_EXP_ALPHABET_GETTER; + +} /* namespace regexp */ diff --git a/alib2data/src/regexp/RegExpAlphabetGetter.h b/alib2data/src/regexp/RegExpAlphabetGetter.h new file mode 100644 index 0000000000000000000000000000000000000000..fdd6be7c75f2be49a92cc49fda56c9b5dc843f96 --- /dev/null +++ b/alib2data/src/regexp/RegExpAlphabetGetter.h @@ -0,0 +1,40 @@ +/* + * RegExpAlphabetGetter.h + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#ifndef REX_EXP_ALPHABET_GETTER_H_ +#define REX_EXP_ALPHABET_GETTER_H_ + +#include <set> +#include "RegExp.h" +#include "../alphabet/Symbol.h" +#include "unbounded/UnboundedRegExp.h" +#include "formal/FormalRegExp.h" + +namespace regexp { + +class RegExpAlphabetGetter : public RegExpBase::const_visitor_type { + void Visit(void*, const UnboundedRegExp& empty) const; + void Visit(void*, const FormalRegExp& empty) const; + + void Visit(void*, const RegExpBase::element_type& element) const; + + void Visit(void*, const RegExp& empty) const; + +public: + /** + * Composes string representation of RegExp. + * @param regexp RegExp to print + * @returns string representation of regexp + */ + std::set<alphabet::Symbol> getAlphabet(const RegExp& regexp) const; + + static const RegExpAlphabetGetter REG_EXP_ALPHABET_GETTER; +}; + +} /* namespace regexp */ + +#endif /* REX_EXP_ALPHABET_GETTER_H_ */ diff --git a/alib2data/src/regexp/RegExpBase.cpp b/alib2data/src/regexp/RegExpBase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..82cd52b2d782c36c3dcbbd8ec8a6b30f6fe03858 --- /dev/null +++ b/alib2data/src/regexp/RegExpBase.cpp @@ -0,0 +1,34 @@ +/* + * RegExpBase.cpp + * + * Created on: Apr 16, 2013 + * Author: Jan Travnicek + */ + +#include "RegExpBase.h" + +namespace regexp { + +RegExpBase::~RegExpBase() { + +} + +bool RegExpBase::operator!=(const RegExpBase& other) const { + return !(*this == other); +} + +bool RegExpBase::operator==(const UnboundedRegExp&) const { + return false; +} + +bool RegExpBase::operator==(const FormalRegExp&) const { + return false; +} + +std::ostream& operator<<(std::ostream& os, const RegExpBase& regexp) { + regexp >> os; + return os; +} + +} /* namespace regexp */ + diff --git a/alib2data/src/regexp/RegExpBase.h b/alib2data/src/regexp/RegExpBase.h new file mode 100644 index 0000000000000000000000000000000000000000..a18f1f59bef9dcad5c828d2c253fc380088d737b --- /dev/null +++ b/alib2data/src/regexp/RegExpBase.h @@ -0,0 +1,49 @@ +/* + * RegExpBase.h + * + * Created on: Apr 10, 2013 + * Author: Jan Travnicek + */ + +#ifndef REG_EXP_BASE_H_ +#define REG_EXP_BASE_H_ + +#include "../std/visitor.hpp" +#include <iostream> + +namespace regexp { + +class UnboundedRegExp; +class FormalRegExp; + +/** + * Abstract base class for all automata. + */ +class RegExpBase : public std::elementBase<UnboundedRegExp, FormalRegExp> { +public: + virtual RegExpBase* clone() const = 0; + + virtual RegExpBase* plunder() && = 0; + + virtual ~RegExpBase() noexcept; + + virtual bool operator <(const RegExpBase& other) const = 0; + virtual bool operator ==(const RegExpBase& other) const = 0; + virtual bool operator >(const RegExpBase& other) const = 0; + bool operator !=(const RegExpBase& other) const; + + virtual bool operator==(const FormalRegExp& other) const = 0; + virtual bool operator==(const UnboundedRegExp& other) const = 0; + + virtual bool operator<(const FormalRegExp& other) const = 0; + virtual bool operator<(const UnboundedRegExp& other) const = 0; + + friend std::ostream& operator<<(std::ostream& os, const RegExpBase& regexp); + + virtual void operator>>(std::ostream&) const = 0; +}; + +} /* namespace regexp */ + +#endif /* REG_EXP_BASE_H_ */ + diff --git a/alib2data/src/regexp/RegExpElement.cpp b/alib2data/src/regexp/RegExpElement.cpp deleted file mode 100644 index bb653bce5b0f4a91ee4cb3376078554fe0954407..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/RegExpElement.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * RegExpElement.cpp - * - * Created on: Nov 23, 2013 - * Author: Martin Zak - */ - -#include "RegExpElement.h" -#include <typeinfo> - -#include "RegExpElements.h" - -namespace regexp { - -RegExpElement::RegExpElement() : parentRegExp(NULL) { - -} - -RegExpElement::~RegExpElement() noexcept { - -} - -bool RegExpElement::operator>=(const RegExpElement& other) const { - return !(*this < other); -} - -bool RegExpElement::operator<=(const RegExpElement& other) const { - return !(*this > other); -} - -bool RegExpElement::operator!=(const RegExpElement& other) const { - return !(*this == other); -} - - -bool RegExpElement::operator<(const Concatenation& other) const { - return typeid(*this).before(typeid(other)); -} - -bool RegExpElement::operator<(const Alternation& other) const { - return typeid(*this).before(typeid(other)); -} - -bool RegExpElement::operator<(const Iteration& other) const { - return typeid(*this).before(typeid(other)); -} - -bool RegExpElement::operator<(const RegExpSymbol& other) const { - return typeid(*this).before(typeid(other)); -} - -bool RegExpElement::operator<(const RegExpEpsilon& other) const { - return typeid(*this).before(typeid(other)); -} - -bool RegExpElement::operator<(const RegExpEmpty& other) const { - return typeid(*this).before(typeid(other)); -} - - -bool RegExpElement::operator==(const Concatenation&) const { - return false; -} - -bool RegExpElement::operator==(const Alternation&) const { - return false; -} - -bool RegExpElement::operator==(const Iteration&) const { - return false; -} - -bool RegExpElement::operator==(const RegExpSymbol&) const { - return false; -} - -bool RegExpElement::operator==(const RegExpEpsilon&) const { - return false; -} - -bool RegExpElement::operator==(const RegExpEmpty&) const { - return false; -} - -std::ostream& operator<<(std::ostream& out, const RegExpElement& regexp) { - regexp >> out; - return out; -} - -} /* namespace regexp */ diff --git a/alib2data/src/regexp/RegExpElement.h b/alib2data/src/regexp/RegExpElement.h deleted file mode 100644 index 12981564a4005b30e8dabcefbbc5ff3ff65eea5c..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/RegExpElement.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * RegExpElement.h - * - * Created on: Nov 23, 2013 - * Author: Martin Zak - */ - -#ifndef REG_EXP_ELEMENT_H_ -#define REG_EXP_ELEMENT_H_ - -#include "../std/visitor.hpp" -#include "../alphabet/Symbol.h" -#include "RegExp.h" -#include <set> - -namespace regexp { - -class RegExp; - -class Alternation; -class Concatenation; -class Iteration; -class RegExpSymbol; -class RegExpEmpty; -class RegExpEpsilon; - -/** - * Abstract class representing element in the regular expression. Can be operator or symbol. - */ -class RegExpElement : public std::elementBase<Alternation, Concatenation, Iteration, RegExpSymbol, RegExpEmpty, RegExpEpsilon> { -protected: - /* - * Parent regexp contanining this instance of RegExpElement - */ - const RegExp * parentRegExp; - - /** - * Traverses the regexp tree looking if particular Symbol is used in the regexp. - * - * @param symbol to test if used in regexp element - * @return true if symbol is used by the element and its successor - */ - virtual bool testSymbol( const alphabet::Symbol & symbol ) const = 0; - - /** - * Attaches the regexp to this instance and all its childs - * @param regexp parent regexp to attach as parent - * @return true if symbols used in regexp element are in the regexp's alphabet - */ - virtual bool attachRegExp ( const RegExp * regexp ) = 0; - - /** - * Traverses the regexp tree computing minimal alphabet needed by regexp - * - * @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>& alphabet ) const = 0; - -public: - RegExpElement(); - - /** - * Creates copy of the element. - * @return copy of the element - */ - virtual RegExpElement* clone() const = 0; - - virtual RegExpElement* plunder() && = 0; - - virtual ~RegExpElement() noexcept; - - // RegExpEmpty < RegExpEpsilon < RegExpSymbol < RegExpIteration < RegExpAlternation < RegExpConcatenation - virtual bool operator<(const RegExpElement&) const = 0; - virtual bool operator==(const RegExpElement&) const = 0; - virtual bool operator>(const RegExpElement&) const = 0; - - virtual bool operator>=(const RegExpElement&) const; - virtual bool operator<=(const RegExpElement&) const; - virtual bool operator!=(const RegExpElement&) const; - - virtual bool operator<(const Concatenation&) const; - virtual bool operator<(const Alternation&) const; - virtual bool operator<(const Iteration&) const; - virtual bool operator<(const RegExpSymbol&) const; - virtual bool operator<(const RegExpEpsilon&) const; - virtual bool operator<(const RegExpEmpty&) const; - - virtual bool operator==(const Concatenation&) const; - virtual bool operator==(const Alternation&) const; - virtual bool operator==(const Iteration&) const; - virtual bool operator==(const RegExpSymbol&) const; - virtual bool operator==(const RegExpEpsilon&) const; - virtual bool operator==(const RegExpEmpty&) const; - - /** - * Prints XML representation of the RegExp to the output stream. - * @param out output stream to which print the RegExp - */ - virtual void operator>>(std::ostream& out) const = 0; - - /** - * Prints XML representation of the RegExp to the output stream. - * @param out output stream to which print the RegExp - * @param regexp RegExp to print - */ - friend std::ostream& operator<<(std::ostream& out, const RegExpElement& regexp); - - /** - * @return true if this subtree of regexp matches empty string (epsilon) - */ - virtual bool containsEmptyString() const = 0; - - /** - * @return true if this subtree describes empty language - */ - virtual bool isEmpty() const = 0; - - friend class RegExp; - - friend class Alternation; - friend class Concatenation; - friend class Iteration; - friend class RegExpSymbol; - friend class RegExpEmpty; - friend class RegExpEpsilon; -}; - -} /* namespace regexp */ - -#endif /* REG_EXP_ELEMENT_H_ */ diff --git a/alib2data/src/regexp/RegExpElements.h b/alib2data/src/regexp/RegExpElements.h deleted file mode 100644 index b3d1f02de90fa08a2ecb480b0fae1cad6214ccc1..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/RegExpElements.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * RegExpElements.h - * - * Created on: 14. 3. 2014 - * Author: Tomas Pecka - */ - -#ifndef REG_EXP_ELEMENTS_H_ -#define REG_EXP_ELEMENTS_H_ - -#include "Alternation.h" -#include "Concatenation.h" -#include "Iteration.h" -#include "RegExpElement.h" -#include "RegExpEpsilon.h" -#include "RegExpEmpty.h" -#include "RegExpSymbol.h" - -#endif /* REG_EXP_ELEMENTS_H_ */ diff --git a/alib2data/src/regexp/RegExpEmpty.cpp b/alib2data/src/regexp/RegExpEmpty.cpp deleted file mode 100644 index e7ce1a3623344cd74e8c7286eb742fe9e34dfce5..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/RegExpEmpty.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * RegExpEmpty.cpp - * - * Created on: Jan 30, 2014 - * Author: Jan Travnicek - */ - -#include "RegExpEmpty.h" - -namespace regexp { - -RegExpEmpty::RegExpEmpty() { - // so that default constructor is available -} - -RegExpEmpty::RegExpEmpty(const RegExpEmpty&) { - // so that copy constructor is available -} - -RegExpEmpty::RegExpEmpty(RegExpEmpty&&) noexcept { - this->attachRegExp(NULL); -} - -RegExpEmpty& RegExpEmpty::operator =(const RegExpEmpty&) { - //this is actually different than default implementation - return *this; -} - -RegExpEmpty& RegExpEmpty::operator =(RegExpEmpty&&) noexcept { - //this is actually different than default implementation - return *this; -} - -RegExpElement* RegExpEmpty::clone() const { - return new RegExpEmpty(*this); -} - -RegExpElement* RegExpEmpty::plunder() && { - return new RegExpEmpty(std::move(*this)); -} - -bool RegExpEmpty::operator<(const RegExpElement& other) const { - return other > *this; -} - -bool RegExpEmpty::operator==(const RegExpElement& other) const { - return other == *this; -} - -bool RegExpEmpty::operator>(const RegExpElement& other) const { - return other < *this; -} - - -bool RegExpEmpty::operator<(const RegExpEmpty&) const { - return false; -} - -bool RegExpEmpty::operator==(const RegExpEmpty&) const { - return true; -} - -void RegExpEmpty::operator>>(std::ostream& out) const { - out << "(RegExpEmpty)"; -} - -bool RegExpEmpty::testSymbol( const alphabet::Symbol & ) const { - return false; -} - -bool RegExpEmpty::attachRegExp(const RegExp * regexp ) { - if(this->parentRegExp == regexp) return true; - this->parentRegExp = regexp; - return true; -} - -void RegExpEmpty::computeMinimalAlphabet( std::set<alphabet::Symbol>&) const { - -} - -bool RegExpEmpty::containsEmptyString() const { - return false; -} - -bool RegExpEmpty::isEmpty() const { - return true; -} - -} /* namespace regexp */ diff --git a/alib2data/src/regexp/RegExpEmpty.h b/alib2data/src/regexp/RegExpEmpty.h deleted file mode 100644 index c87739ecc1dc7bc57f3fd98120f4f0317dda7578..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/RegExpEmpty.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * RegExpEmpty.h - * - * Created on: Jan 30, 2014 - * Author: Jan Travnicek - */ - -#ifndef REG_EXP_EMPTY_H_ -#define REG_EXP_EMPTY_H_ - -#include "RegExpElement.h" - -namespace regexp { - -/** - * Represents empty regular expression in the regular expression. - */ -class RegExpEmpty: public std::element<RegExpEmpty, RegExpElement> { -protected: - /** - * @copydoc RegExpElement::clone() const - */ - virtual RegExpElement* clone() const; - - virtual RegExpElement* plunder() &&; - - /** - * @copydoc RegExpElement::testSymbol() const - */ - virtual bool testSymbol( const alphabet::Symbol & symbol ) const; - - /** - * @copydoc RegExpElement::attachRegExp() - */ - virtual bool attachRegExp ( const RegExp * regexp ); - - /** - * @copydoc RegExpElement::computeMinimalAlphabet() - */ - virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; - -public: - RegExpEmpty(); - RegExpEmpty(const RegExpEmpty& other); - RegExpEmpty(RegExpEmpty&& other) noexcept; - RegExpEmpty& operator =(const RegExpEmpty& other); - RegExpEmpty& operator =(RegExpEmpty&& other) noexcept; - - virtual bool operator<(const RegExpElement&) const; - virtual bool operator==(const RegExpElement&) const; - virtual bool operator>(const RegExpElement&) const; - - virtual bool operator<(const RegExpEmpty&) const; - virtual bool operator==(const RegExpEmpty&) const; - - /** - * @copydoc RegExpElement::operator>>() const - */ - virtual void operator>>(std::ostream& out) const; - - /** - * @copydoc RegExpElement::containsEmptyString() const - */ - virtual bool containsEmptyString() const; - - /** - * @copydoc RegExpElement::isEmpty() const - */ - virtual bool isEmpty() const; -}; - -} /* namespace regexp */ - -#endif /* REG_EXP_EMPTY_H_ */ diff --git a/alib2data/src/regexp/RegExpEpsilon.cpp b/alib2data/src/regexp/RegExpEpsilon.cpp deleted file mode 100644 index 36ea54fd8580e407a05df7e7986a579a1c1b704e..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/RegExpEpsilon.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * RegExpEpsilon.cpp - * - * Created on: Jan 30, 2014 - * Author: Jan Travnicek - */ - -#include "RegExpEpsilon.h" - -namespace regexp { - -RegExpEpsilon::RegExpEpsilon() { - // so that default constructor is available -} - -RegExpEpsilon::RegExpEpsilon(const RegExpEpsilon&) { - // so that copy constructor is available -} - -RegExpEpsilon::RegExpEpsilon(RegExpEpsilon&&) noexcept { - this->attachRegExp(NULL); -} - -RegExpEpsilon& RegExpEpsilon::operator =(const RegExpEpsilon&) { - //this is actually different than default implementation - return *this; -} - -RegExpEpsilon& RegExpEpsilon::operator =(RegExpEpsilon&&) noexcept { - //this is actually different than default implementation - return *this; -} - -RegExpElement* RegExpEpsilon::clone() const { - return new RegExpEpsilon(*this); -} - -RegExpElement* RegExpEpsilon::plunder() && { - return new RegExpEpsilon(std::move(*this)); -} - -bool RegExpEpsilon::operator<(const RegExpElement& other) const { - return other > *this; -} - -bool RegExpEpsilon::operator==(const RegExpElement& other) const { - return other == *this; -} - -bool RegExpEpsilon::operator>(const RegExpElement& other) const { - return other < *this; -} - - -bool RegExpEpsilon::operator<(const RegExpEpsilon&) const { - return false; -} - -bool RegExpEpsilon::operator==(const RegExpEpsilon&) const { - return true; -} - -void RegExpEpsilon::operator>>(std::ostream& out) const { - out << "(RegExpEpsilon)"; -} - -bool RegExpEpsilon::testSymbol( const alphabet::Symbol & ) const { - return false; -} - -bool RegExpEpsilon::attachRegExp(const RegExp * regexp ) { - if(this->parentRegExp == regexp) return true; - this->parentRegExp = regexp; - return true; -} - -void RegExpEpsilon::computeMinimalAlphabet( std::set<alphabet::Symbol>&) const { - -} - -bool RegExpEpsilon::containsEmptyString() const { - return true; -} - -bool RegExpEpsilon::isEmpty() const { - return false; -} - -} /* namespace regexp */ diff --git a/alib2data/src/regexp/RegExpEpsilon.h b/alib2data/src/regexp/RegExpEpsilon.h deleted file mode 100644 index 96ed05db09457d49696523701cec06c89e0485e6..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/RegExpEpsilon.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * RegExpEpsilon.h - * - * Created on: Jan 30, 2014 - * Author: Jan Travnicek - */ - -#ifndef REG_EXP_EPSILON_H_ -#define REG_EXP_EPSILON_H_ - -#include "RegExpElement.h" - -namespace regexp { - -/** - * Represents epsilon in the regular expression. - */ -class RegExpEpsilon: public std::element<RegExpEpsilon, RegExpElement> { -protected: - /** - * @copydoc RegExpElement::clone() const - */ - virtual RegExpElement* clone() const; - - virtual RegExpElement* plunder() &&; - - /** - * @copydoc RegExpElement::testSymbol() const - */ - virtual bool testSymbol( const alphabet::Symbol & symbol ) const; - - /** - * @copydoc RegExpElement::attachRegExp() - */ - virtual bool attachRegExp ( const RegExp * regexp ); - - /** - * @copydoc RegExpElement::computeMinimalAlphabet() - */ - virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; - -public: - - RegExpEpsilon(); - RegExpEpsilon(const RegExpEpsilon& other); - RegExpEpsilon(RegExpEpsilon&& other) noexcept; - RegExpEpsilon& operator=(const RegExpEpsilon& other); - RegExpEpsilon& operator=(RegExpEpsilon&& other) noexcept; - - virtual bool operator<(const RegExpElement&) const; - virtual bool operator==(const RegExpElement&) const; - virtual bool operator>(const RegExpElement&) const; - - virtual bool operator<(const RegExpEpsilon&) const; - virtual bool operator==(const RegExpEpsilon&) const; - - /** - * @copydoc RegExpElement::operator>>() const - */ - virtual void operator>>(std::ostream& out) const; - - /** - * @copydoc RegExpElement::containsEmptyString() const - */ - virtual bool containsEmptyString() const; - - /** - * @copydoc RegExpElement::isEmpty() const - */ - virtual bool isEmpty() const; -}; - -} /* namespace regexp */ - -#endif /* REG_EXP_EPSILON_H_ */ diff --git a/alib2data/src/regexp/RegExpFeatures.h b/alib2data/src/regexp/RegExpFeatures.h index a1b64f7cedfdda9a192aa3e9adf72107fa0a267b..0cf15f29bd9453365849eb312d357a6df2886299 100644 --- a/alib2data/src/regexp/RegExpFeatures.h +++ b/alib2data/src/regexp/RegExpFeatures.h @@ -11,7 +11,8 @@ namespace regexp { enum class FEATURES { - COMPACT + FORMAL, + UNBOUNDED }; } /* namespace regexp */ diff --git a/alib2data/src/regexp/RegExpFromStringParser.cpp b/alib2data/src/regexp/RegExpFromStringParser.cpp index c5d92e2f65eb95577192357a360d11b410e55e2f..6ca6c60f535d0a3d3ac6b70bdfc0399aedd0fbb8 100644 --- a/alib2data/src/regexp/RegExpFromStringParser.cpp +++ b/alib2data/src/regexp/RegExpFromStringParser.cpp @@ -10,15 +10,18 @@ RegExpFromStringParser::RegExpFromStringParser(std::stringstream& input) : m_Reg } RegExp RegExpFromStringParser::parse() { - return parse(std::set<FEATURES>({FEATURES::COMPACT})); + return parse(std::set<FEATURES>({FEATURES::FORMAL, FEATURES::UNBOUNDED})); } RegExp RegExpFromStringParser::parse(const std::set<FEATURES>& features) { - if(!features.count(FEATURES::COMPACT)) throw exception::AlibException(); - RegExpElement* element = this->alternation(); - RegExp regexp(std::move(*element)); + UnboundedRegExpElement* element = this->alternation(); + UnboundedRegExp regexp(std::move(*element)); delete element; - return regexp; + if(features.count(FEATURES::UNBOUNDED)) return RegExp{regexp}; + +// if(features.count(FEATURES::FORMAL)) return RegExp{FormalRegExp{regexp}}; TODO + + throw exception::AlibException(); } bool RegExpFromStringParser::first() { @@ -48,18 +51,20 @@ bool RegExpFromStringParser::last() { } } -RegExpElement* RegExpFromStringParser::alternation() { +UnboundedRegExpElement* RegExpFromStringParser::alternation() { return this->alternationCont(this->concatenation()); } -RegExpElement* RegExpFromStringParser::alternationCont(RegExpElement* left) { +UnboundedRegExpElement* RegExpFromStringParser::alternationCont(UnboundedRegExpElement* left) { RegExpFromStringLexer::Token token = m_RegexpLexer.token(); if(token.type == RegExpFromStringLexer::TokenType::PLUS) { next() || m_SymbolParser.first(); try { - RegExpElement* right = this->concatenation(); - Alternation* res = new Alternation(std::move(*left), std::move(*right)); + UnboundedRegExpElement* right = this->concatenation(); + UnboundedRegExpAlternation* res = new UnboundedRegExpAlternation(); + res->appendElement(std::move(*left)); + res->appendElement(std::move(*right)); delete right; delete left; left = NULL; @@ -74,13 +79,13 @@ RegExpElement* RegExpFromStringParser::alternationCont(RegExpElement* left) { } } -RegExpElement* RegExpFromStringParser::alternationContCont(Alternation* res) { +UnboundedRegExpElement* RegExpFromStringParser::alternationContCont(UnboundedRegExpAlternation* res) { RegExpFromStringLexer::Token token = m_RegexpLexer.token(); if(token.type == RegExpFromStringLexer::TokenType::PLUS) { next() || m_SymbolParser.first(); try { - RegExpElement* next = this->concatenation(); + UnboundedRegExpElement* next = this->concatenation(); res->appendElement(std::move(*next)); delete next; @@ -95,17 +100,19 @@ RegExpElement* RegExpFromStringParser::alternationContCont(Alternation* res) { } -RegExpElement* RegExpFromStringParser::concatenation() { +UnboundedRegExpElement* RegExpFromStringParser::concatenation() { return this->concatenationCont(this->factor()); } -RegExpElement* RegExpFromStringParser::concatenationCont(RegExpElement* left) { +UnboundedRegExpElement* RegExpFromStringParser::concatenationCont(UnboundedRegExpElement* left) { RegExpFromStringLexer::Token token = m_RegexpLexer.token(); if(token.type == RegExpFromStringLexer::TokenType::ERROR || token.type == RegExpFromStringLexer::TokenType::LPAR || token.type == RegExpFromStringLexer::TokenType::EPS || token.type == RegExpFromStringLexer::TokenType::EMPTY) { try { - RegExpElement* right = this->factor(); - Concatenation* res = new Concatenation(std::move(*left), std::move(*right)); + UnboundedRegExpElement* right = this->factor(); + UnboundedRegExpConcatenation* res = new UnboundedRegExpConcatenation(); + res->appendElement(std::move(*left)); + res->appendElement(std::move(*right)); delete right; delete left; left = NULL; @@ -121,12 +128,12 @@ RegExpElement* RegExpFromStringParser::concatenationCont(RegExpElement* left) { throw exception::AlibException("Impossible"); } -RegExpElement* RegExpFromStringParser::concatenationContCont(Concatenation* res) { +UnboundedRegExpElement* RegExpFromStringParser::concatenationContCont(UnboundedRegExpConcatenation* res) { RegExpFromStringLexer::Token token = m_RegexpLexer.token(); if(token.type == RegExpFromStringLexer::TokenType::ERROR || token.type == RegExpFromStringLexer::TokenType::LPAR || token.type == RegExpFromStringLexer::TokenType::EPS || token.type == RegExpFromStringLexer::TokenType::EMPTY) { try { - RegExpElement* next = this->factor(); + UnboundedRegExpElement* next = this->factor(); res->appendElement(std::move(*next)); delete next; @@ -141,33 +148,33 @@ RegExpElement* RegExpFromStringParser::concatenationContCont(Concatenation* res) throw exception::AlibException("Imúpssible"); } -RegExpElement* RegExpFromStringParser::factor() { +UnboundedRegExpElement* RegExpFromStringParser::factor() { RegExpFromStringLexer::Token token = m_RegexpLexer.token(); if(token.type == RegExpFromStringLexer::TokenType::LPAR) { next() || m_SymbolParser.first(); - RegExpElement* base = this->alternation(); + UnboundedRegExpElement* base = this->alternation(); token = m_RegexpLexer.token(); if(token.type != RegExpFromStringLexer::TokenType::RPAR) throw exception::AlibException(); return this->star(base); } else if(token.type == RegExpFromStringLexer::TokenType::EPS) { - return this->star(new RegExpEpsilon()); + return this->star(new UnboundedRegExpEpsilon()); } else if(token.type == RegExpFromStringLexer::TokenType::EMPTY) { - return this->star(new RegExpEmpty()); + return this->star(new UnboundedRegExpEmpty()); } else if(token.type == RegExpFromStringLexer::TokenType::ERROR) { - RegExpSymbol* res = new RegExpSymbol(m_SymbolParser.parse()); + UnboundedRegExpSymbol* res = new UnboundedRegExpSymbol(m_SymbolParser.parse()); return this->star(res); } else { throw exception::AlibException(); } } -RegExpElement* RegExpFromStringParser::star(RegExpElement* elem) { +UnboundedRegExpElement* RegExpFromStringParser::star(UnboundedRegExpElement* elem) { next() || m_SymbolParser.first(); RegExpFromStringLexer::Token token = m_RegexpLexer.token(); if(token.type == RegExpFromStringLexer::TokenType::STAR) { - Iteration* iter = new Iteration(std::move(*elem)); + UnboundedRegExpIteration* iter = new UnboundedRegExpIteration(std::move(*elem)); delete elem; return this->star(iter); } else { diff --git a/alib2data/src/regexp/RegExpFromStringParser.h b/alib2data/src/regexp/RegExpFromStringParser.h index 2f9291a33cde6412db9af4a9b45aafe6bc3e5d38..96c488031d3360963b9e1c5674bf6e8fbca6a8fe 100644 --- a/alib2data/src/regexp/RegExpFromStringParser.h +++ b/alib2data/src/regexp/RegExpFromStringParser.h @@ -9,7 +9,7 @@ #define REG_EXP_FROM_STRING_PARSER_H_ #include "RegExp.h" -#include "RegExpElements.h" +#include "unbounded/UnboundedRegExpElements.h" #include "RegExpFromStringLexer.h" #include "../alphabet/SymbolFromStringParser.h" @@ -19,16 +19,16 @@ namespace regexp { class RegExpFromStringParser : public alib::FromStringParser<RegExp, FEATURES> { - RegExpElement* alternation(); - RegExpElement* alternationCont(RegExpElement* left); - RegExpElement* alternationContCont(Alternation* left); + UnboundedRegExpElement* alternation(); + UnboundedRegExpElement* alternationCont(UnboundedRegExpElement* left); + UnboundedRegExpElement* alternationContCont(UnboundedRegExpAlternation* left); - RegExpElement* concatenation(); - RegExpElement* concatenationCont(RegExpElement* left); - RegExpElement* concatenationContCont(Concatenation* left); + UnboundedRegExpElement* concatenation(); + UnboundedRegExpElement* concatenationCont(UnboundedRegExpElement* left); + UnboundedRegExpElement* concatenationContCont(UnboundedRegExpConcatenation* left); - RegExpElement* factor(); - RegExpElement* star(RegExpElement* elem); + UnboundedRegExpElement* factor(); + UnboundedRegExpElement* star(UnboundedRegExpElement* elem); RegExpFromStringLexer m_RegexpLexer; alphabet::SymbolFromStringParser m_SymbolParser; diff --git a/alib2data/src/regexp/RegExpFromXMLParser.cpp b/alib2data/src/regexp/RegExpFromXMLParser.cpp index 1fdc6ad2239023784fc97a054f0cd1542a6fc143..2399549d0057cc1dacd0eb929f3136c3b426808c 100644 --- a/alib2data/src/regexp/RegExpFromXMLParser.cpp +++ b/alib2data/src/regexp/RegExpFromXMLParser.cpp @@ -14,34 +14,59 @@ namespace regexp { RegExp RegExpFromXMLParser::parse(std::list<sax::Token>& input) const { - return parse(input, std::set<FEATURES>({FEATURES::COMPACT})); + return parse(input, std::set<FEATURES>({FEATURES::FORMAL, FEATURES::UNBOUNDED})); } RegExp RegExpFromXMLParser::parse(std::list<sax::Token>& input, const std::set<FEATURES>& features) const { - if(!features.count(FEATURES::COMPACT)) throw exception::AlibException(); - popToken(input, sax::Token::TokenType::START_ELEMENT, "regexp"); - - RegExp regexp; - parseAlphabet(input, regexp); - - RegExpElement* element = parseElement(input); - regexp.setRegExp(std::move(*element)); - delete element; - - popToken(input, sax::Token::TokenType::END_ELEMENT, "regexp"); + if(isToken(input, sax::Token::TokenType::START_ELEMENT, "unboundedRegexp")) { + if(!features.count(FEATURES::UNBOUNDED)) throw exception::AlibException(); + popToken(input, sax::Token::TokenType::START_ELEMENT, "unboundedRegexp"); + + UnboundedRegExp regexp; + parseAlphabet(input, regexp); + + UnboundedRegExpElement* element = parseUnboundedRegExpElement(input); + regexp.setRegExp(std::move(*element)); + delete element; + + popToken(input, sax::Token::TokenType::END_ELEMENT, "unboundedRegexp"); + + return RegExp { regexp }; + } else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "formalRegexp")) { + if(!features.count(FEATURES::UNBOUNDED)) throw exception::AlibException(); + popToken(input, sax::Token::TokenType::START_ELEMENT, "formalRegexp"); + + FormalRegExp regexp; + parseAlphabet(input, regexp); - return regexp; + FormalRegExpElement* element = parseFormalRegExpElement(input); + regexp.setRegExp(std::move(*element)); + delete element; + + popToken(input, sax::Token::TokenType::END_ELEMENT, "formalRegexp"); + + return RegExp { regexp }; + } + throw exception::AlibException(); } bool RegExpFromXMLParser::first(std::list<sax::Token>& input) const { - if(isToken(input, sax::Token::TokenType::START_ELEMENT, "regexp")) { + if(isToken(input, sax::Token::TokenType::START_ELEMENT, "unboundedRegexp") || isToken(input, sax::Token::TokenType::START_ELEMENT, "formalRegexp")) { return true; } else { return false; } } -void RegExpFromXMLParser::parseAlphabet(std::list<sax::Token> &input, RegExp& regexp) const { +void RegExpFromXMLParser::parseAlphabet(std::list<sax::Token> &input, UnboundedRegExp& regexp) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "alphabet"); + while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + regexp.addSymbolToAlphabet(alib::FromXMLParsers::symbolParser.parse(input)); + } + popToken(input, sax::Token::TokenType::END_ELEMENT, "alphabet"); +} + +void RegExpFromXMLParser::parseAlphabet(std::list<sax::Token> &input, FormalRegExp& regexp) const { popToken(input, sax::Token::TokenType::START_ELEMENT, "alphabet"); while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { regexp.addSymbolToAlphabet(alib::FromXMLParsers::symbolParser.parse(input)); @@ -49,34 +74,38 @@ void RegExpFromXMLParser::parseAlphabet(std::list<sax::Token> &input, RegExp& re popToken(input, sax::Token::TokenType::END_ELEMENT, "alphabet"); } -RegExpElement* RegExpFromXMLParser::parseElement(std::list<sax::Token>& input) const { +UnboundedRegExpElement* RegExpFromXMLParser::parseUnboundedRegExpElement(std::list<sax::Token>& input) const { if (isToken(input, sax::Token::TokenType::START_ELEMENT, "empty")) { - return parseEmpty(input); + return parseUnboundedRegExpEmpty(input); } else if (isToken(input, sax::Token::TokenType::START_ELEMENT, "epsilon")) { - return parseEpsilon(input); + return parseUnboundedRegExpEpsilon(input); } else if (isToken(input, sax::Token::TokenType::START_ELEMENT, "iteration")) { - return parseIteration(input); + return parseUnboundedRegExpIteration(input); } else if (isToken(input, sax::Token::TokenType::START_ELEMENT, "alternation")) { - return parseAlternation(input); + return parseUnboundedRegExpAlternation(input); } else if (isToken(input, sax::Token::TokenType::START_ELEMENT, "concatenation")) { - return parseConcatenation(input); + return parseUnboundedRegExpConcatenation(input); } else { - return new RegExpSymbol(alib::FromXMLParsers::symbolParser.parse(input)); + return new UnboundedRegExpSymbol(alib::FromXMLParsers::symbolParser.parse(input)); } } -Alternation* RegExpFromXMLParser::parseAlternation(std::list<sax::Token>& input) const { +UnboundedRegExpAlternation* RegExpFromXMLParser::parseUnboundedRegExpAlternation(std::list<sax::Token>& input) const { popToken(input, sax::Token::TokenType::START_ELEMENT, "alternation"); - RegExpElement* element1 = parseElement(input); - RegExpElement* element2 = parseElement(input); + UnboundedRegExpElement* element1 = parseUnboundedRegExpElement(input); + UnboundedRegExpElement* element2 = parseUnboundedRegExpElement(input); - Alternation* alternation = new Alternation(std::move(*element1), std::move(*element2)); + UnboundedRegExpAlternation* alternation = new UnboundedRegExpAlternation(); + + alternation->appendElement(std::move(*element1)); + alternation->appendElement(std::move(*element2)); + delete element1; delete element2; while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { - RegExpElement* element = parseElement(input); + UnboundedRegExpElement* element = parseUnboundedRegExpElement(input); alternation->appendElement(std::move(*element)); delete element; } @@ -85,18 +114,22 @@ Alternation* RegExpFromXMLParser::parseAlternation(std::list<sax::Token>& input) return alternation; } -Concatenation* RegExpFromXMLParser::parseConcatenation(std::list<sax::Token>& input) const { +UnboundedRegExpConcatenation* RegExpFromXMLParser::parseUnboundedRegExpConcatenation(std::list<sax::Token>& input) const { popToken(input, sax::Token::TokenType::START_ELEMENT, "concatenation"); - RegExpElement* element1 = parseElement(input); - RegExpElement* element2 = parseElement(input); + UnboundedRegExpElement* element1 = parseUnboundedRegExpElement(input); + UnboundedRegExpElement* element2 = parseUnboundedRegExpElement(input); - Concatenation* concatenation = new Concatenation(std::move(*element1), std::move(*element2)); + UnboundedRegExpConcatenation* concatenation = new UnboundedRegExpConcatenation(); + + concatenation->appendElement(std::move(*element1)); + concatenation->appendElement(std::move(*element2)); + delete element1; delete element2; while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { - RegExpElement* element = parseElement(input); + UnboundedRegExpElement* element = parseUnboundedRegExpElement(input); concatenation->appendElement(std::move(*element)); delete element; } @@ -106,30 +139,106 @@ Concatenation* RegExpFromXMLParser::parseConcatenation(std::list<sax::Token>& in } -Iteration* RegExpFromXMLParser::parseIteration(std::list<sax::Token>& input) const { +UnboundedRegExpIteration* RegExpFromXMLParser::parseUnboundedRegExpIteration(std::list<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "iteration"); + + UnboundedRegExpElement* element = parseUnboundedRegExpElement(input); + UnboundedRegExpIteration* iteration = new UnboundedRegExpIteration(std::move(*element)); + delete element; + + popToken(input, sax::Token::TokenType::END_ELEMENT, "iteration"); + return iteration; +} + +UnboundedRegExpEpsilon* RegExpFromXMLParser::parseUnboundedRegExpEpsilon(std::list<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "epsilon"); + + UnboundedRegExpEpsilon* epsilon = new UnboundedRegExpEpsilon(); + + popToken(input, sax::Token::TokenType::END_ELEMENT, "epsilon"); + return epsilon; +} + +UnboundedRegExpEmpty* RegExpFromXMLParser::parseUnboundedRegExpEmpty(std::list<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "empty"); + + UnboundedRegExpEmpty* empty = new UnboundedRegExpEmpty(); + + popToken(input, sax::Token::TokenType::END_ELEMENT, "empty"); + return empty; +} + +FormalRegExpElement* RegExpFromXMLParser::parseFormalRegExpElement(std::list<sax::Token>& input) const { + if (isToken(input, sax::Token::TokenType::START_ELEMENT, "empty")) { + return parseFormalRegExpEmpty(input); + } else if (isToken(input, sax::Token::TokenType::START_ELEMENT, "epsilon")) { + return parseFormalRegExpEpsilon(input); + } else if (isToken(input, sax::Token::TokenType::START_ELEMENT, "iteration")) { + return parseFormalRegExpIteration(input); + } else if (isToken(input, sax::Token::TokenType::START_ELEMENT, "alternation")) { + return parseFormalRegExpAlternation(input); + } else if (isToken(input, sax::Token::TokenType::START_ELEMENT, "concatenation")) { + return parseFormalRegExpConcatenation(input); + } else { + return new FormalRegExpSymbol(alib::FromXMLParsers::symbolParser.parse(input)); + } +} + +FormalRegExpAlternation* RegExpFromXMLParser::parseFormalRegExpAlternation(std::list<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "alternation"); + + FormalRegExpElement* element1 = parseFormalRegExpElement(input); + FormalRegExpElement* element2 = parseFormalRegExpElement(input); + + FormalRegExpAlternation* alternation = new FormalRegExpAlternation(std::move(*element1), std::move(*element2)); + + delete element1; + delete element2; + + popToken(input, sax::Token::TokenType::END_ELEMENT, "alternation"); + return alternation; +} + +FormalRegExpConcatenation* RegExpFromXMLParser::parseFormalRegExpConcatenation(std::list<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "concatenation"); + + FormalRegExpElement* element1 = parseFormalRegExpElement(input); + FormalRegExpElement* element2 = parseFormalRegExpElement(input); + + FormalRegExpConcatenation* concatenation = new FormalRegExpConcatenation(std::move(*element1), std::move(*element2)); + + delete element1; + delete element2; + + popToken(input, sax::Token::TokenType::END_ELEMENT, "concatenation"); + return concatenation; + +} + +FormalRegExpIteration* RegExpFromXMLParser::parseFormalRegExpIteration(std::list<sax::Token>& input) const { popToken(input, sax::Token::TokenType::START_ELEMENT, "iteration"); - RegExpElement* element = parseElement(input); - Iteration* iteration = new Iteration(std::move(*element)); + FormalRegExpElement* element = parseFormalRegExpElement(input); + FormalRegExpIteration* iteration = new FormalRegExpIteration(std::move(*element)); delete element; popToken(input, sax::Token::TokenType::END_ELEMENT, "iteration"); return iteration; } -RegExpEpsilon* RegExpFromXMLParser::parseEpsilon(std::list<sax::Token>& input) const { +FormalRegExpEpsilon* RegExpFromXMLParser::parseFormalRegExpEpsilon(std::list<sax::Token>& input) const { popToken(input, sax::Token::TokenType::START_ELEMENT, "epsilon"); - RegExpEpsilon* epsilon = new RegExpEpsilon(); + FormalRegExpEpsilon* epsilon = new FormalRegExpEpsilon(); popToken(input, sax::Token::TokenType::END_ELEMENT, "epsilon"); return epsilon; } -RegExpEmpty* RegExpFromXMLParser::parseEmpty(std::list<sax::Token>& input) const { +FormalRegExpEmpty* RegExpFromXMLParser::parseFormalRegExpEmpty(std::list<sax::Token>& input) const { popToken(input, sax::Token::TokenType::START_ELEMENT, "empty"); - RegExpEmpty* empty = new RegExpEmpty(); + FormalRegExpEmpty* empty = new FormalRegExpEmpty(); popToken(input, sax::Token::TokenType::END_ELEMENT, "empty"); return empty; diff --git a/alib2data/src/regexp/RegExpFromXMLParser.h b/alib2data/src/regexp/RegExpFromXMLParser.h index 0d8cb5f87602ce036fe21ad0dd4d059e28a157b6..d124145c379f13b2ed1864cb1cee4c4812fa7e63 100644 --- a/alib2data/src/regexp/RegExpFromXMLParser.h +++ b/alib2data/src/regexp/RegExpFromXMLParser.h @@ -11,7 +11,8 @@ #include "../FromXMLParser.hpp" #include "RegExp.h" #include "RegExpFeatures.h" -#include "RegExpElements.h" +#include "unbounded/UnboundedRegExpElements.h" +#include "formal/FormalRegExpElements.h" #include "../sax/Token.h" #include "../alphabet/Symbol.h" @@ -27,15 +28,24 @@ namespace regexp { * Parser used to get RegExp from XML parsed into list of tokens. */ class RegExpFromXMLParser : public alib::FromXMLParser<RegExp, FEATURES> { - void parseAlphabet(std::list<sax::Token>& input, RegExp& regexp) const; + void parseAlphabet(std::list<sax::Token>& input, UnboundedRegExp& regexp) const; + void parseAlphabet(std::list<sax::Token>& input, FormalRegExp& regexp) const; - RegExpElement* parseElement(std::list<sax::Token>& input) const; + UnboundedRegExpElement* parseUnboundedRegExpElement(std::list<sax::Token>& input) const; - RegExpEpsilon* parseEpsilon(std::list<sax::Token>& input) const; - RegExpEmpty* parseEmpty(std::list<sax::Token>& input) const; - Iteration* parseIteration(std::list<sax::Token> &input) const; - Alternation* parseAlternation(std::list<sax::Token> &input) const; - Concatenation* parseConcatenation(std::list<sax::Token> &input) const; + UnboundedRegExpEpsilon* parseUnboundedRegExpEpsilon(std::list<sax::Token>& input) const; + UnboundedRegExpEmpty* parseUnboundedRegExpEmpty(std::list<sax::Token>& input) const; + UnboundedRegExpIteration* parseUnboundedRegExpIteration(std::list<sax::Token> &input) const; + UnboundedRegExpAlternation* parseUnboundedRegExpAlternation(std::list<sax::Token> &input) const; + UnboundedRegExpConcatenation* parseUnboundedRegExpConcatenation(std::list<sax::Token> &input) const; + + FormalRegExpElement* parseFormalRegExpElement(std::list<sax::Token>& input) const; + + FormalRegExpEpsilon* parseFormalRegExpEpsilon(std::list<sax::Token>& input) const; + FormalRegExpEmpty* parseFormalRegExpEmpty(std::list<sax::Token>& input) const; + FormalRegExpIteration* parseFormalRegExpIteration(std::list<sax::Token> &input) const; + FormalRegExpAlternation* parseFormalRegExpAlternation(std::list<sax::Token> &input) const; + FormalRegExpConcatenation* parseFormalRegExpConcatenation(std::list<sax::Token> &input) const; virtual RegExp parse(std::list<sax::Token>& input) const; virtual RegExp parse(std::list<sax::Token>& input, const std::set<FEATURES>& features) const; diff --git a/alib2data/src/regexp/RegExpSymbol.cpp b/alib2data/src/regexp/RegExpSymbol.cpp deleted file mode 100644 index d62251f019aaf77c06a6edadb50816f26391a350..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/RegExpSymbol.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * RegExpSymbol.cpp - * - * Created on: Nov 23, 2013 - * Author: Martin Zak - */ - -#include "RegExpSymbol.h" - -namespace regexp { - -RegExpSymbol::RegExpSymbol(const RegExpSymbol& other) : symbol(other.symbol) { - -} - -RegExpSymbol::RegExpSymbol(RegExpSymbol&& other) noexcept : symbol(std::move(other.symbol)) { - this->attachRegExp(NULL); -} - -RegExpSymbol& RegExpSymbol::operator=(const RegExpSymbol& other) { - if (this == &other) { - return *this; - } - - *this = RegExpSymbol(other); - - return *this; -} - -RegExpSymbol& RegExpSymbol::operator=(RegExpSymbol&& other) { - std::swap(this->symbol, other.symbol); - std::swap(this->parentRegExp, other.parentRegExp); - - this->attachRegExp(other.parentRegExp); - - return *this; -} - -RegExpSymbol::RegExpSymbol(const alphabet::Symbol& symbol) : - symbol(symbol) { -} - -RegExpSymbol::RegExpSymbol(alphabet::Symbol&& symbol) : - symbol(std::move(symbol)) { -} - -RegExpElement* RegExpSymbol::clone() const { - return new RegExpSymbol(*this); -} - -RegExpElement* RegExpSymbol::plunder() && { - return new RegExpSymbol(std::move(*this)); -} - -bool RegExpSymbol::operator==(const alphabet::Symbol& other) const { - return this->symbol == other; -} - -bool operator==(const alphabet::Symbol& first, const RegExpSymbol& second) { - return first == second.symbol; -} - -bool RegExpSymbol::operator<(const RegExpElement& other) const { - return other > *this; -} - -bool RegExpSymbol::operator==(const RegExpElement& other) const { - return other == *this; -} - -bool RegExpSymbol::operator>(const RegExpElement& other) const { - return other < *this; -} - - -bool RegExpSymbol::operator<(const RegExpSymbol& other) const { - return symbol < other.symbol; -} - -bool RegExpSymbol::operator==(const RegExpSymbol& other) const { - return symbol == other.symbol; -} - -void RegExpSymbol::operator>>(std::ostream& out) const { - out << "(RegExpSymbol " << symbol << ")"; -} - -bool RegExpSymbol::containsEmptyString() const { - return false; -} - -bool RegExpSymbol::isEmpty() const { - return false; -} - -bool RegExpSymbol::testSymbol( const alphabet::Symbol & symbol ) const { - return symbol == this->symbol; -} - -bool RegExpSymbol::attachRegExp(const RegExp * regexp ) { - if(this->parentRegExp == regexp) return true; - this->parentRegExp = regexp; - if(regexp == NULL) return true; - return this->parentRegExp->getAlphabet().find(this->symbol) != this->parentRegExp->getAlphabet().end(); -} - -void RegExpSymbol::computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const { - alphabet.insert(this->symbol); -} - -const alphabet::Symbol& RegExpSymbol::getSymbol() const { - return this->symbol; -} - -} /* namespace regexp */ - diff --git a/alib2data/src/regexp/RegExpSymbol.h b/alib2data/src/regexp/RegExpSymbol.h deleted file mode 100644 index 2939172ee507b3201a4b95d76a41a7c570b928be..0000000000000000000000000000000000000000 --- a/alib2data/src/regexp/RegExpSymbol.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * RegExpSymbol.h - * - * Created on: Nov 23, 2013 - * Author: Martin Zak - */ - -#ifndef REG_EXP_SYMBOL_H_ -#define REG_EXP_SYMBOL_H_ - -#include "../label/Label.h" -#include "RegExpElement.h" -#include "../alphabet/LabeledSymbol.h" - -namespace regexp { - -/** - * Represents symbol in the regular expression. Contains name of the symbol. - */ -class RegExpSymbol : public std::element<RegExpSymbol, RegExpElement> { -protected: - alphabet::Symbol symbol; - - /** - * @copydoc RegExpElement::clone() const - */ - virtual RegExpElement* clone() const; - - virtual RegExpElement* plunder() &&; - - /** - * @copydoc RegExpElement::testSymbol() const - */ - virtual bool testSymbol( const alphabet::Symbol & symbol ) const; - - /** - * @copydoc RegExpElement::attachRegExp() - */ - virtual bool attachRegExp ( const RegExp * regexp ); - - /** - * @copydoc RegExpElement::computeMinimalAlphabet() - */ - virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; -public: - explicit RegExpSymbol(const alphabet::Symbol& symbol); - explicit RegExpSymbol(alphabet::Symbol&& symbol); - - RegExpSymbol(const RegExpSymbol& other); - RegExpSymbol(RegExpSymbol&& other) noexcept; - RegExpSymbol& operator=(const RegExpSymbol& other); - RegExpSymbol& operator=(RegExpSymbol&& other); - - bool operator==(const alphabet::Symbol&) const; - friend bool operator==(const alphabet::Symbol&, const RegExpSymbol&); - - virtual bool operator<(const RegExpElement&) const; - virtual bool operator==(const RegExpElement&) const; - virtual bool operator>(const RegExpElement&) const; - - virtual bool operator<(const RegExpSymbol&) const; - virtual bool operator==(const RegExpSymbol&) const; - - /** - * @copydoc RegExpElement::operator>>() const - */ - virtual void operator>>(std::ostream& out) const; - - /** - * @copydoc RegExpElement::containsEmptyString() const - */ - virtual bool containsEmptyString() const; - - /** - * Returns the string representation of RegExp Symbol. - */ - const alphabet::Symbol& getSymbol() const; - - /** - * @copydoc RegExpElement::isEmpty() const - */ - virtual bool isEmpty() const; -}; - -} /* namespace regexp */ - -#endif /* REG_EXP_SYMBOL_H_ */ - diff --git a/alib2data/src/regexp/RegExpToStringComposer.cpp b/alib2data/src/regexp/RegExpToStringComposer.cpp index dc1c188c25ac95b72ed7dd139d68cec57348fcb0..84cd6a343f41717f3d546dcf29ef664b15e4dfe1 100644 --- a/alib2data/src/regexp/RegExpToStringComposer.cpp +++ b/alib2data/src/regexp/RegExpToStringComposer.cpp @@ -16,69 +16,177 @@ void RegExpToStringComposer::Visit(void* userData, const RegExp& regexp) { regexp.getRegExp().Accept(userData, *this); } -void RegExpToStringComposer::Visit(void* userData, const RegExpElement::element_type& element) { +void RegExpToStringComposer::Visit(void* userData, const RegExpBase::element_type& element) { element.Accept(userData, *this); } -void RegExpToStringComposer::Visit(void* userData, const Alternation& alternation) { +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExp& regexp) { + regexp.getRegExp().Accept(userData, *this); +} + +void RegExpToStringComposer::Visit(void* userData, const FormalRegExp& regexp) { + regexp.getRegExp().Accept(userData, *this); +} + +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpElement::element_type& element) { + element.Accept(userData, *this); +} + +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpAlternation& alternation) { + std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); + + if(alternation.getElements().size() == 0) { + out.second << "#0"; + } else if(alternation.getElements().size() == 1) { + const auto& element = alternation.getElements()[0]; + const UnboundedRegExpElement::element_type& object = static_cast<const UnboundedRegExpElement::element_type&>(*element); + object.Accept(userData, *this); + } else { + Priority outerPriorityMinimum = out.first; + if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) out.second << '('; + bool first = true; + for (const auto& element : alternation.getElements()) { + if(first) { + first = false; + } else { + out.second << '+'; + } + const UnboundedRegExpElement::element_type& object = static_cast<const UnboundedRegExpElement::element_type&>(*element); + out.first = Priority::ALTERNATION; + object.Accept(userData, *this); + } + if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) out.second << ')'; + } +} + +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpConcatenation& concatenation) { std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); Priority outerPriorityMinimum = out.first; - if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) out.second << '('; - bool first = true; - for (const auto& element : alternation.getElements()) { - if(first) { - first = false; - } else { - out.second << '+'; + if(concatenation.getElements().size() == 0) { + out.second << "#E"; + } else if(concatenation.getElements().size() == 1) { + const auto& element = concatenation.getElements()[0]; + const UnboundedRegExpElement::element_type& object = static_cast<const UnboundedRegExpElement::element_type&>(*element); + object.Accept(userData, *this); + } else { + if(outerPriorityMinimum == Priority::FACTOR) out.second << '('; + bool first = true; + for (auto element : concatenation.getElements()) { + if(first) + first = false; + else + out.second << ' '; + const UnboundedRegExpElement::element_type& object = static_cast<const UnboundedRegExpElement::element_type&>(*element); + out.first = Priority::CONCATENATION; + object.Accept(userData, *this); } - const RegExpElement::element_type& object = static_cast<const RegExpElement::element_type&>(*element); - out.first = Priority::ALTERNATION; + if(outerPriorityMinimum == Priority::FACTOR) out.second << ')'; + } +} + +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpIteration& iteration) { + std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); + + const UnboundedRegExpElement::element_type& object = static_cast<const UnboundedRegExpElement::element_type&>(iteration.getElement()); + out.first = Priority::FACTOR; + object.Accept(userData, *this); + out.second << "*"; +} + +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpSymbol& symbol) { + std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); + + alphabet::SymbolToStringComposer composer; + out.second << composer.compose(symbol.getSymbol()); +} + +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpEpsilon&) { + std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); + out.second << "#E"; +} + +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpEmpty&) { + std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); + out.second << "#0"; +} + +void RegExpToStringComposer::Visit(void* userData, const FormalRegExpElement::element_type& element) { + element.Accept(userData, *this); +} + +void RegExpToStringComposer::Visit(void* userData, const FormalRegExpAlternation& alternation) { + std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); + + Priority outerPriorityMinimum = out.first; + if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) out.second << '('; + + out.first = Priority::ALTERNATION; + + { + const auto& element = alternation.getLeftElement(); + const FormalRegExpElement::element_type& object = static_cast<const FormalRegExpElement::element_type&>(element); + object.Accept(userData, *this); + } + + out.second << '+'; + + { + const auto& element = alternation.getRightElement(); + const FormalRegExpElement::element_type& object = static_cast<const FormalRegExpElement::element_type&>(element); object.Accept(userData, *this); } + if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) out.second << ')'; } -void RegExpToStringComposer::Visit(void* userData, const Concatenation& concatenation) { +void RegExpToStringComposer::Visit(void* userData, const FormalRegExpConcatenation& concatenation) { std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); Priority outerPriorityMinimum = out.first; if(outerPriorityMinimum == Priority::FACTOR) out.second << '('; - bool first = true; - for (auto element : concatenation.getElements()) { - if(first) - first = false; - else - out.second << ' '; - const RegExpElement::element_type& object = static_cast<const RegExpElement::element_type&>(*element); - out.first = Priority::CONCATENATION; + + out.first = Priority::CONCATENATION; + + { + const auto& element = concatenation.getLeftElement(); + const FormalRegExpElement::element_type& object = static_cast<const FormalRegExpElement::element_type&>(element); + object.Accept(userData, *this); + } + + out.second << '+'; + + { + const auto& element = concatenation.getRightElement(); + const FormalRegExpElement::element_type& object = static_cast<const FormalRegExpElement::element_type&>(element); object.Accept(userData, *this); } + if(outerPriorityMinimum == Priority::FACTOR) out.second << ')'; } -void RegExpToStringComposer::Visit(void* userData, const Iteration& iteration) { +void RegExpToStringComposer::Visit(void* userData, const FormalRegExpIteration& iteration) { std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); - const RegExpElement::element_type& object = static_cast<const RegExpElement::element_type&>(iteration.getElement()); + const FormalRegExpElement::element_type& object = static_cast<const FormalRegExpElement::element_type&>(iteration.getElement()); out.first = Priority::FACTOR; object.Accept(userData, *this); out.second << "*"; } -void RegExpToStringComposer::Visit(void* userData, const RegExpSymbol& symbol) { +void RegExpToStringComposer::Visit(void* userData, const FormalRegExpSymbol& symbol) { std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); alphabet::SymbolToStringComposer composer; out.second << composer.compose(symbol.getSymbol()); } -void RegExpToStringComposer::Visit(void* userData, const RegExpEpsilon&) { +void RegExpToStringComposer::Visit(void* userData, const FormalRegExpEpsilon&) { std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); out.second << "#E"; } -void RegExpToStringComposer::Visit(void* userData, const RegExpEmpty&) { +void RegExpToStringComposer::Visit(void* userData, const FormalRegExpEmpty&) { std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); out.second << "#0"; } diff --git a/alib2data/src/regexp/RegExpToStringComposer.h b/alib2data/src/regexp/RegExpToStringComposer.h index 00f23cdee7b73c241d29f40512a7daa14eefcd5e..f666ad14a4df93ea1f3268b26486fdea3476f2cd 100644 --- a/alib2data/src/regexp/RegExpToStringComposer.h +++ b/alib2data/src/regexp/RegExpToStringComposer.h @@ -10,21 +10,38 @@ #include <string> #include "RegExp.h" -#include "RegExpElements.h" +#include "unbounded/UnboundedRegExpElements.h" +#include "formal/FormalRegExpElements.h" namespace regexp { -class RegExpToStringComposer : public RegExpElement::visitor_type { - void Visit(void*, const Alternation& alternation); - void Visit(void*, const Concatenation& concatenation); - void Visit(void*, const Iteration& iteration); - void Visit(void*, const RegExpSymbol& symbol); - void Visit(void*, const RegExpEpsilon& epsilon); - void Visit(void*, const RegExpEmpty& empty); - - void Visit(void*, const RegExpElement::element_type& element); - - +class RegExpToStringComposer : public RegExpBase::visitor_type, UnboundedRegExpElement::visitor_type, FormalRegExpElement::visitor_type { + void Visit(void*, const UnboundedRegExpAlternation& alternation); + void Visit(void*, const UnboundedRegExpConcatenation& concatenation); + void Visit(void*, const UnboundedRegExpIteration& iteration); + void Visit(void*, const UnboundedRegExpSymbol& symbol); + void Visit(void*, const UnboundedRegExpEpsilon& epsilon); + void Visit(void*, const UnboundedRegExpEmpty& empty); + + void Visit(void*, const UnboundedRegExpElement::element_type& element); + + + void Visit(void*, const FormalRegExpAlternation& alternation); + void Visit(void*, const FormalRegExpConcatenation& concatenation); + void Visit(void*, const FormalRegExpIteration& iteration); + void Visit(void*, const FormalRegExpSymbol& symbol); + void Visit(void*, const FormalRegExpEpsilon& epsilon); + void Visit(void*, const FormalRegExpEmpty& empty); + + void Visit(void*, const FormalRegExpElement::element_type& element); + + + void Visit(void*, const UnboundedRegExp& empty); + void Visit(void*, const FormalRegExp& empty); + + void Visit(void*, const RegExpBase::element_type& element); + + void Visit(void*, const RegExp& empty); enum class Priority { diff --git a/alib2data/src/regexp/RegExpToXMLComposer.cpp b/alib2data/src/regexp/RegExpToXMLComposer.cpp index dabb628930faa0d28ad3b6875eb1c6b1a6a1982b..5bf722f6b66aeb1f32c04e82157664b1d168e804 100644 --- a/alib2data/src/regexp/RegExpToXMLComposer.cpp +++ b/alib2data/src/regexp/RegExpToXMLComposer.cpp @@ -12,9 +12,17 @@ namespace regexp { void RegExpToXMLComposer::Visit(void* userData, const RegExp& regexp) const { + regexp.getRegExp().Accept(userData, *this); +} + +void RegExpToXMLComposer::Visit(void* userData, const RegExpBase::element_type& element) const { + element.Accept(userData, *this); +} + +void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExp& regexp) const { std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); - out.push_back(sax::Token("regexp", sax::Token::TokenType::START_ELEMENT)); + out.push_back(sax::Token("unboundedRegexp", sax::Token::TokenType::START_ELEMENT)); { out.push_back(sax::Token("alphabet", sax::Token::TokenType::START_ELEMENT)); for (const auto& symbol: regexp.getAlphabet()) { @@ -23,59 +31,142 @@ void RegExpToXMLComposer::Visit(void* userData, const RegExp& regexp) const { out.push_back(sax::Token("alphabet", sax::Token::TokenType::END_ELEMENT)); } regexp.getRegExp().Accept(userData, *this); - out.push_back(sax::Token("regexp", sax::Token::TokenType::END_ELEMENT)); + out.push_back(sax::Token("unboundedRegexp", sax::Token::TokenType::END_ELEMENT)); } -void RegExpToXMLComposer::Visit(void* userData, const RegExpElement::element_type& element) const { +void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpElement::element_type& element) const { element.Accept(userData, *this); } -void RegExpToXMLComposer::Visit(void* userData, const Alternation& alternation) const { +void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpAlternation& alternation) const { std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); out.push_back(sax::Token("alternation", sax::Token::TokenType::START_ELEMENT)); for (const auto& element : alternation.getElements()) { - const RegExpElement::element_type& object = static_cast<const RegExpElement::element_type&>(*element); + const UnboundedRegExpElement::element_type& object = static_cast<const UnboundedRegExpElement::element_type&>(*element); object.Accept(userData, *this); } out.push_back(sax::Token("alternation", sax::Token::TokenType::END_ELEMENT)); } -void RegExpToXMLComposer::Visit(void* userData, const Concatenation& concatenation) const { +void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpConcatenation& concatenation) const { std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); out.push_back(sax::Token("concatenation", sax::Token::TokenType::START_ELEMENT)); for (auto element : concatenation.getElements()) { - const RegExpElement::element_type& object = static_cast<const RegExpElement::element_type&>(*element); + const UnboundedRegExpElement::element_type& object = static_cast<const UnboundedRegExpElement::element_type&>(*element); + object.Accept(userData, *this); + } + out.push_back(sax::Token("concatenation", sax::Token::TokenType::END_ELEMENT)); + +} + +void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpIteration& iteration) const { + std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); + + out.push_back(sax::Token("iteration", sax::Token::TokenType::START_ELEMENT)); + const UnboundedRegExpElement::element_type& object = static_cast<const UnboundedRegExpElement::element_type&>(iteration.getElement()); + object.Accept(userData, *this); + out.push_back(sax::Token("iteration", sax::Token::TokenType::END_ELEMENT)); +} + +void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpSymbol& symbol) const { + std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); + + out.splice(out.end(), alib::ToXMLComposers::symbolComposer.compose(symbol.getSymbol())); +} + +void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpEpsilon&) 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("epsilon", sax::Token::TokenType::END_ELEMENT)); +} + +void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpEmpty&) const { + std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); + + out.push_back(sax::Token("empty", sax::Token::TokenType::START_ELEMENT)); + out.push_back(sax::Token("empty", sax::Token::TokenType::END_ELEMENT)); +} + +void RegExpToXMLComposer::Visit(void* userData, const FormalRegExp& regexp) const { + std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); + + out.push_back(sax::Token("formalRegexp", sax::Token::TokenType::START_ELEMENT)); + { + out.push_back(sax::Token("alphabet", sax::Token::TokenType::START_ELEMENT)); + for (const auto& symbol: regexp.getAlphabet()) { + out.splice(out.end(), alib::ToXMLComposers::symbolComposer.compose(symbol)); + } + out.push_back(sax::Token("alphabet", sax::Token::TokenType::END_ELEMENT)); + } + regexp.getRegExp().Accept(userData, *this); + out.push_back(sax::Token("formalRegexp", sax::Token::TokenType::END_ELEMENT)); +} + +void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpElement::element_type& element) const { + element.Accept(userData, *this); +} + +void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpAlternation& alternation) const { + std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); + + out.push_back(sax::Token("alternation", sax::Token::TokenType::START_ELEMENT)); + { + const auto& element = alternation.getLeftElement(); + const FormalRegExpElement::element_type& object = static_cast<const FormalRegExpElement::element_type&>(element); + object.Accept(userData, *this); + } + { + const auto& element = alternation.getRightElement(); + const FormalRegExpElement::element_type& object = static_cast<const FormalRegExpElement::element_type&>(element); + object.Accept(userData, *this); + } + out.push_back(sax::Token("alternation", sax::Token::TokenType::END_ELEMENT)); +} + +void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpConcatenation& concatenation) const { + std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); + + out.push_back(sax::Token("concatenation", sax::Token::TokenType::START_ELEMENT)); + { + const auto& element = concatenation.getLeftElement(); + const FormalRegExpElement::element_type& object = static_cast<const FormalRegExpElement::element_type&>(element); + object.Accept(userData, *this); + } + { + const auto& element = concatenation.getRightElement(); + const FormalRegExpElement::element_type& object = static_cast<const FormalRegExpElement::element_type&>(element); object.Accept(userData, *this); } out.push_back(sax::Token("concatenation", sax::Token::TokenType::END_ELEMENT)); } -void RegExpToXMLComposer::Visit(void* userData, const Iteration& iteration) const { +void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpIteration& iteration) const { std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); out.push_back(sax::Token("iteration", sax::Token::TokenType::START_ELEMENT)); - const RegExpElement::element_type& object = static_cast<const RegExpElement::element_type&>(iteration.getElement()); + const FormalRegExpElement::element_type& object = static_cast<const FormalRegExpElement::element_type&>(iteration.getElement()); object.Accept(userData, *this); out.push_back(sax::Token("iteration", sax::Token::TokenType::END_ELEMENT)); } -void RegExpToXMLComposer::Visit(void* userData, const RegExpSymbol& symbol) const { +void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpSymbol& symbol) const { std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); out.splice(out.end(), alib::ToXMLComposers::symbolComposer.compose(symbol.getSymbol())); } -void RegExpToXMLComposer::Visit(void* userData, const RegExpEpsilon&) const { +void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpEpsilon&) 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("epsilon", sax::Token::TokenType::END_ELEMENT)); } -void RegExpToXMLComposer::Visit(void* userData, const RegExpEmpty&) const { +void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpEmpty&) const { std::list<sax::Token> &out = *((std::list<sax::Token>*) userData); out.push_back(sax::Token("empty", sax::Token::TokenType::START_ELEMENT)); diff --git a/alib2data/src/regexp/RegExpToXMLComposer.h b/alib2data/src/regexp/RegExpToXMLComposer.h index 4a8de9cb3f67989172d7d527e69b43f485cba804..0097fda4b8d3a544dd9f57a9612489a629681c68 100644 --- a/alib2data/src/regexp/RegExpToXMLComposer.h +++ b/alib2data/src/regexp/RegExpToXMLComposer.h @@ -9,7 +9,8 @@ #define REG_EXP_TO_XML_COMPOSER_H_ #include "RegExp.h" -#include "RegExpElements.h" +#include "unbounded/UnboundedRegExpElements.h" +#include "formal/FormalRegExpElements.h" #include "../std/visitor.hpp" #include "../sax/Token.h" @@ -18,18 +19,34 @@ namespace regexp { /** * This class contains methods to print XML representation of regular expression to the output stream. */ -class RegExpToXMLComposer : public RegExpElement::const_visitor_type { - void Visit(void*, const Alternation& alternation) const; - void Visit(void*, const Concatenation& concatenation) const; - void Visit(void*, const Iteration& iteration) const; - void Visit(void*, const RegExpSymbol& symbol) const; - void Visit(void*, const RegExpEpsilon& epsilon) const; - void Visit(void*, const RegExpEmpty& empty) const; +class RegExpToXMLComposer : public RegExpBase::const_visitor_type, UnboundedRegExpElement::const_visitor_type, FormalRegExpElement::const_visitor_type { + void Visit(void*, const UnboundedRegExpAlternation& alternation) const; + void Visit(void*, const UnboundedRegExpConcatenation& concatenation) const; + void Visit(void*, const UnboundedRegExpIteration& iteration) const; + void Visit(void*, const UnboundedRegExpSymbol& symbol) const; + void Visit(void*, const UnboundedRegExpEpsilon& epsilon) const; + void Visit(void*, const UnboundedRegExpEmpty& empty) const; - void Visit(void*, const RegExpElement::element_type& element) const; + void Visit(void*, const UnboundedRegExpElement::element_type& element) const; - void Visit(void*, const RegExp& empty) const; + void Visit(void*, const FormalRegExpAlternation& alternation) const; + void Visit(void*, const FormalRegExpConcatenation& concatenation) const; + void Visit(void*, const FormalRegExpIteration& iteration) const; + void Visit(void*, const FormalRegExpSymbol& symbol) const; + void Visit(void*, const FormalRegExpEpsilon& epsilon) const; + void Visit(void*, const FormalRegExpEmpty& empty) const; + + void Visit(void*, const FormalRegExpElement::element_type& element) const; + + + void Visit(void*, const UnboundedRegExp& empty) const; + void Visit(void*, const FormalRegExp& empty) const; + + void Visit(void*, const RegExpBase::element_type& element) const; + + + void Visit(void*, const RegExp& regexp) const; public: /** diff --git a/alib2data/src/regexp/formal/FormalRegExp.cpp b/alib2data/src/regexp/formal/FormalRegExp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e1a6319427f6eba4782f82365c5f5e4edc480370 --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExp.cpp @@ -0,0 +1,186 @@ +/* + * FormalRegExp.cpp + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#include "FormalRegExp.h" +#include "../../exception/AlibException.h" +#include "FormalRegExpEmpty.h" +#include "FormalRegExpSymbol.h" + +#include <iostream> +#include <algorithm> +#include <sstream> + +#include "../../std/set.hpp" +#include "../unbounded/UnboundedRegExp.h" + +namespace regexp { + +FormalRegExp::FormalRegExp() { + this->regExp = new FormalRegExpEmpty(); +} + +FormalRegExp::FormalRegExp(const std::set<alphabet::Symbol>& alphabet, const FormalRegExpElement& regExp) : alphabet(alphabet) { + this->regExp = NULL; + setRegExp(regExp); +} + +FormalRegExp::FormalRegExp(std::set<alphabet::Symbol>&& alphabet, FormalRegExpElement&& regExp) : alphabet(std::move(alphabet)) { + this->regExp = NULL; + setRegExp(std::move(regExp)); +} + +FormalRegExp::FormalRegExp(const FormalRegExpElement& regExp) { + regExp.computeMinimalAlphabet(alphabet); + this->regExp = NULL; + setRegExp(regExp); +} + +FormalRegExp::FormalRegExp(FormalRegExpElement&& regExp) { + regExp.computeMinimalAlphabet(alphabet); + this->regExp = NULL; + setRegExp(std::move(regExp)); +} + +FormalRegExp::FormalRegExp(const FormalRegExp& other) : regExp(other.regExp->clone()), alphabet(other.alphabet) { + this->regExp->attachRegExp(this); +} + +FormalRegExp::FormalRegExp(FormalRegExp&& other) noexcept : regExp(other.regExp), alphabet(std::move(other.alphabet) ) { + this->regExp->attachRegExp(this); + other.regExp = NULL; +} + +RegExpBase* FormalRegExp::clone() const { + return new FormalRegExp(*this); +} + +RegExpBase* FormalRegExp::plunder() && { + return new FormalRegExp(std::move(*this)); +} + +FormalRegExp& FormalRegExp::operator=(const FormalRegExp& other) { + if (this == &other) { + return *this; + } + + *this = FormalRegExp(other); + + return *this; +} + +FormalRegExp& FormalRegExp::operator=(FormalRegExp&& other) noexcept { + std::swap(this->regExp, other.regExp); + std::swap(this->alphabet, other.alphabet); + return *this; +} + +FormalRegExp::~FormalRegExp() noexcept { + delete regExp; +} + +const FormalRegExpElement& FormalRegExp::getRegExp() const { + return *regExp; +} + +FormalRegExpElement& FormalRegExp::getRegExp() { + return *regExp; +} + +void FormalRegExp::setRegExp(const FormalRegExpElement& regExp) { + delete this->regExp; + this->regExp = regExp.clone(); + if(!this->regExp->attachRegExp(this)) + throw exception::AlibException("Input symbols not in the alphabet."); +} + +void FormalRegExp::setRegExp(FormalRegExpElement&& regExp) { + delete this->regExp; + this->regExp = std::move(regExp).plunder(); + if(!this->regExp->attachRegExp(this)) + throw exception::AlibException("Input symbols not in the alphabet."); +} + +const std::set<alphabet::Symbol>& FormalRegExp::getAlphabet() const { + return alphabet; +} + +bool FormalRegExp::addSymbolToAlphabet(const alphabet::Symbol & symbol) { + return alphabet.insert(symbol).second; +} + +void FormalRegExp::setAlphabet(const std::set<alphabet::Symbol> & symbols) { + std::set<alphabet::Symbol> minimalAlphabet; + this->regExp->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 FormalRegExp::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) { + if(this->regExp->testSymbol(symbol)) + throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is used."); + + return alphabet.erase(symbol); +} + +bool FormalRegExp::isEmpty() const { + return regExp->isEmpty(); +} + +bool FormalRegExp::containsEmptyString() const { + return regExp->containsEmptyString(); +} + +void FormalRegExp::operator >>(std::ostream& out) const { + out << "(FormalRegExp " << *(this->regExp) << ")"; +} + +bool FormalRegExp::operator<(const UnboundedRegExp& other) const { + return typeid(*this).before(typeid(other)); +} + +bool FormalRegExp::operator<(const FormalRegExp& other) const { + if(*(this->regExp) < *(other.regExp)) { + return true; + } else if(*(this->regExp) > *(other.regExp)) { + return false; + } else { + return this->alphabet < other.alphabet; + } +} + +bool FormalRegExp::operator==(const UnboundedRegExp&) const { + return false; +} + +bool FormalRegExp::operator==(const FormalRegExp& other) const { + return *(this->regExp) == *(other.regExp) && this->alphabet == other.alphabet; +} + +bool FormalRegExp::operator<(const RegExpBase& other) const { + return other > *this; +} + +bool FormalRegExp::operator ==(const RegExpBase& other) const { + return other == *this; +} + +bool FormalRegExp::operator >(const RegExpBase& other) const { + return other < *this; +} + +FormalRegExp::operator std::string () const { + std::stringstream ss; + ss << *this; + return ss.str(); +} + +} /* namespace regexp */ diff --git a/alib2data/src/regexp/formal/FormalRegExp.h b/alib2data/src/regexp/formal/FormalRegExp.h new file mode 100644 index 0000000000000000000000000000000000000000..2a2f7082b4baaaad58da3cda3543c82beb282777 --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExp.h @@ -0,0 +1,140 @@ +/* + * FormalRegExp.h + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#ifndef FORMAL_REG_EXP_H_ +#define FORMAL_REG_EXP_H_ + +#include <vector> +#include <list> +#include <string> +#include <set> +#include "FormalRegExpElement.h" +#include "../../std/visitor.hpp" +#include "../RegExpBase.h" + +namespace regexp { + +class FormalRegExpElement; + +/** + * Represents regular expression parsed from the XML. Regular expression is stored + * as a tree of RegExpElement. + */ +class FormalRegExp : public std::element<FormalRegExp, RegExpBase> { +protected: + FormalRegExpElement* regExp; + + std::set<alphabet::Symbol> alphabet; + + /** + * @copydoc FormalRegExpElement::clone() const + */ + virtual RegExpBase* clone() const; + + /** + * @copydoc FormalRegExpElement::plunder() const + */ + virtual RegExpBase* plunder() &&; + +public: + FormalRegExp(); + FormalRegExp(const std::set<alphabet::Symbol>& alphabet, const FormalRegExpElement& regExp); + FormalRegExp(std::set<alphabet::Symbol>&& alphabet, FormalRegExpElement&& regExp); + explicit FormalRegExp(const FormalRegExpElement& regExp); + explicit FormalRegExp(FormalRegExpElement&& regExp); + + /** + * Copy constructor. + * @param other RegExp to copy + */ + FormalRegExp(const FormalRegExp& other); + FormalRegExp(FormalRegExp&& other) noexcept; + FormalRegExp& operator =(const FormalRegExp& other); + FormalRegExp& operator =(FormalRegExp&& other) noexcept; + ~FormalRegExp() noexcept; + + /** + * @return Root node of the regular expression tree + */ + const FormalRegExpElement& getRegExp() const; + + /** + * @return Root node of the regular expression tree + */ + FormalRegExpElement& getRegExp(); + + /** + * Sets the root node of the regular expression tree. Doesn't perform copy of the regExp param, + * just stores it! + * @param regExp root node to set + */ + void setRegExp(const FormalRegExpElement& regExp); + + /** + * Sets the root node of the regular expression tree + * @param regExp root node to set + */ + void setRegExp(FormalRegExpElement&& regExp); + + /** + * Gets alphabet symbols used in RegExp. + * @return set of alphabet symbols used in regexp. + */ + const std::set<alphabet::Symbol>& getAlphabet() const; + + /** + * Adds symbol to the alphabet available in the regular expression + * @param symbol new symbol added to the alphabet + */ + bool addSymbolToAlphabet(const alphabet::Symbol & symbol); + + /** + * Sets the alphabet of the regular expression + * @param symbols new alphabet + */ + void setAlphabet(const std::set<alphabet::Symbol>& symbols); + + /** + * Removes symbol from the alphabet of symbol available in the regular expression + * @param symbol removed symbol from the alphabet + */ + bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol); + + /** + * @return true if regexp represents empty language + */ + bool isEmpty() const; + + /** + * @return true if regexp matches empty string (epsilon) + */ + bool containsEmptyString() const; + + /** + * Prints XML representation of the RegExp to the output stream. + * @param out output stream to which print the RegExp + * @param regexp RegExp to print + */ + virtual void operator>>(std::ostream& out) const; + + virtual bool operator <(const RegExpBase& other) const; + virtual bool operator ==(const RegExpBase& other) const; + virtual bool operator >(const RegExpBase& other) const; + + virtual bool operator==(const FormalRegExp& other) const; + virtual bool operator==(const UnboundedRegExp&) const; + + virtual bool operator<(const FormalRegExp& other) const; + virtual bool operator<(const UnboundedRegExp&) const; + + virtual operator std::string() const; + +}; + +} /* namespace regexp */ + +#endif /* FORMAL_REG_EXP_H_ */ diff --git a/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp b/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..45457e9bda67a1e5527358ada641c6cac9194179 --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp @@ -0,0 +1,172 @@ +/* + * FormalRegExpAlternation.cpp + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#include "FormalRegExpAlternation.h" +#include "../../exception/AlibException.h" + +namespace regexp { + +FormalRegExpAlternation::FormalRegExpAlternation(FormalRegExpElement&& left, FormalRegExpElement&& right) { + this->left = std::move(left).plunder(); + this->right = std::move(right).plunder(); +} + +FormalRegExpAlternation::FormalRegExpAlternation(const FormalRegExpElement& left, const FormalRegExpElement& right) { + this->left = left.clone(); + this->right = right.clone(); +} + +FormalRegExpAlternation::FormalRegExpAlternation(const FormalRegExpAlternation& other) { + this->left = other.left->clone(); + this->right = other.right->clone(); +} + +FormalRegExpAlternation::FormalRegExpAlternation(FormalRegExpAlternation&& other) noexcept : left(std::move(other.left)), right(std::move(other.right)) { + other.left = NULL; + other.right = NULL; + this->attachRegExp(NULL); +} + +FormalRegExpAlternation& FormalRegExpAlternation::operator=(const FormalRegExpAlternation& other) { + if (this == &other) { + return *this; + } + + *this = FormalRegExpAlternation(other); + + return *this; +} + +FormalRegExpAlternation& FormalRegExpAlternation::operator=(FormalRegExpAlternation&& other) { + std::swap(this->left, other.left); + std::swap(this->right, other.right); + std::swap(this->parentRegExp, other.parentRegExp); + + this->attachRegExp(other.parentRegExp); + + return *this; +} + +FormalRegExpAlternation::~FormalRegExpAlternation() noexcept { + delete left; + delete right; +} + +const FormalRegExpElement & FormalRegExpAlternation::getLeftElement() const { + return *left; +} + +const FormalRegExpElement & FormalRegExpAlternation::getRightElement() const { + return *right; +} + +FormalRegExpElement & FormalRegExpAlternation::getLeftElement() { + return *left; +} + +FormalRegExpElement & FormalRegExpAlternation::getRightElement() { + return *right; +} + +void FormalRegExpAlternation::setLeftElement(const FormalRegExpElement& element) { + FormalRegExpElement* elem = element.clone(); + if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + delete left; + this->left = elem; +} + +void FormalRegExpAlternation::setLeftElement(FormalRegExpElement&& element) { + FormalRegExpElement* elem = std::move(element).plunder(); + if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + delete left; + this->left = elem; +} + +void FormalRegExpAlternation::setRightElement(const FormalRegExpElement& element) { + FormalRegExpElement* elem = element.clone(); + if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + delete right; + this->right = elem; +} + +void FormalRegExpAlternation::setRightElement(FormalRegExpElement&& element) { + FormalRegExpElement* elem = std::move(element).plunder(); + if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + delete right; + this->right = elem; +} + +FormalRegExpElement* FormalRegExpAlternation::clone() const { + return new FormalRegExpAlternation(*this); +} + +FormalRegExpElement* FormalRegExpAlternation::plunder() && { + return new FormalRegExpAlternation(std::move(*this)); +} + +bool FormalRegExpAlternation::operator<(const FormalRegExpElement& other) const { + return other > *this; +} + +bool FormalRegExpAlternation::operator==(const FormalRegExpElement& other) const { + return other == *this; +} + +bool FormalRegExpAlternation::operator>(const FormalRegExpElement& other) const { + return other < *this; +} + + +bool FormalRegExpAlternation::operator<(const FormalRegExpAlternation& other) const { + if(this->left == other.left) return this->right < other.right; + return this->left < other.left; +} + +bool FormalRegExpAlternation::operator==(const FormalRegExpAlternation& other) const { + return this->left == other.left && this->right == other.right; +} + +void FormalRegExpAlternation::operator>>(std::ostream& out) const { + out << "(FormalRegExpAlternation"; + out << " " << *left; + out << " " << *right; + out << ")"; +} + +bool FormalRegExpAlternation::testSymbol( const alphabet::Symbol & symbol ) const { + if(left->testSymbol(symbol)) return true; + if(right->testSymbol(symbol)) return true; + return false; +} + +bool FormalRegExpAlternation::attachRegExp(const FormalRegExp * regexp ) { + if(this->parentRegExp == regexp) return true; + + this->parentRegExp = regexp; + if(!left->attachRegExp(regexp)) return false; + if(!right->attachRegExp(regexp)) return false; + return true; +} + +void FormalRegExpAlternation::computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const { + left->computeMinimalAlphabet(alphabet); + right->computeMinimalAlphabet(alphabet); +} + +bool FormalRegExpAlternation::containsEmptyString() const { + return left->containsEmptyString() || right->containsEmptyString(); +} + +bool FormalRegExpAlternation::isEmpty() const { + return left->isEmpty() && right->isEmpty(); +} + +} /* namespace regexp */ diff --git a/alib2data/src/regexp/formal/FormalRegExpAlternation.h b/alib2data/src/regexp/formal/FormalRegExpAlternation.h new file mode 100644 index 0000000000000000000000000000000000000000..4f317b8de717922fcbfbc6d1e4bb1d58e77da0e2 --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpAlternation.h @@ -0,0 +1,109 @@ +/* + * FormalRegExpAlternation.h + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#ifndef FORMAL_REG_EXP_ALTERNATION_H_ +#define FORMAL_REG_EXP_ALTERNATION_H_ + +#include <vector> +#include "FormalRegExpElement.h" + +namespace regexp { + +/** + * Represents alternation operator in the regular expression. Contains list of FormalRegExpElement + * as operands of the operator. + */ +class FormalRegExpAlternation: public std::element<FormalRegExpAlternation, FormalRegExpElement> { +protected: + /** + * @copydoc FormalRegExpElement::clone() const + */ + virtual FormalRegExpElement* clone() const; + + /** + * @copydoc FormalRegExpElement::plunder() const + */ + virtual FormalRegExpElement* plunder() &&; + + FormalRegExpElement* left; + FormalRegExpElement* right; + + /** + * @copydoc FormalRegExpElement::testSymbol() const + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const; + + /** + * @copydoc FormalRegExpElement::attachRegExp() + */ + virtual bool attachRegExp ( const FormalRegExp * regexp ); + + /** + * @copydoc FormalRegExpElement::computeMinimalAlphabet() + */ + virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; + +public: + explicit FormalRegExpAlternation(FormalRegExpElement&& left, FormalRegExpElement&& right); + explicit FormalRegExpAlternation(const FormalRegExpElement& left, const FormalRegExpElement& right); + + FormalRegExpAlternation(const FormalRegExpAlternation& other); + FormalRegExpAlternation(FormalRegExpAlternation&& other) noexcept; + FormalRegExpAlternation& operator =(const FormalRegExpAlternation& other); + FormalRegExpAlternation& operator =(FormalRegExpAlternation&& other); + virtual ~FormalRegExpAlternation() noexcept; + + /** + * @return elements + */ + const FormalRegExpElement & getLeftElement() const; + const FormalRegExpElement & getRightElement() const; + + /** + * @return elements + */ + FormalRegExpElement & getLeftElement(); + FormalRegExpElement & getRightElement(); + + /** + * @param element to append + */ + void setLeftElement(const FormalRegExpElement& element); + void setLeftElement(FormalRegExpElement&& element); + + /** + * @param element to append + */ + void setRightElement(const FormalRegExpElement& element); + void setRightElement(FormalRegExpElement&& element); + + virtual bool operator<(const FormalRegExpElement&) const; + virtual bool operator==(const FormalRegExpElement&) const; + virtual bool operator>(const FormalRegExpElement&) const; + + virtual bool operator<(const FormalRegExpAlternation&) const; + virtual bool operator==(const FormalRegExpAlternation&) const; + + /** + * @copydoc FormalRegExpElement::operator>>() const + */ + virtual void operator>>(std::ostream& out) const; + + /** + * @copydoc FormalRegExpElement::containsEmptyString() const + */ + virtual bool containsEmptyString() const; + + /** + * @copydoc FormalRegExpElement::isEmpty() const + */ + virtual bool isEmpty() const; +}; + +} /* namespace regexp */ + +#endif /* FORMAL_REG_EXP_ALTERNATION_H_ */ diff --git a/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp b/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0358aaae44d6776e77f219b91ba00fe58ec47630 --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp @@ -0,0 +1,172 @@ +/* + * FormalRegExpConcatenation.cpp + * + * Created on: Nov 27, 2013 + * Author: Martin Zak + */ + +#include "FormalRegExpConcatenation.h" +#include "../../exception/AlibException.h" + +namespace regexp { + +FormalRegExpConcatenation::FormalRegExpConcatenation(FormalRegExpElement&& left, FormalRegExpElement&& right) { + this->left = std::move(left).plunder(); + this->right = std::move(right).plunder(); +} + +FormalRegExpConcatenation::FormalRegExpConcatenation(const FormalRegExpElement& left, const FormalRegExpElement& right) { + this->left = left.clone(); + this->right = right.clone(); +} + +FormalRegExpConcatenation::FormalRegExpConcatenation(const FormalRegExpConcatenation& other) { + this->left = other.left->clone(); + this->right = other.right->clone(); +} + +FormalRegExpConcatenation::FormalRegExpConcatenation(FormalRegExpConcatenation&& other) noexcept : left(std::move(other.left)), right(std::move(other.right)) { + other.left = NULL; + other.right = NULL; + this->attachRegExp(NULL); +} + +FormalRegExpConcatenation& FormalRegExpConcatenation::operator=(const FormalRegExpConcatenation& other) { + if(this == &other) { + return *this; + } + + *this = FormalRegExpConcatenation(other); + + return *this; +} + +FormalRegExpConcatenation& FormalRegExpConcatenation::operator=(FormalRegExpConcatenation&& other) { + std::swap(this->left, other.left); + std::swap(this->right, other.right); + std::swap(this->parentRegExp, other.parentRegExp); //TODO make more clear by not swapping parentRegExp + + this->attachRegExp(other.parentRegExp); + + return *this; +} + +FormalRegExpConcatenation::~FormalRegExpConcatenation() noexcept { + delete left; + delete right; +} + +const FormalRegExpElement & FormalRegExpConcatenation::getLeftElement() const { + return * left; +} + +const FormalRegExpElement & FormalRegExpConcatenation::getRightElement() const { + return * right; +} + +FormalRegExpElement & FormalRegExpConcatenation::getLeftElement() { + return *left; +} + +FormalRegExpElement & FormalRegExpConcatenation::getRightElement() { + return *right; +} + +void FormalRegExpConcatenation::setLeftElement(const FormalRegExpElement& element) { + FormalRegExpElement* elem = element.clone(); + if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + delete left; + this->left = elem; +} + +void FormalRegExpConcatenation::setLeftElement(FormalRegExpElement&& element) { + FormalRegExpElement* elem = std::move(element).plunder(); + if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + delete left; + this->left = elem; +} + +void FormalRegExpConcatenation::setRightElement(const FormalRegExpElement& element) { + FormalRegExpElement* elem = element.clone(); + if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + delete left; + this->right = elem; +} + +void FormalRegExpConcatenation::setRightElement(FormalRegExpElement&& element) { + FormalRegExpElement* elem = std::move(element).plunder(); + if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + delete left; + this->right = elem; +} + +FormalRegExpElement* FormalRegExpConcatenation::clone() const { + return new FormalRegExpConcatenation(*this); +} + +FormalRegExpElement* FormalRegExpConcatenation::plunder() && { + return new FormalRegExpConcatenation(std::move(*this)); +} + +bool FormalRegExpConcatenation::operator<(const FormalRegExpElement& other) const { + return other > *this; +} + +bool FormalRegExpConcatenation::operator==(const FormalRegExpElement& other) const { + return other == *this; +} + +bool FormalRegExpConcatenation::operator>(const FormalRegExpElement& other) const { + return other < *this; +} + + +bool FormalRegExpConcatenation::operator<(const FormalRegExpConcatenation& other) const { + if(this->left == other.left) return this->right < other.right; + return this->left < other.left; +} + +bool FormalRegExpConcatenation::operator==(const FormalRegExpConcatenation& other) const { + return this->left == other.left && this->right == other.right; +} + +void FormalRegExpConcatenation::operator>>(std::ostream& out) const { + out << "(FormalRegExpConcatenation"; + out << " " << *left; + out << " " << *right; + out << ")"; +} + +bool FormalRegExpConcatenation::testSymbol( const alphabet::Symbol & symbol ) const { + if(left->testSymbol(symbol)) return true; + if(right->testSymbol(symbol)) return true; + return false; +} + +bool FormalRegExpConcatenation::attachRegExp(const FormalRegExp * regexp ) { + if(this->parentRegExp == regexp) return true; + + this->parentRegExp = regexp; + if(!left->attachRegExp(regexp)) return false; + if(!right->attachRegExp(regexp)) return false; + return true; +} + +void FormalRegExpConcatenation::computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const { + left->computeMinimalAlphabet(alphabet); + right->computeMinimalAlphabet(alphabet); +} + +bool FormalRegExpConcatenation::containsEmptyString() const { + return left->containsEmptyString() && right->containsEmptyString(); +} + +bool FormalRegExpConcatenation::isEmpty() const { + return left->isEmpty() || right->isEmpty(); +} + +} /* namespace regexp */ diff --git a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h new file mode 100644 index 0000000000000000000000000000000000000000..c47a20a8c8a56752cad31ef8376c749d7778d285 --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h @@ -0,0 +1,103 @@ +/* + * FormalRegExpConcatenation.h + * + * Created on: Nov 27, 2013 + * Author: Martin Zak + */ + +#ifndef FORMAL_REG_EXP_CONCATENATION_H_ +#define FORMAL_REG_EXP_CONCATENATION_H_ + +#include <vector> +#include "FormalRegExpElement.h" + +namespace regexp { + +/** + * Represents concatenation operator in the regular expression. Contains list of FormalRegExpElement + * as operands of the operator. + */ +class FormalRegExpConcatenation: public std::element<FormalRegExpConcatenation, FormalRegExpElement> { +protected: + /** + * @copydoc FormalRegExpElement::clone() const + */ + virtual FormalRegExpElement* clone() const; + + virtual FormalRegExpElement* plunder() &&; + + FormalRegExpElement* left; + FormalRegExpElement* right; + + /** + * @copydoc FormalRegExpElement::testSymbol() const + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const; + + /** + * @copydoc FormalRegExpElement::attachRegExp() + */ + virtual bool attachRegExp ( const FormalRegExp * regexp ); + + /** + * @copydoc FormalRegExpElement::computeMinimalAlphabet() + */ + virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; + +public: + explicit FormalRegExpConcatenation(FormalRegExpElement&& left, FormalRegExpElement&& right); + explicit FormalRegExpConcatenation(const FormalRegExpElement& left, const FormalRegExpElement& right); + + FormalRegExpConcatenation(const FormalRegExpConcatenation& other); + FormalRegExpConcatenation(FormalRegExpConcatenation&& other) noexcept; + FormalRegExpConcatenation& operator =(const FormalRegExpConcatenation& other); + FormalRegExpConcatenation& operator =(FormalRegExpConcatenation&& other); + virtual ~FormalRegExpConcatenation() noexcept; + + /** + * @return elements + */ + const FormalRegExpElement & getLeftElement() const; + const FormalRegExpElement & getRightElement() const; + + /** + * @return elements + */ + FormalRegExpElement& getLeftElement(); + FormalRegExpElement& getRightElement(); + + /** + * @param element to append + */ + void setLeftElement(const FormalRegExpElement& element); + void setLeftElement(FormalRegExpElement&& element); + + void setRightElement(const FormalRegExpElement& element); + void setRightElement(FormalRegExpElement&& element); + + virtual bool operator<(const FormalRegExpElement&) const; + virtual bool operator==(const FormalRegExpElement&) const; + virtual bool operator>(const FormalRegExpElement&) const; + + virtual bool operator<(const FormalRegExpConcatenation&) const; + virtual bool operator==(const FormalRegExpConcatenation&) const; + + /** + * @copydoc FormalRegExpElement::operator>>() const + */ + virtual void operator>>(std::ostream& out) const; + + /** + * @copydoc FormalRegExpElement::containsEmptyString() const + */ + virtual bool containsEmptyString() const; + + /** + * @copydoc FormalRegExpElement::isEmpty() const + */ + virtual bool isEmpty() const; +}; + +} /* namespace regexp */ + +#endif /* FORMAL_REG_EXP_CONCATENATION_H_ */ diff --git a/alib2data/src/regexp/formal/FormalRegExpElement.cpp b/alib2data/src/regexp/formal/FormalRegExpElement.cpp new file mode 100644 index 0000000000000000000000000000000000000000..612bfc591c5977a276809abf86f3aea9a4309f87 --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpElement.cpp @@ -0,0 +1,90 @@ +/* + * FormalRegExpElement.cpp + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#include "FormalRegExpElement.h" +#include <typeinfo> + +#include "FormalRegExpElements.h" + +namespace regexp { + +FormalRegExpElement::FormalRegExpElement() : parentRegExp(NULL) { + +} + +FormalRegExpElement::~FormalRegExpElement() noexcept { + +} + +bool FormalRegExpElement::operator>=(const FormalRegExpElement& other) const { + return !(*this < other); +} + +bool FormalRegExpElement::operator<=(const FormalRegExpElement& other) const { + return !(*this > other); +} + +bool FormalRegExpElement::operator!=(const FormalRegExpElement& other) const { + return !(*this == other); +} + + +bool FormalRegExpElement::operator<(const FormalRegExpConcatenation& other) const { + return typeid(*this).before(typeid(other)); +} + +bool FormalRegExpElement::operator<(const FormalRegExpAlternation& other) const { + return typeid(*this).before(typeid(other)); +} + +bool FormalRegExpElement::operator<(const FormalRegExpIteration& other) const { + return typeid(*this).before(typeid(other)); +} + +bool FormalRegExpElement::operator<(const FormalRegExpSymbol& other) const { + return typeid(*this).before(typeid(other)); +} + +bool FormalRegExpElement::operator<(const FormalRegExpEpsilon& other) const { + return typeid(*this).before(typeid(other)); +} + +bool FormalRegExpElement::operator<(const FormalRegExpEmpty& other) const { + return typeid(*this).before(typeid(other)); +} + + +bool FormalRegExpElement::operator==(const FormalRegExpConcatenation&) const { + return false; +} + +bool FormalRegExpElement::operator==(const FormalRegExpAlternation&) const { + return false; +} + +bool FormalRegExpElement::operator==(const FormalRegExpIteration&) const { + return false; +} + +bool FormalRegExpElement::operator==(const FormalRegExpSymbol&) const { + return false; +} + +bool FormalRegExpElement::operator==(const FormalRegExpEpsilon&) const { + return false; +} + +bool FormalRegExpElement::operator==(const FormalRegExpEmpty&) const { + return false; +} + +std::ostream& operator<<(std::ostream& out, const FormalRegExpElement& regexp) { + regexp >> out; + return out; +} + +} /* namespace regexp */ diff --git a/alib2data/src/regexp/formal/FormalRegExpElement.h b/alib2data/src/regexp/formal/FormalRegExpElement.h new file mode 100644 index 0000000000000000000000000000000000000000..ee6fb0dea1a333c1cc7f1c58bc92283b64fde487 --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpElement.h @@ -0,0 +1,131 @@ +/* + * FormalRegExpElement.h + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#ifndef FORMAL_REG_EXP_ELEMENT_H_ +#define FORMAL_REG_EXP_ELEMENT_H_ + +#include "../../std/visitor.hpp" +#include "../../alphabet/Symbol.h" +#include "FormalRegExp.h" +#include <set> + +namespace regexp { + +class FormalRegExp; + +class FormalRegExpAlternation; +class FormalRegExpConcatenation; +class FormalRegExpIteration; +class FormalRegExpSymbol; +class FormalRegExpEmpty; +class FormalRegExpEpsilon; + +/** + * Abstract class representing element in the regular expression. Can be operator or symbol. + */ +class FormalRegExpElement : public std::elementBase<FormalRegExpAlternation, FormalRegExpConcatenation, FormalRegExpIteration, FormalRegExpSymbol, FormalRegExpEmpty, FormalRegExpEpsilon> { +protected: + /* + * Parent regexp contanining this instance of RegExpElement + */ + const FormalRegExp * parentRegExp; + + /** + * Traverses the regexp tree looking if particular Symbol is used in the regexp. + * + * @param symbol to test if used in regexp element + * @return true if symbol is used by the element and its successor + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const = 0; + + /** + * Attaches the regexp to this instance and all its childs + * @param regexp parent regexp to attach as parent + * @return true if symbols used in regexp element are in the regexp's alphabet + */ + virtual bool attachRegExp ( const FormalRegExp * regexp ) = 0; + + /** + * Traverses the regexp tree computing minimal alphabet needed by regexp + * + * @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>& alphabet ) const = 0; + +public: + FormalRegExpElement(); + + /** + * Creates copy of the element. + * @return copy of the element + */ + virtual FormalRegExpElement* clone() const = 0; + + virtual FormalRegExpElement* plunder() && = 0; + + virtual ~FormalRegExpElement() noexcept; + + // RegExpEmpty < RegExpEpsilon < RegExpSymbol < RegExpIteration < RegExpAlternation < RegExpConcatenation + virtual bool operator<(const FormalRegExpElement&) const = 0; + virtual bool operator==(const FormalRegExpElement&) const = 0; + virtual bool operator>(const FormalRegExpElement&) const = 0; + + virtual bool operator>=(const FormalRegExpElement&) const; + virtual bool operator<=(const FormalRegExpElement&) const; + virtual bool operator!=(const FormalRegExpElement&) const; + + virtual bool operator<(const FormalRegExpConcatenation&) const; + virtual bool operator<(const FormalRegExpAlternation&) const; + virtual bool operator<(const FormalRegExpIteration&) const; + virtual bool operator<(const FormalRegExpSymbol&) const; + virtual bool operator<(const FormalRegExpEpsilon&) const; + virtual bool operator<(const FormalRegExpEmpty&) const; + + virtual bool operator==(const FormalRegExpConcatenation&) const; + virtual bool operator==(const FormalRegExpAlternation&) const; + virtual bool operator==(const FormalRegExpIteration&) const; + virtual bool operator==(const FormalRegExpSymbol&) const; + virtual bool operator==(const FormalRegExpEpsilon&) const; + virtual bool operator==(const FormalRegExpEmpty&) const; + + /** + * Prints XML representation of the RegExp to the output stream. + * @param out output stream to which print the RegExp + */ + virtual void operator>>(std::ostream& out) const = 0; + + /** + * Prints XML representation of the RegExp to the output stream. + * @param out output stream to which print the RegExp + * @param regexp RegExp to print + */ + friend std::ostream& operator<<(std::ostream& out, const FormalRegExpElement& regexp); + + /** + * @return true if this subtree of regexp matches empty string (epsilon) + */ + virtual bool containsEmptyString() const = 0; + + /** + * @return true if this subtree describes empty language + */ + virtual bool isEmpty() const = 0; + + friend class FormalRegExp; + + friend class FormalRegExpAlternation; + friend class FormalRegExpConcatenation; + friend class FormalRegExpIteration; + friend class FromalRegExpSymbol; + friend class FormalRegExpEmpty; + friend class FormalRegExpEpsilon; +}; + +} /* namespace regexp */ + +#endif /* FORMAL_REG_EXP_ELEMENT_H_ */ diff --git a/alib2data/src/regexp/formal/FormalRegExpElements.h b/alib2data/src/regexp/formal/FormalRegExpElements.h new file mode 100644 index 0000000000000000000000000000000000000000..7355a911e5b8b6b60b5ef1784b380d837462083d --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpElements.h @@ -0,0 +1,19 @@ +/* + * FormalRegExpElements.h + * + * Created on: 14. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef FORMAL_REG_EXP_ELEMENTS_H_ +#define FORMAL_REG_EXP_ELEMENTS_H_ + +#include "FormalRegExpAlternation.h" +#include "FormalRegExpConcatenation.h" +#include "FormalRegExpIteration.h" +#include "FormalRegExpElement.h" +#include "FormalRegExpEpsilon.h" +#include "FormalRegExpEmpty.h" +#include "FormalRegExpSymbol.h" + +#endif /* FORMAL_REG_EXP_ELEMENTS_H_ */ diff --git a/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp b/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f9ffa8e78ebba4d198343d42df8f6cf55702f99e --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp @@ -0,0 +1,89 @@ +/* + * FormalRegExpEmpty.cpp + * + * Created on: Jan 30, 2014 + * Author: Jan Travnicek + */ + +#include "FormalRegExpEmpty.h" + +namespace regexp { + +FormalRegExpEmpty::FormalRegExpEmpty() { + // so that default constructor is available +} + +FormalRegExpEmpty::FormalRegExpEmpty(const FormalRegExpEmpty&) { + // so that copy constructor is available +} + +FormalRegExpEmpty::FormalRegExpEmpty(FormalRegExpEmpty&&) noexcept { + this->attachRegExp(NULL); +} + +FormalRegExpEmpty& FormalRegExpEmpty::operator =(const FormalRegExpEmpty&) { + //this is actually different than default implementation + return *this; +} + +FormalRegExpEmpty& FormalRegExpEmpty::operator =(FormalRegExpEmpty&&) noexcept { + //this is actually different than default implementation + return *this; +} + +FormalRegExpElement* FormalRegExpEmpty::clone() const { + return new FormalRegExpEmpty(*this); +} + +FormalRegExpElement* FormalRegExpEmpty::plunder() && { + return new FormalRegExpEmpty(std::move(*this)); +} + +bool FormalRegExpEmpty::operator<(const FormalRegExpElement& other) const { + return other > *this; +} + +bool FormalRegExpEmpty::operator==(const FormalRegExpElement& other) const { + return other == *this; +} + +bool FormalRegExpEmpty::operator>(const FormalRegExpElement& other) const { + return other < *this; +} + + +bool FormalRegExpEmpty::operator<(const FormalRegExpEmpty&) const { + return false; +} + +bool FormalRegExpEmpty::operator==(const FormalRegExpEmpty&) const { + return true; +} + +void FormalRegExpEmpty::operator>>(std::ostream& out) const { + out << "(FormalRegExpEmpty)"; +} + +bool FormalRegExpEmpty::testSymbol( const alphabet::Symbol & ) const { + return false; +} + +bool FormalRegExpEmpty::attachRegExp(const FormalRegExp * regexp ) { + if(this->parentRegExp == regexp) return true; + this->parentRegExp = regexp; + return true; +} + +void FormalRegExpEmpty::computeMinimalAlphabet( std::set<alphabet::Symbol>&) const { + +} + +bool FormalRegExpEmpty::containsEmptyString() const { + return false; +} + +bool FormalRegExpEmpty::isEmpty() const { + return true; +} + +} /* namespace regexp */ diff --git a/alib2data/src/regexp/formal/FormalRegExpEmpty.h b/alib2data/src/regexp/formal/FormalRegExpEmpty.h new file mode 100644 index 0000000000000000000000000000000000000000..a34a9823e1c1f59f6d8216af06e5279a6b34f8f7 --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpEmpty.h @@ -0,0 +1,74 @@ +/* + * FormalRegExpEmpty.h + * + * Created on: Jan 30, 2014 + * Author: Jan Travnicek + */ + +#ifndef FORMAL_REG_EXP_EMPTY_H_ +#define FORMAL_REG_EXP_EMPTY_H_ + +#include "FormalRegExpElement.h" + +namespace regexp { + +/** + * Represents empty regular expression in the regular expression. + */ +class FormalRegExpEmpty: public std::element<FormalRegExpEmpty, FormalRegExpElement> { +protected: + /** + * @copydoc FormalRegExpElement::clone() const + */ + virtual FormalRegExpElement* clone() const; + + virtual FormalRegExpElement* plunder() &&; + + /** + * @copydoc FormalRegExpElement::testSymbol() const + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const; + + /** + * @copydoc FormalRegExpElement::attachRegExp() + */ + virtual bool attachRegExp ( const FormalRegExp * regexp ); + + /** + * @copydoc RegExpElement::computeMinimalAlphabet() + */ + virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; + +public: + FormalRegExpEmpty(); + FormalRegExpEmpty(const FormalRegExpEmpty& other); + FormalRegExpEmpty(FormalRegExpEmpty&& other) noexcept; + FormalRegExpEmpty& operator =(const FormalRegExpEmpty& other); + FormalRegExpEmpty& operator =(FormalRegExpEmpty&& other) noexcept; + + virtual bool operator<(const FormalRegExpElement&) const; + virtual bool operator==(const FormalRegExpElement&) const; + virtual bool operator>(const FormalRegExpElement&) const; + + virtual bool operator<(const FormalRegExpEmpty&) const; + virtual bool operator==(const FormalRegExpEmpty&) const; + + /** + * @copydoc FormalRegExpElement::operator>>() const + */ + virtual void operator>>(std::ostream& out) const; + + /** + * @copydoc FormalRegExpElement::containsEmptyString() const + */ + virtual bool containsEmptyString() const; + + /** + * @copydoc FormalRegExpElement::isEmpty() const + */ + virtual bool isEmpty() const; +}; + +} /* namespace regexp */ + +#endif /* FORMAL_REG_EXP_EMPTY_H_ */ diff --git a/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp b/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dcbabffcb37249d56db61233a80dcf64a8087e86 --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp @@ -0,0 +1,89 @@ +/* + * FormalRegExpEpsilon.cpp + * + * Created on: Jan 30, 2014 + * Author: Jan Travnicek + */ + +#include "FormalRegExpEpsilon.h" + +namespace regexp { + +FormalRegExpEpsilon::FormalRegExpEpsilon() { + // so that default constructor is available +} + +FormalRegExpEpsilon::FormalRegExpEpsilon(const FormalRegExpEpsilon&) { + // so that copy constructor is available +} + +FormalRegExpEpsilon::FormalRegExpEpsilon(FormalRegExpEpsilon&&) noexcept { + this->attachRegExp(NULL); +} + +FormalRegExpEpsilon& FormalRegExpEpsilon::operator =(const FormalRegExpEpsilon&) { + //this is actually different than default implementation + return *this; +} + +FormalRegExpEpsilon& FormalRegExpEpsilon::operator =(FormalRegExpEpsilon&&) noexcept { + //this is actually different than default implementation + return *this; +} + +FormalRegExpElement* FormalRegExpEpsilon::clone() const { + return new FormalRegExpEpsilon(*this); +} + +FormalRegExpElement* FormalRegExpEpsilon::plunder() && { + return new FormalRegExpEpsilon(std::move(*this)); +} + +bool FormalRegExpEpsilon::operator<(const FormalRegExpElement& other) const { + return other > *this; +} + +bool FormalRegExpEpsilon::operator==(const FormalRegExpElement& other) const { + return other == *this; +} + +bool FormalRegExpEpsilon::operator>(const FormalRegExpElement& other) const { + return other < *this; +} + + +bool FormalRegExpEpsilon::operator<(const FormalRegExpEpsilon&) const { + return false; +} + +bool FormalRegExpEpsilon::operator==(const FormalRegExpEpsilon&) const { + return true; +} + +void FormalRegExpEpsilon::operator>>(std::ostream& out) const { + out << "(FormalRegExpEpsilon)"; +} + +bool FormalRegExpEpsilon::testSymbol( const alphabet::Symbol & ) const { + return false; +} + +bool FormalRegExpEpsilon::attachRegExp(const FormalRegExp * regexp ) { + if(this->parentRegExp == regexp) return true; + this->parentRegExp = regexp; + return true; +} + +void FormalRegExpEpsilon::computeMinimalAlphabet( std::set<alphabet::Symbol>&) const { + +} + +bool FormalRegExpEpsilon::containsEmptyString() const { + return true; +} + +bool FormalRegExpEpsilon::isEmpty() const { + return false; +} + +} /* namespace regexp */ diff --git a/alib2data/src/regexp/formal/FormalRegExpEpsilon.h b/alib2data/src/regexp/formal/FormalRegExpEpsilon.h new file mode 100644 index 0000000000000000000000000000000000000000..44b6721496cb2227b30cf3a0f38e2a1390301f3c --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpEpsilon.h @@ -0,0 +1,75 @@ +/* + * FormalRegExpEpsilon.h + * + * Created on: Jan 30, 2014 + * Author: Jan Travnicek + */ + +#ifndef FORMAL_REG_EXP_EPSILON_H_ +#define FORMAL_REG_EXP_EPSILON_H_ + +#include "FormalRegExpElement.h" + +namespace regexp { + +/** + * Represents epsilon in the regular expression. + */ +class FormalRegExpEpsilon: public std::element<FormalRegExpEpsilon, FormalRegExpElement> { +protected: + /** + * @copydoc FormalRegExpElement::clone() const + */ + virtual FormalRegExpElement* clone() const; + + virtual FormalRegExpElement* plunder() &&; + + /** + * @copydoc FormalRegExpElement::testSymbol() const + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const; + + /** + * @copydoc FormalRegExpElement::attachRegExp() + */ + virtual bool attachRegExp ( const FormalRegExp * regexp ); + + /** + * @copydoc FormalRegExpElement::computeMinimalAlphabet() + */ + virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; + +public: + + FormalRegExpEpsilon(); + FormalRegExpEpsilon(const FormalRegExpEpsilon& other); + FormalRegExpEpsilon(FormalRegExpEpsilon&& other) noexcept; + FormalRegExpEpsilon& operator=(const FormalRegExpEpsilon& other); + FormalRegExpEpsilon& operator=(FormalRegExpEpsilon&& other) noexcept; + + virtual bool operator<(const FormalRegExpElement&) const; + virtual bool operator==(const FormalRegExpElement&) const; + virtual bool operator>(const FormalRegExpElement&) const; + + virtual bool operator<(const FormalRegExpEpsilon&) const; + virtual bool operator==(const FormalRegExpEpsilon&) const; + + /** + * @copydoc FormalRegExpElement::operator>>() const + */ + virtual void operator>>(std::ostream& out) const; + + /** + * @copydoc FormalRegExpElement::containsEmptyString() const + */ + virtual bool containsEmptyString() const; + + /** + * @copydoc FormalRegExpElement::isEmpty() const + */ + virtual bool isEmpty() const; +}; + +} /* namespace regexp */ + +#endif /* FORMAL_REG_EXP_EPSILON_H_ */ diff --git a/alib2data/src/regexp/formal/FormalRegExpIteration.cpp b/alib2data/src/regexp/formal/FormalRegExpIteration.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6198410e3d3639f1e17cc0444c3440209d779981 --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpIteration.cpp @@ -0,0 +1,133 @@ +/* + * FormalRegExpIteration.cpp + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#include "FormalRegExpIteration.h" +#include "../../exception/AlibException.h" + +namespace regexp { + +FormalRegExpIteration::FormalRegExpIteration(FormalRegExpElement&& element) : element( NULL ) { + this->setElement(std::move(element)); +} + +FormalRegExpIteration::FormalRegExpIteration(const FormalRegExpElement& element) : element( NULL ) { + this->setElement(element); +} + + +FormalRegExpIteration::FormalRegExpIteration(const FormalRegExpIteration& other) : element(other.element->clone()) { + +} + +FormalRegExpIteration::FormalRegExpIteration(FormalRegExpIteration&& other) noexcept : element(other.element) { + other.element = NULL; + this->attachRegExp(NULL); +} + +FormalRegExpIteration& FormalRegExpIteration::operator=(const FormalRegExpIteration& other) { + if (this == &other) { + return *this; + } + + *this = FormalRegExpIteration(other); + + return *this; +} + +FormalRegExpIteration& FormalRegExpIteration::operator=(FormalRegExpIteration&& other) { + std::swap(this->element, other.element); + std::swap(this->parentRegExp, other.parentRegExp); + + this->attachRegExp(other.parentRegExp); + + return *this; +} + +regexp::FormalRegExpIteration::~FormalRegExpIteration() noexcept { + delete element; +} + +const FormalRegExpElement & FormalRegExpIteration::getElement() const { + return *element; +} + +FormalRegExpElement & FormalRegExpIteration::getElement() { + return *element; +} + +void FormalRegExpIteration::setElement(const FormalRegExpElement& element) { + FormalRegExpElement* elem = element.clone(); + if(this->parentRegExp && !this->element->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + delete this->element; + this->element = elem; +} + +void FormalRegExpIteration::setElement(FormalRegExpElement&& element) { + FormalRegExpElement* elem = std::move(element).plunder(); + if(this->parentRegExp && !this->element->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + delete this->element; + this->element = elem; +} + +FormalRegExpElement* FormalRegExpIteration::clone() const { + return new FormalRegExpIteration(*this); +} + +FormalRegExpElement* FormalRegExpIteration::plunder() && { + return new FormalRegExpIteration(std::move(*this)); +} + +bool FormalRegExpIteration::operator<(const FormalRegExpElement& other) const { + return other > *this; +} + +bool FormalRegExpIteration::operator==(const FormalRegExpElement& other) const { + return other == *this; +} + +bool FormalRegExpIteration::operator>(const FormalRegExpElement& other) const { + return other < *this; +} + +bool FormalRegExpIteration::operator<(const FormalRegExpIteration& other) const { + return *(this->element) < *(other.element); +} + +bool FormalRegExpIteration::operator==(const FormalRegExpIteration& other) const { + return *(this->element) == *(other.element); +} + +void FormalRegExpIteration::operator>>(std::ostream& out) const { + out << "(RegExpFormalRegExpIteration " << *element << ")"; +} + +bool FormalRegExpIteration::testSymbol( const alphabet::Symbol & symbol ) const { + return element->testSymbol( symbol ); +} + +bool FormalRegExpIteration::attachRegExp(const FormalRegExp * regexp ) { + if(this->parentRegExp == regexp) return true; + this->parentRegExp = regexp; + return this->element->attachRegExp(regexp); +} + +void FormalRegExpIteration::computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const { + element->computeMinimalAlphabet(alphabet); +} + +bool FormalRegExpIteration::containsEmptyString() const { + return true; +} + +bool FormalRegExpIteration::isEmpty() const { + return false; +} + +} /* namespace regexp */ + diff --git a/alib2data/src/regexp/formal/FormalRegExpIteration.h b/alib2data/src/regexp/formal/FormalRegExpIteration.h new file mode 100644 index 0000000000000000000000000000000000000000..db404a7ee1a2eba6d3b5101a403993c7b734ae84 --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpIteration.h @@ -0,0 +1,98 @@ +/* + * FormalRegExpIteration.h + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#ifndef FORMAL_REG_EXP_ITERATION_H_ +#define FORMAL_REG_EXP_ITERATION_H_ + +#include "FormalRegExpElement.h" +#include "FormalRegExpEmpty.h" + +namespace regexp { + +/** + * Represents iteration operator in the regular expression. Contains one FormalRegExpElement + * as operand. + */ +class FormalRegExpIteration: public std::element<FormalRegExpIteration, FormalRegExpElement> { +protected: + FormalRegExpElement* element; + + /** + * @copydoc FormalRegExpElement::clone() const + */ + virtual FormalRegExpElement* clone() const; + + virtual FormalRegExpElement* plunder() &&; + + /** + * @copydoc FormalRegExpElement::testSymbol() const + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const; + + /** + * @copydoc FormalRegExpElement::attachRegExp() + */ + virtual bool attachRegExp ( const FormalRegExp * regexp ); + + /** + * @copydoc FormalRegExpElement::computeMinimalAlphabet() + */ + virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; + +public: + explicit FormalRegExpIteration(FormalRegExpElement&&); + explicit FormalRegExpIteration(const FormalRegExpElement&); + + FormalRegExpIteration(const FormalRegExpIteration& other); + FormalRegExpIteration(FormalRegExpIteration&& other) noexcept; + FormalRegExpIteration& operator =(const FormalRegExpIteration& other); + FormalRegExpIteration& operator =(FormalRegExpIteration&& other); + virtual ~FormalRegExpIteration() noexcept; + + /** + * @return element + */ + const FormalRegExpElement & getElement() const; + + /** + * @return element + */ + FormalRegExpElement & getElement(); + + /** + * @param element to iterate + */ + void setElement(const FormalRegExpElement& element); + + void setElement(FormalRegExpElement&& element); + + virtual bool operator<(const FormalRegExpElement&) const; + virtual bool operator==(const FormalRegExpElement&) const; + virtual bool operator>(const FormalRegExpElement&) const; + + virtual bool operator<(const FormalRegExpIteration&) const; + virtual bool operator==(const FormalRegExpIteration&) const; + + /** + * @copydoc FormalRegExpElement::operator>>() const + */ + virtual void operator>>(std::ostream& out) const; + + /** + * @copydoc FormalRegExpElement::containsEmptyString() const + */ + virtual bool containsEmptyString() const; + + /** + * @copydoc FormalRegExpElement::isEmpty() const + */ + virtual bool isEmpty() const; +}; + +} /* namespace regexp */ + +#endif /* FORMAL_REG_EXP_ITERATION_H_ */ diff --git a/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp b/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7885ca4e733196fb50aaedff5e563a1b063e529d --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp @@ -0,0 +1,116 @@ +/* + * FormalRegExpSymbol.cpp + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#include "FormalRegExpSymbol.h" + +namespace regexp { + +FormalRegExpSymbol::FormalRegExpSymbol(const FormalRegExpSymbol& other) : symbol(other.symbol) { + +} + +FormalRegExpSymbol::FormalRegExpSymbol(FormalRegExpSymbol&& other) noexcept : symbol(std::move(other.symbol)) { + this->attachRegExp(NULL); +} + +FormalRegExpSymbol& FormalRegExpSymbol::operator=(const FormalRegExpSymbol& other) { + if (this == &other) { + return *this; + } + + *this = FormalRegExpSymbol(other); + + return *this; +} + +FormalRegExpSymbol& FormalRegExpSymbol::operator=(FormalRegExpSymbol&& other) { + std::swap(this->symbol, other.symbol); + std::swap(this->parentRegExp, other.parentRegExp); + + this->attachRegExp(other.parentRegExp); + + return *this; +} + +FormalRegExpSymbol::FormalRegExpSymbol(const alphabet::Symbol& symbol) : + symbol(symbol) { +} + +FormalRegExpSymbol::FormalRegExpSymbol(alphabet::Symbol&& symbol) : + symbol(std::move(symbol)) { +} + +FormalRegExpElement* FormalRegExpSymbol::clone() const { + return new FormalRegExpSymbol(*this); +} + +FormalRegExpElement* FormalRegExpSymbol::plunder() && { + return new FormalRegExpSymbol(std::move(*this)); +} + +bool FormalRegExpSymbol::operator==(const alphabet::Symbol& other) const { + return this->symbol == other; +} + +bool operator==(const alphabet::Symbol& first, const FormalRegExpSymbol& second) { + return first == second.symbol; +} + +bool FormalRegExpSymbol::operator<(const FormalRegExpElement& other) const { + return other > *this; +} + +bool FormalRegExpSymbol::operator==(const FormalRegExpElement& other) const { + return other == *this; +} + +bool FormalRegExpSymbol::operator>(const FormalRegExpElement& other) const { + return other < *this; +} + + +bool FormalRegExpSymbol::operator<(const FormalRegExpSymbol& other) const { + return symbol < other.symbol; +} + +bool FormalRegExpSymbol::operator==(const FormalRegExpSymbol& other) const { + return symbol == other.symbol; +} + +void FormalRegExpSymbol::operator>>(std::ostream& out) const { + out << "(FormalRegExpSymbol " << symbol << ")"; +} + +bool FormalRegExpSymbol::containsEmptyString() const { + return false; +} + +bool FormalRegExpSymbol::isEmpty() const { + return false; +} + +bool FormalRegExpSymbol::testSymbol( const alphabet::Symbol & symbol ) const { + return symbol == this->symbol; +} + +bool FormalRegExpSymbol::attachRegExp(const FormalRegExp * regexp ) { + if(this->parentRegExp == regexp) return true; + this->parentRegExp = regexp; + if(regexp == NULL) return true; + return this->parentRegExp->getAlphabet().find(this->symbol) != this->parentRegExp->getAlphabet().end(); +} + +void FormalRegExpSymbol::computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const { + alphabet.insert(this->symbol); +} + +const alphabet::Symbol& FormalRegExpSymbol::getSymbol() const { + return this->symbol; +} + +} /* namespace regexp */ + diff --git a/alib2data/src/regexp/formal/FormalRegExpSymbol.h b/alib2data/src/regexp/formal/FormalRegExpSymbol.h new file mode 100644 index 0000000000000000000000000000000000000000..3edb3aed80c5f062dbce9e978d8a9d5e8da51a94 --- /dev/null +++ b/alib2data/src/regexp/formal/FormalRegExpSymbol.h @@ -0,0 +1,88 @@ +/* + * FormalRegExpSymbol.h + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#ifndef FORMAL_REG_EXP_SYMBOL_H_ +#define FORMAL_REG_EXP_SYMBOL_H_ + +#include "../../label/Label.h" +#include "FormalRegExpElement.h" +#include "../../alphabet/LabeledSymbol.h" + +namespace regexp { + +/** + * Represents symbol in the regular expression. Contains name of the symbol. + */ +class FormalRegExpSymbol : public std::element<FormalRegExpSymbol, FormalRegExpElement> { +protected: + alphabet::Symbol symbol; + + /** + * @copydoc FormalRegExpElement::clone() const + */ + virtual FormalRegExpElement* clone() const; + + virtual FormalRegExpElement* plunder() &&; + + /** + * @copydoc FormalRegExpElement::testSymbol() const + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const; + + /** + * @copydoc FormalRegExpElement::attachRegExp() + */ + virtual bool attachRegExp ( const FormalRegExp * regexp ); + + /** + * @copydoc FormalRegExpElement::computeMinimalAlphabet() + */ + virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; +public: + explicit FormalRegExpSymbol(const alphabet::Symbol& symbol); + explicit FormalRegExpSymbol(alphabet::Symbol&& symbol); + + FormalRegExpSymbol(const FormalRegExpSymbol& other); + FormalRegExpSymbol(FormalRegExpSymbol&& other) noexcept; + FormalRegExpSymbol& operator=(const FormalRegExpSymbol& other); + FormalRegExpSymbol& operator=(FormalRegExpSymbol&& other); + + bool operator==(const alphabet::Symbol&) const; + friend bool operator==(const alphabet::Symbol&, const FormalRegExpSymbol&); + + virtual bool operator<(const FormalRegExpElement&) const; + virtual bool operator==(const FormalRegExpElement&) const; + virtual bool operator>(const FormalRegExpElement&) const; + + virtual bool operator<(const FormalRegExpSymbol&) const; + virtual bool operator==(const FormalRegExpSymbol&) const; + + /** + * @copydoc FormalRegExpElement::operator>>() const + */ + virtual void operator>>(std::ostream& out) const; + + /** + * @copydoc FormalRegExpElement::containsEmptyString() const + */ + virtual bool containsEmptyString() const; + + /** + * Returns the string representation of RegExp Symbol. + */ + const alphabet::Symbol& getSymbol() const; + + /** + * @copydoc FormalRegExpElement::isEmpty() const + */ + virtual bool isEmpty() const; +}; + +} /* namespace regexp */ + +#endif /* FORMAL_REG_EXP_SYMBOL_H_ */ + diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExp.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a630d8898053aa75af042d87d575f6fa785092c3 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExp.cpp @@ -0,0 +1,186 @@ +/* + * UnboundedRegExp.cpp + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#include "UnboundedRegExp.h" +#include "../../exception/AlibException.h" +#include "UnboundedRegExpEmpty.h" +#include "UnboundedRegExpSymbol.h" + +#include <iostream> +#include <algorithm> +#include <sstream> + +#include "../../std/set.hpp" +#include "../formal/FormalRegExp.h" + +namespace regexp { + +UnboundedRegExp::UnboundedRegExp() { + this->regExp = new UnboundedRegExpEmpty(); +} + +UnboundedRegExp::UnboundedRegExp(const std::set<alphabet::Symbol>& alphabet, const UnboundedRegExpElement& regExp) : alphabet(alphabet) { + this->regExp = NULL; + setRegExp(regExp); +} + +UnboundedRegExp::UnboundedRegExp(std::set<alphabet::Symbol>&& alphabet, UnboundedRegExpElement&& regExp) : alphabet(std::move(alphabet)) { + this->regExp = NULL; + setRegExp(std::move(regExp)); +} + +UnboundedRegExp::UnboundedRegExp(const UnboundedRegExpElement& regExp) { + regExp.computeMinimalAlphabet(alphabet); + this->regExp = NULL; + setRegExp(regExp); +} + +UnboundedRegExp::UnboundedRegExp(UnboundedRegExpElement&& regExp) { + regExp.computeMinimalAlphabet(alphabet); + this->regExp = NULL; + setRegExp(std::move(regExp)); +} + +UnboundedRegExp::UnboundedRegExp(const UnboundedRegExp& other) : regExp(other.regExp->clone()), alphabet(other.alphabet) { + this->regExp->attachRegExp(this); +} + +UnboundedRegExp::UnboundedRegExp(UnboundedRegExp&& other) noexcept : regExp(other.regExp), alphabet(std::move(other.alphabet) ) { + this->regExp->attachRegExp(this); + other.regExp = NULL; +} + +RegExpBase* UnboundedRegExp::clone() const { + return new UnboundedRegExp(*this); +} + +RegExpBase* UnboundedRegExp::plunder() && { + return new UnboundedRegExp(std::move(*this)); +} + +UnboundedRegExp& UnboundedRegExp::operator=(const UnboundedRegExp& other) { + if (this == &other) { + return *this; + } + + *this = UnboundedRegExp(other); + + return *this; +} + +UnboundedRegExp& UnboundedRegExp::operator=(UnboundedRegExp&& other) noexcept { + std::swap(this->regExp, other.regExp); + std::swap(this->alphabet, other.alphabet); + return *this; +} + +UnboundedRegExp::~UnboundedRegExp() noexcept { + delete regExp; +} + +const UnboundedRegExpElement& UnboundedRegExp::getRegExp() const { + return *regExp; +} + +UnboundedRegExpElement& UnboundedRegExp::getRegExp() { + return *regExp; +} + +void UnboundedRegExp::setRegExp(const UnboundedRegExpElement& regExp) { + delete this->regExp; + this->regExp = regExp.clone(); + if(!this->regExp->attachRegExp(this)) + throw exception::AlibException("Input symbols not in the alphabet."); +} + +void UnboundedRegExp::setRegExp(UnboundedRegExpElement&& regExp) { + delete this->regExp; + this->regExp = std::move(regExp).plunder(); + if(!this->regExp->attachRegExp(this)) + throw exception::AlibException("Input symbols not in the alphabet."); +} + +const std::set<alphabet::Symbol>& UnboundedRegExp::getAlphabet() const { + return alphabet; +} + +bool UnboundedRegExp::addSymbolToAlphabet(const alphabet::Symbol & symbol) { + return alphabet.insert(symbol).second; +} + +void UnboundedRegExp::setAlphabet(const std::set<alphabet::Symbol> & symbols) { + std::set<alphabet::Symbol> minimalAlphabet; + this->regExp->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 UnboundedRegExp::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) { + if(this->regExp->testSymbol(symbol)) + throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is used."); + + return alphabet.erase(symbol); +} + +bool UnboundedRegExp::isEmpty() const { + return regExp->isEmpty(); +} + +bool UnboundedRegExp::containsEmptyString() const { + return regExp->containsEmptyString(); +} + +void UnboundedRegExp::operator >>(std::ostream& out) const { + out << "(UnboundedRegExp " << *(this->regExp) << ")"; +} + +bool UnboundedRegExp::operator<(const FormalRegExp& other) const { + return typeid(*this).before(typeid(other)); +} + +bool UnboundedRegExp::operator<(const UnboundedRegExp& other) const { + if(*(this->regExp) < *(other.regExp)) { + return true; + } else if(*(this->regExp) > *(other.regExp)) { + return false; + } else { + return this->alphabet < other.alphabet; + } +} + +bool UnboundedRegExp::operator==(const FormalRegExp&) const { + return false; +} + +bool UnboundedRegExp::operator==(const UnboundedRegExp& other) const { + return *(this->regExp) == *(other.regExp) && this->alphabet == other.alphabet; +} + +bool UnboundedRegExp::operator<(const RegExpBase& other) const { + return other > *this; +} + +bool UnboundedRegExp::operator ==(const RegExpBase& other) const { + return other == *this; +} + +bool UnboundedRegExp::operator >(const RegExpBase& other) const { + return other < *this; +} + +UnboundedRegExp::operator std::string () const { + std::stringstream ss; + ss << *this; + return ss.str(); +} + +} /* namespace regexp */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExp.h b/alib2data/src/regexp/unbounded/UnboundedRegExp.h new file mode 100644 index 0000000000000000000000000000000000000000..d72db72cdb7cff9ca8db4dbc94da5accc04927e8 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExp.h @@ -0,0 +1,140 @@ +/* + * UnboundedRegExp.h + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#ifndef UNBOUNDED_REG_EXP_H_ +#define UNBOUNDED_REG_EXP_H_ + +#include <vector> +#include <list> +#include <string> +#include <set> +#include "UnboundedRegExpElement.h" +#include "../../std/visitor.hpp" +#include "../RegExpBase.h" + +namespace regexp { + +class UnboundedRegExpElement; + +/** + * Represents regular expression parsed from the XML. Regular expression is stored + * as a tree of RegExpElement. + */ +class UnboundedRegExp : public std::element<UnboundedRegExp, RegExpBase> { +protected: + UnboundedRegExpElement* regExp; + + std::set<alphabet::Symbol> alphabet; + + /** + * @copydoc UnboundedRegExpElement::clone() const + */ + virtual RegExpBase* clone() const; + + /** + * @copydoc UnboundedRegExpElement::plunder() const + */ + virtual RegExpBase* plunder() &&; + +public: + UnboundedRegExp(); + UnboundedRegExp(const std::set<alphabet::Symbol>& alphabet, const UnboundedRegExpElement& regExp); + UnboundedRegExp(std::set<alphabet::Symbol>&& alphabet, UnboundedRegExpElement&& regExp); + explicit UnboundedRegExp(const UnboundedRegExpElement& regExp); + explicit UnboundedRegExp(UnboundedRegExpElement&& regExp); + + /** + * Copy constructor. + * @param other RegExp to copy + */ + UnboundedRegExp(const UnboundedRegExp& other); + UnboundedRegExp(UnboundedRegExp&& other) noexcept; + UnboundedRegExp& operator =(const UnboundedRegExp& other); + UnboundedRegExp& operator =(UnboundedRegExp&& other) noexcept; + ~UnboundedRegExp() noexcept; + + /** + * @return Root node of the regular expression tree + */ + const UnboundedRegExpElement& getRegExp() const; + + /** + * @return Root node of the regular expression tree + */ + UnboundedRegExpElement& getRegExp(); + + /** + * Sets the root node of the regular expression tree. Doesn't perform copy of the regExp param, + * just stores it! + * @param regExp root node to set + */ + void setRegExp(const UnboundedRegExpElement& regExp); + + /** + * Sets the root node of the regular expression tree + * @param regExp root node to set + */ + void setRegExp(UnboundedRegExpElement&& regExp); + + /** + * Gets alphabet symbols used in RegExp. + * @return set of alphabet symbols used in regexp. + */ + const std::set<alphabet::Symbol>& getAlphabet() const; + + /** + * Adds symbol to the alphabet available in the regular expression + * @param symbol new symbol added to the alphabet + */ + bool addSymbolToAlphabet(const alphabet::Symbol & symbol); + + /** + * Sets the alphabet of the regular expression + * @param symbols new alphabet + */ + void setAlphabet(const std::set<alphabet::Symbol>& symbols); + + /** + * Removes symbol from the alphabet of symbol available in the regular expression + * @param symbol removed symbol from the alphabet + */ + bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol); + + /** + * @return true if regexp represents empty language + */ + bool isEmpty() const; + + /** + * @return true if regexp matches empty string (epsilon) + */ + bool containsEmptyString() const; + + /** + * Prints XML representation of the RegExp to the output stream. + * @param out output stream to which print the RegExp + * @param regexp RegExp to print + */ + virtual void operator>>(std::ostream& out) const; + + virtual bool operator <(const RegExpBase& other) const; + virtual bool operator ==(const RegExpBase& other) const; + virtual bool operator >(const RegExpBase& other) const; + + virtual bool operator==(const FormalRegExp&) const; + virtual bool operator==(const UnboundedRegExp& other) const; + + virtual bool operator<(const FormalRegExp& other) const; + virtual bool operator<(const UnboundedRegExp& other) const; + + virtual operator std::string() const; + +}; + +} /* namespace regexp */ + +#endif /* UNBOUNDED_REG_EXP_H_ */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b9690ed284a761d84dfb1d48bd625e1f84033ab9 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp @@ -0,0 +1,169 @@ +/* + * UnboundedRegExpAlternation.cpp + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#include "UnboundedRegExpAlternation.h" +#include "../../exception/AlibException.h" + +namespace regexp { + +UnboundedRegExpAlternation::UnboundedRegExpAlternation() { + +} + +UnboundedRegExpAlternation::UnboundedRegExpAlternation(const UnboundedRegExpAlternation& other) { + for (const auto& element : other.elements) { + elements.push_back(element->clone()); + } +} + +UnboundedRegExpAlternation::UnboundedRegExpAlternation(UnboundedRegExpAlternation&& other) noexcept : elements(std::move(other.elements)) { + other.elements.clear(); + this->attachRegExp(NULL); +} + +UnboundedRegExpAlternation& UnboundedRegExpAlternation::operator=(const UnboundedRegExpAlternation& other) { + if (this == &other) { + return *this; + } + + *this = UnboundedRegExpAlternation(other); + + return *this; +} + +UnboundedRegExpAlternation& UnboundedRegExpAlternation::operator=(UnboundedRegExpAlternation&& other) { + std::swap(this->elements, other.elements); + std::swap(this->parentRegExp, other.parentRegExp); + + this->attachRegExp(other.parentRegExp); + + return *this; +} + +UnboundedRegExpAlternation::~UnboundedRegExpAlternation() noexcept { + for (auto element : elements) { + delete element; + } + elements.clear(); +} + +const std::vector<const UnboundedRegExpElement*> & UnboundedRegExpAlternation::getElements() const { + return * reinterpret_cast<const std::vector<const UnboundedRegExpElement*> * > (&elements); +} + +const std::vector<UnboundedRegExpElement*> & UnboundedRegExpAlternation::getElements() { + return elements; +} + +void UnboundedRegExpAlternation::appendElement(const UnboundedRegExpElement& element) { + UnboundedRegExpElement* elem = element.clone(); + if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + this->elements.push_back(elem); +} + +void UnboundedRegExpAlternation::appendElement(UnboundedRegExpElement&& element) { + UnboundedRegExpElement* elem = std::move(element).plunder(); + if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + this->elements.push_back(elem); +} + +UnboundedRegExpElement* UnboundedRegExpAlternation::clone() const { + return new UnboundedRegExpAlternation(*this); +} + +UnboundedRegExpElement* UnboundedRegExpAlternation::plunder() && { + return new UnboundedRegExpAlternation(std::move(*this)); +} + +bool UnboundedRegExpAlternation::operator<(const UnboundedRegExpElement& other) const { + return other > *this; +} + +bool UnboundedRegExpAlternation::operator==(const UnboundedRegExpElement& other) const { + return other == *this; +} + +bool UnboundedRegExpAlternation::operator>(const UnboundedRegExpElement& other) const { + return other < *this; +} + + +bool UnboundedRegExpAlternation::operator<(const UnboundedRegExpAlternation& other) const { + int thisSize = this->elements.size(); + int otherSize = other.elements.size(); + if(thisSize < otherSize) return true; + if(thisSize > otherSize) return false; + + auto thisIter = this->elements.begin(); + auto otherIter = other.elements.begin(); + for(; thisIter != this->elements.end(); thisIter++, otherIter++) { + if(**thisIter != **otherIter) break; + } + if(thisIter == this->elements.end()) return false; + + return **thisIter < **otherIter; +} + +bool UnboundedRegExpAlternation::operator==(const UnboundedRegExpAlternation& other) const { + if(this->elements.size() != other.elements.size()) return false; + + auto thisIter = this->elements.begin(); + auto otherIter = other.elements.begin(); + for(; thisIter != this->elements.end(); thisIter++, otherIter++) { + if(**thisIter != **otherIter) return false; + } + + return true; +} + +void UnboundedRegExpAlternation::operator>>(std::ostream& out) const { + out << "(UnboundedRegExpAlternation"; + for(const auto& e : elements) + out << " " << *e; + + out << ")"; +} + +bool UnboundedRegExpAlternation::testSymbol( const alphabet::Symbol & symbol ) const { + for(const auto& child : this->elements) + if(child->testSymbol(symbol)) return true; + return false; +} + +bool UnboundedRegExpAlternation::attachRegExp(const UnboundedRegExp * regexp ) { + if(this->parentRegExp == regexp) return true; + + this->parentRegExp = regexp; + for(const auto& child : this->elements) + if(!child->attachRegExp(regexp)) return false; + return true; +} + +void UnboundedRegExpAlternation::computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const { + for(const auto& child : this->elements) + child->computeMinimalAlphabet(alphabet); +} + +bool UnboundedRegExpAlternation::containsEmptyString() const { + for(const auto& e : elements) + if(e->containsEmptyString()) + return true; + + return false; // alternation of zero regexps is empty so by default it doesn't contain epsilon +} + +bool UnboundedRegExpAlternation::isEmpty() const { + for(const auto& e : elements) + if(!e->isEmpty()) + return false; + + return true; // alternation of zero regexps is empty +} + +} /* namespace regexp */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h new file mode 100644 index 0000000000000000000000000000000000000000..1e51660957e0c58cb6768cb9ae7dbf6b2602c60b --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h @@ -0,0 +1,103 @@ +/* + * UnboundedRegExpAlternation.h + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#ifndef UNBOUNDED_REG_EXP_ALTERNATION_H_ +#define UNBOUNDED_REG_EXP_ALTERNATION_H_ + +#include <vector> +#include "UnboundedRegExpElement.h" + +namespace regexp { + +/** + * Represents alternation operator in the regular expression. Contains list of UnboundedRegExpElement + * as operands of the operator. + */ +class UnboundedRegExpAlternation: public std::element<UnboundedRegExpAlternation, UnboundedRegExpElement> { +protected: + /** + * @copydoc UnboundedRegExpElement::clone() const + */ + virtual UnboundedRegExpElement* clone() const; + + /** + * @copydoc UnboundedRegExpElement::plunder() const + */ + virtual UnboundedRegExpElement* plunder() &&; + + std::vector<UnboundedRegExpElement*> elements; + + /** + * @copydoc UnboundedRegExpElement::testSymbol() const + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const; + + /** + * @copydoc UnboundedRegExpElement::attachRegExp() + */ + virtual bool attachRegExp ( const UnboundedRegExp * regexp ); + + /** + * @copydoc UnboundedRegExpElement::computeMinimalAlphabet() + */ + virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; + +public: + UnboundedRegExpAlternation(); + + UnboundedRegExpAlternation(const UnboundedRegExpAlternation& other); + UnboundedRegExpAlternation(UnboundedRegExpAlternation&& other) noexcept; + UnboundedRegExpAlternation& operator =(const UnboundedRegExpAlternation& other); + UnboundedRegExpAlternation& operator =(UnboundedRegExpAlternation&& other); + virtual ~UnboundedRegExpAlternation() noexcept; + + /** + * @return elements + */ + const std::vector<const UnboundedRegExpElement*> & getElements() const; + + /** + * @return elements + */ + const std::vector<UnboundedRegExpElement*> & getElements(); + + /** + * @param element to append + */ + void appendElement(const UnboundedRegExpElement& element); + + /** + * @param element to append + */ + void appendElement(UnboundedRegExpElement&& element); + + virtual bool operator<(const UnboundedRegExpElement&) const; + virtual bool operator==(const UnboundedRegExpElement&) const; + virtual bool operator>(const UnboundedRegExpElement&) const; + + virtual bool operator<(const UnboundedRegExpAlternation&) const; + virtual bool operator==(const UnboundedRegExpAlternation&) const; + + /** + * @copydoc UnboundedRegExpElement::operator>>() const + */ + virtual void operator>>(std::ostream& out) const; + + /** + * @copydoc UnboundedRegExpElement::containsEmptyString() const + */ + virtual bool containsEmptyString() const; + + /** + * @copydoc UnboundedRegExpElement::isEmpty() const + */ + virtual bool isEmpty() const; +}; + +} /* namespace regexp */ + +#endif /* UNBOUNDED_REG_EXP_ALTERNATION_H_ */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b166013bc6d904bcbd351c4d0ca2569343410c87 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp @@ -0,0 +1,168 @@ +/* + * UnboundedRegExpConcatenation.cpp + * + * Created on: Nov 27, 2013 + * Author: Martin Zak + */ + +#include "UnboundedRegExpConcatenation.h" +#include "../../exception/AlibException.h" + +namespace regexp { + +UnboundedRegExpConcatenation::UnboundedRegExpConcatenation() { +} + +UnboundedRegExpConcatenation::UnboundedRegExpConcatenation(const UnboundedRegExpConcatenation& other) { + for (auto element : other.elements) { + elements.push_back(element->clone()); + } +} + +UnboundedRegExpConcatenation::UnboundedRegExpConcatenation(UnboundedRegExpConcatenation&& other) noexcept : elements(std::move(other.elements)) { + other.elements.clear(); + this->attachRegExp(NULL); +} + +UnboundedRegExpConcatenation& UnboundedRegExpConcatenation::operator=(const UnboundedRegExpConcatenation& other) { + if(this == &other) { + return *this; + } + + *this = UnboundedRegExpConcatenation(other); + + return *this; +} + +UnboundedRegExpConcatenation& UnboundedRegExpConcatenation::operator=(UnboundedRegExpConcatenation&& other) { + std::swap(this->elements, other.elements); + std::swap(this->parentRegExp, other.parentRegExp); + + this->attachRegExp(other.parentRegExp); + + return *this; +} + +UnboundedRegExpConcatenation::~UnboundedRegExpConcatenation() noexcept { + for (auto element : elements) { + delete element; + } + elements.clear(); +} + +const std::vector<const UnboundedRegExpElement*> & UnboundedRegExpConcatenation::getElements() const { + return * reinterpret_cast<const std::vector<const UnboundedRegExpElement*> * > (&elements); +} + +const std::vector<UnboundedRegExpElement*> & UnboundedRegExpConcatenation::getElements() { + return elements; +} + +void UnboundedRegExpConcatenation::appendElement(const UnboundedRegExpElement& element) { + UnboundedRegExpElement* elem = element.clone(); + if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + this->elements.push_back(elem); +} + +void UnboundedRegExpConcatenation::appendElement(UnboundedRegExpElement&& element) { + UnboundedRegExpElement* elem = std::move(element).plunder(); + if(this->parentRegExp && !elem->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + this->elements.push_back(elem); +} + +UnboundedRegExpElement* UnboundedRegExpConcatenation::clone() const { + return new UnboundedRegExpConcatenation(*this); +} + +UnboundedRegExpElement* UnboundedRegExpConcatenation::plunder() && { + return new UnboundedRegExpConcatenation(std::move(*this)); +} + +bool UnboundedRegExpConcatenation::operator<(const UnboundedRegExpElement& other) const { + return other > *this; +} + +bool UnboundedRegExpConcatenation::operator==(const UnboundedRegExpElement& other) const { + return other == *this; +} + +bool UnboundedRegExpConcatenation::operator>(const UnboundedRegExpElement& other) const { + return other < *this; +} + + +bool UnboundedRegExpConcatenation::operator<(const UnboundedRegExpConcatenation& other) const { + int thisSize = this->elements.size(); + int otherSize = other.elements.size(); + if(thisSize < otherSize) return true; + if(thisSize > otherSize) return false; + + auto thisIter = this->elements.begin(); + auto otherIter = other.elements.begin(); + for(; thisIter != this->elements.end(); thisIter++, otherIter++) { + if(**thisIter != **otherIter) break; + } + if(thisIter == this->elements.end()) return false; + + return **thisIter < **otherIter; +} + +bool UnboundedRegExpConcatenation::operator==(const UnboundedRegExpConcatenation& other) const { + if(this->elements.size() != other.elements.size()) return false; + + auto thisIter = this->elements.begin(); + auto otherIter = other.elements.begin(); + for(; thisIter != this->elements.end(); thisIter++, otherIter++) { + if(**thisIter != **otherIter) return false; + } + + return true; +} + +void UnboundedRegExpConcatenation::operator>>(std::ostream& out) const { + out << "(UnboundedRegExpConcatenation"; + for(const auto& e : elements) + out << " " << *e; + + out << ")"; +} + +bool UnboundedRegExpConcatenation::testSymbol( const alphabet::Symbol & symbol ) const { + for(const auto& child : this->elements) + if(child->testSymbol(symbol)) return true; + return false; +} + +bool UnboundedRegExpConcatenation::attachRegExp(const UnboundedRegExp * regexp ) { + if(this->parentRegExp == regexp) return true; + + this->parentRegExp = regexp; + for(const auto& child : this->elements) + if(!child->attachRegExp(regexp)) return false; + return true; +} + +void UnboundedRegExpConcatenation::computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const { + for(const auto& child : this->elements) + child->computeMinimalAlphabet(alphabet); +} + +bool UnboundedRegExpConcatenation::containsEmptyString() const { + for(const auto& e : elements) + if( ! e->containsEmptyString()) + return false; + + return true; // concatenation of zero regexps is epsilon so by default it does contain epsilon +} + +bool UnboundedRegExpConcatenation::isEmpty() const { + for(const auto& e : elements) + if(e->isEmpty()) + return true; + + return false; // concatenation of zero regexps is epsilon +} + +} /* namespace regexp */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h new file mode 100644 index 0000000000000000000000000000000000000000..bf318442565b27afb5243c0034e9fa260f364f97 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h @@ -0,0 +1,97 @@ +/* + * UnboundedRegExpConcatenation.h + * + * Created on: Nov 27, 2013 + * Author: Martin Zak + */ + +#ifndef UNBOUNDED_REG_EXP_CONCATENATION_H_ +#define UNBOUNDED_REG_EXP_CONCATENATION_H_ + +#include <vector> +#include "UnboundedRegExpElement.h" + +namespace regexp { + +/** + * Represents concatenation operator in the regular expression. Contains list of UnboundedRegExpElement + * as operands of the operator. + */ +class UnboundedRegExpConcatenation: public std::element<UnboundedRegExpConcatenation, UnboundedRegExpElement> { +protected: + /** + * @copydoc UnboundedRegExpElement::clone() const + */ + virtual UnboundedRegExpElement* clone() const; + + virtual UnboundedRegExpElement* plunder() &&; + + std::vector<UnboundedRegExpElement*> elements; + + /** + * @copydoc UnboundedRegExpElement::testSymbol() const + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const; + + /** + * @copydoc UnboundedRegExpElement::attachRegExp() + */ + virtual bool attachRegExp ( const UnboundedRegExp * regexp ); + + /** + * @copydoc UnboundedRegExpElement::computeMinimalAlphabet() + */ + virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; + +public: + UnboundedRegExpConcatenation(); + + UnboundedRegExpConcatenation(const UnboundedRegExpConcatenation& other); + UnboundedRegExpConcatenation(UnboundedRegExpConcatenation&& other) noexcept; + UnboundedRegExpConcatenation& operator =(const UnboundedRegExpConcatenation& other); + UnboundedRegExpConcatenation& operator =(UnboundedRegExpConcatenation&& other); + virtual ~UnboundedRegExpConcatenation() noexcept; + + /** + * @return elements + */ + const std::vector<const UnboundedRegExpElement*> & getElements() const; + + /** + * @return elements + */ + const std::vector<UnboundedRegExpElement*> & getElements(); + + /** + * @param element to append + */ + void appendElement(const UnboundedRegExpElement& element); + + void appendElement(UnboundedRegExpElement&& element); + + virtual bool operator<(const UnboundedRegExpElement&) const; + virtual bool operator==(const UnboundedRegExpElement&) const; + virtual bool operator>(const UnboundedRegExpElement&) const; + + virtual bool operator<(const UnboundedRegExpConcatenation&) const; + virtual bool operator==(const UnboundedRegExpConcatenation&) const; + + /** + * @copydoc UnboundedRegExpElement::operator>>() const + */ + virtual void operator>>(std::ostream& out) const; + + /** + * @copydoc UnboundedRegExpElement::containsEmptyString() const + */ + virtual bool containsEmptyString() const; + + /** + * @copydoc UnboundedRegExpElement::isEmpty() const + */ + virtual bool isEmpty() const; +}; + +} /* namespace regexp */ + +#endif /* UNBOUNDED_REG_EXP_CONCATENATION_H_ */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.cpp new file mode 100644 index 0000000000000000000000000000000000000000..499e4cb734a3e8a9276e3dc3a7e77994dc857b35 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.cpp @@ -0,0 +1,90 @@ +/* + * UnboundedRegExpElement.cpp + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#include "UnboundedRegExpElement.h" +#include <typeinfo> + +#include "UnboundedRegExpElements.h" + +namespace regexp { + +UnboundedRegExpElement::UnboundedRegExpElement() : parentRegExp(NULL) { + +} + +UnboundedRegExpElement::~UnboundedRegExpElement() noexcept { + +} + +bool UnboundedRegExpElement::operator>=(const UnboundedRegExpElement& other) const { + return !(*this < other); +} + +bool UnboundedRegExpElement::operator<=(const UnboundedRegExpElement& other) const { + return !(*this > other); +} + +bool UnboundedRegExpElement::operator!=(const UnboundedRegExpElement& other) const { + return !(*this == other); +} + + +bool UnboundedRegExpElement::operator<(const UnboundedRegExpConcatenation& other) const { + return typeid(*this).before(typeid(other)); +} + +bool UnboundedRegExpElement::operator<(const UnboundedRegExpAlternation& other) const { + return typeid(*this).before(typeid(other)); +} + +bool UnboundedRegExpElement::operator<(const UnboundedRegExpIteration& other) const { + return typeid(*this).before(typeid(other)); +} + +bool UnboundedRegExpElement::operator<(const UnboundedRegExpSymbol& other) const { + return typeid(*this).before(typeid(other)); +} + +bool UnboundedRegExpElement::operator<(const UnboundedRegExpEpsilon& other) const { + return typeid(*this).before(typeid(other)); +} + +bool UnboundedRegExpElement::operator<(const UnboundedRegExpEmpty& other) const { + return typeid(*this).before(typeid(other)); +} + + +bool UnboundedRegExpElement::operator==(const UnboundedRegExpConcatenation&) const { + return false; +} + +bool UnboundedRegExpElement::operator==(const UnboundedRegExpAlternation&) const { + return false; +} + +bool UnboundedRegExpElement::operator==(const UnboundedRegExpIteration&) const { + return false; +} + +bool UnboundedRegExpElement::operator==(const UnboundedRegExpSymbol&) const { + return false; +} + +bool UnboundedRegExpElement::operator==(const UnboundedRegExpEpsilon&) const { + return false; +} + +bool UnboundedRegExpElement::operator==(const UnboundedRegExpEmpty&) const { + return false; +} + +std::ostream& operator<<(std::ostream& out, const UnboundedRegExpElement& regexp) { + regexp >> out; + return out; +} + +} /* namespace regexp */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h new file mode 100644 index 0000000000000000000000000000000000000000..00ee179a21a94527ab1bf1b73b14db1adae7c0c7 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h @@ -0,0 +1,131 @@ +/* + * UnboundedRegExpElement.h + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#ifndef UNBOUNDED_REG_EXP_ELEMENT_H_ +#define UNBOUNDED_REG_EXP_ELEMENT_H_ + +#include "../../std/visitor.hpp" +#include "../../alphabet/Symbol.h" +#include "UnboundedRegExp.h" +#include <set> + +namespace regexp { + +class UnboundedRegExp; + +class UnboundedRegExpAlternation; +class UnboundedRegExpConcatenation; +class UnboundedRegExpIteration; +class UnboundedRegExpSymbol; +class UnboundedRegExpEmpty; +class UnboundedRegExpEpsilon; + +/** + * Abstract class representing element in the regular expression. Can be operator or symbol. + */ +class UnboundedRegExpElement : public std::elementBase<UnboundedRegExpAlternation, UnboundedRegExpConcatenation, UnboundedRegExpIteration, UnboundedRegExpSymbol, UnboundedRegExpEmpty, UnboundedRegExpEpsilon> { +protected: + /* + * Parent regexp contanining this instance of RegExpElement + */ + const UnboundedRegExp * parentRegExp; + + /** + * Traverses the regexp tree looking if particular Symbol is used in the regexp. + * + * @param symbol to test if used in regexp element + * @return true if symbol is used by the element and its successor + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const = 0; + + /** + * Attaches the regexp to this instance and all its childs + * @param regexp parent regexp to attach as parent + * @return true if symbols used in regexp element are in the regexp's alphabet + */ + virtual bool attachRegExp ( const UnboundedRegExp * regexp ) = 0; + + /** + * Traverses the regexp tree computing minimal alphabet needed by regexp + * + * @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>& alphabet ) const = 0; + +public: + UnboundedRegExpElement(); + + /** + * Creates copy of the element. + * @return copy of the element + */ + virtual UnboundedRegExpElement* clone() const = 0; + + virtual UnboundedRegExpElement* plunder() && = 0; + + virtual ~UnboundedRegExpElement() noexcept; + + // RegExpEmpty < RegExpEpsilon < RegExpSymbol < RegExpIteration < RegExpAlternation < RegExpConcatenation + virtual bool operator<(const UnboundedRegExpElement&) const = 0; + virtual bool operator==(const UnboundedRegExpElement&) const = 0; + virtual bool operator>(const UnboundedRegExpElement&) const = 0; + + virtual bool operator>=(const UnboundedRegExpElement&) const; + virtual bool operator<=(const UnboundedRegExpElement&) const; + virtual bool operator!=(const UnboundedRegExpElement&) const; + + virtual bool operator<(const UnboundedRegExpConcatenation&) const; + virtual bool operator<(const UnboundedRegExpAlternation&) const; + virtual bool operator<(const UnboundedRegExpIteration&) const; + virtual bool operator<(const UnboundedRegExpSymbol&) const; + virtual bool operator<(const UnboundedRegExpEpsilon&) const; + virtual bool operator<(const UnboundedRegExpEmpty&) const; + + virtual bool operator==(const UnboundedRegExpConcatenation&) const; + virtual bool operator==(const UnboundedRegExpAlternation&) const; + virtual bool operator==(const UnboundedRegExpIteration&) const; + virtual bool operator==(const UnboundedRegExpSymbol&) const; + virtual bool operator==(const UnboundedRegExpEpsilon&) const; + virtual bool operator==(const UnboundedRegExpEmpty&) const; + + /** + * Prints XML representation of the RegExp to the output stream. + * @param out output stream to which print the RegExp + */ + virtual void operator>>(std::ostream& out) const = 0; + + /** + * Prints XML representation of the RegExp to the output stream. + * @param out output stream to which print the RegExp + * @param regexp RegExp to print + */ + friend std::ostream& operator<<(std::ostream& out, const UnboundedRegExpElement& regexp); + + /** + * @return true if this subtree of regexp matches empty string (epsilon) + */ + virtual bool containsEmptyString() const = 0; + + /** + * @return true if this subtree describes empty language + */ + virtual bool isEmpty() const = 0; + + friend class UnboundedRegExp; + + friend class UnboundedRegExpAlternation; + friend class UnboundedRegExpConcatenation; + friend class UnboundedRegExpIteration; + friend class FromalRegExpSymbol; + friend class UnboundedRegExpEmpty; + friend class UnboundedRegExpEpsilon; +}; + +} /* namespace regexp */ + +#endif /* UNBOUNDED_REG_EXP_ELEMENT_H_ */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpElements.h b/alib2data/src/regexp/unbounded/UnboundedRegExpElements.h new file mode 100644 index 0000000000000000000000000000000000000000..10e3ebb90f8a5ee46024cd69d7a2665d0824dff6 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpElements.h @@ -0,0 +1,19 @@ +/* + * UnboundedRegExpElements.h + * + * Created on: 14. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef UNBOUNDED_REG_EXP_ELEMENTS_H_ +#define UNBOUNDED_REG_EXP_ELEMENTS_H_ + +#include "UnboundedRegExpAlternation.h" +#include "UnboundedRegExpConcatenation.h" +#include "UnboundedRegExpIteration.h" +#include "UnboundedRegExpElement.h" +#include "UnboundedRegExpEpsilon.h" +#include "UnboundedRegExpEmpty.h" +#include "UnboundedRegExpSymbol.h" + +#endif /* UNBOUNDED_REG_EXP_ELEMENTS_H_ */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp new file mode 100644 index 0000000000000000000000000000000000000000..23bbd113008e5efd1e81069355dba12b9a54db9b --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp @@ -0,0 +1,89 @@ +/* + * UnboundedRegExpEmpty.cpp + * + * Created on: Jan 30, 2014 + * Author: Jan Travnicek + */ + +#include "UnboundedRegExpEmpty.h" + +namespace regexp { + +UnboundedRegExpEmpty::UnboundedRegExpEmpty() { + // so that default constructor is available +} + +UnboundedRegExpEmpty::UnboundedRegExpEmpty(const UnboundedRegExpEmpty&) { + // so that copy constructor is available +} + +UnboundedRegExpEmpty::UnboundedRegExpEmpty(UnboundedRegExpEmpty&&) noexcept { + this->attachRegExp(NULL); +} + +UnboundedRegExpEmpty& UnboundedRegExpEmpty::operator =(const UnboundedRegExpEmpty&) { + //this is actually different than default implementation + return *this; +} + +UnboundedRegExpEmpty& UnboundedRegExpEmpty::operator =(UnboundedRegExpEmpty&&) noexcept { + //this is actually different than default implementation + return *this; +} + +UnboundedRegExpElement* UnboundedRegExpEmpty::clone() const { + return new UnboundedRegExpEmpty(*this); +} + +UnboundedRegExpElement* UnboundedRegExpEmpty::plunder() && { + return new UnboundedRegExpEmpty(std::move(*this)); +} + +bool UnboundedRegExpEmpty::operator<(const UnboundedRegExpElement& other) const { + return other > *this; +} + +bool UnboundedRegExpEmpty::operator==(const UnboundedRegExpElement& other) const { + return other == *this; +} + +bool UnboundedRegExpEmpty::operator>(const UnboundedRegExpElement& other) const { + return other < *this; +} + + +bool UnboundedRegExpEmpty::operator<(const UnboundedRegExpEmpty&) const { + return false; +} + +bool UnboundedRegExpEmpty::operator==(const UnboundedRegExpEmpty&) const { + return true; +} + +void UnboundedRegExpEmpty::operator>>(std::ostream& out) const { + out << "(UnboundedRegExpEmpty)"; +} + +bool UnboundedRegExpEmpty::testSymbol( const alphabet::Symbol & ) const { + return false; +} + +bool UnboundedRegExpEmpty::attachRegExp(const UnboundedRegExp * regexp ) { + if(this->parentRegExp == regexp) return true; + this->parentRegExp = regexp; + return true; +} + +void UnboundedRegExpEmpty::computeMinimalAlphabet( std::set<alphabet::Symbol>&) const { + +} + +bool UnboundedRegExpEmpty::containsEmptyString() const { + return false; +} + +bool UnboundedRegExpEmpty::isEmpty() const { + return true; +} + +} /* namespace regexp */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h new file mode 100644 index 0000000000000000000000000000000000000000..598d4a56efac6e71c96c7b55560642f0f5ea4375 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h @@ -0,0 +1,74 @@ +/* + * UnboundedRegExpEmpty.h + * + * Created on: Jan 30, 2014 + * Author: Jan Travnicek + */ + +#ifndef UNBOUNDED_REG_EXP_EMPTY_H_ +#define UNBOUNDED_REG_EXP_EMPTY_H_ + +#include "UnboundedRegExpElement.h" + +namespace regexp { + +/** + * Represents empty regular expression in the regular expression. + */ +class UnboundedRegExpEmpty: public std::element<UnboundedRegExpEmpty, UnboundedRegExpElement> { +protected: + /** + * @copydoc UnboundedRegExpElement::clone() const + */ + virtual UnboundedRegExpElement* clone() const; + + virtual UnboundedRegExpElement* plunder() &&; + + /** + * @copydoc UnboundedRegExpElement::testSymbol() const + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const; + + /** + * @copydoc UnboundedRegExpElement::attachRegExp() + */ + virtual bool attachRegExp ( const UnboundedRegExp * regexp ); + + /** + * @copydoc RegExpElement::computeMinimalAlphabet() + */ + virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; + +public: + UnboundedRegExpEmpty(); + UnboundedRegExpEmpty(const UnboundedRegExpEmpty& other); + UnboundedRegExpEmpty(UnboundedRegExpEmpty&& other) noexcept; + UnboundedRegExpEmpty& operator =(const UnboundedRegExpEmpty& other); + UnboundedRegExpEmpty& operator =(UnboundedRegExpEmpty&& other) noexcept; + + virtual bool operator<(const UnboundedRegExpElement&) const; + virtual bool operator==(const UnboundedRegExpElement&) const; + virtual bool operator>(const UnboundedRegExpElement&) const; + + virtual bool operator<(const UnboundedRegExpEmpty&) const; + virtual bool operator==(const UnboundedRegExpEmpty&) const; + + /** + * @copydoc UnboundedRegExpElement::operator>>() const + */ + virtual void operator>>(std::ostream& out) const; + + /** + * @copydoc UnboundedRegExpElement::containsEmptyString() const + */ + virtual bool containsEmptyString() const; + + /** + * @copydoc UnboundedRegExpElement::isEmpty() const + */ + virtual bool isEmpty() const; +}; + +} /* namespace regexp */ + +#endif /* UNBOUNDED_REG_EXP_EMPTY_H_ */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp new file mode 100644 index 0000000000000000000000000000000000000000..10544081928510e34f654f8abec088112d993be9 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp @@ -0,0 +1,89 @@ +/* + * UnboundedRegExpEpsilon.cpp + * + * Created on: Jan 30, 2014 + * Author: Jan Travnicek + */ + +#include "UnboundedRegExpEpsilon.h" + +namespace regexp { + +UnboundedRegExpEpsilon::UnboundedRegExpEpsilon() { + // so that default constructor is available +} + +UnboundedRegExpEpsilon::UnboundedRegExpEpsilon(const UnboundedRegExpEpsilon&) { + // so that copy constructor is available +} + +UnboundedRegExpEpsilon::UnboundedRegExpEpsilon(UnboundedRegExpEpsilon&&) noexcept { + this->attachRegExp(NULL); +} + +UnboundedRegExpEpsilon& UnboundedRegExpEpsilon::operator =(const UnboundedRegExpEpsilon&) { + //this is actually different than default implementation + return *this; +} + +UnboundedRegExpEpsilon& UnboundedRegExpEpsilon::operator =(UnboundedRegExpEpsilon&&) noexcept { + //this is actually different than default implementation + return *this; +} + +UnboundedRegExpElement* UnboundedRegExpEpsilon::clone() const { + return new UnboundedRegExpEpsilon(*this); +} + +UnboundedRegExpElement* UnboundedRegExpEpsilon::plunder() && { + return new UnboundedRegExpEpsilon(std::move(*this)); +} + +bool UnboundedRegExpEpsilon::operator<(const UnboundedRegExpElement& other) const { + return other > *this; +} + +bool UnboundedRegExpEpsilon::operator==(const UnboundedRegExpElement& other) const { + return other == *this; +} + +bool UnboundedRegExpEpsilon::operator>(const UnboundedRegExpElement& other) const { + return other < *this; +} + + +bool UnboundedRegExpEpsilon::operator<(const UnboundedRegExpEpsilon&) const { + return false; +} + +bool UnboundedRegExpEpsilon::operator==(const UnboundedRegExpEpsilon&) const { + return true; +} + +void UnboundedRegExpEpsilon::operator>>(std::ostream& out) const { + out << "(UnboundedRegExpEpsilon)"; +} + +bool UnboundedRegExpEpsilon::testSymbol( const alphabet::Symbol & ) const { + return false; +} + +bool UnboundedRegExpEpsilon::attachRegExp(const UnboundedRegExp * regexp ) { + if(this->parentRegExp == regexp) return true; + this->parentRegExp = regexp; + return true; +} + +void UnboundedRegExpEpsilon::computeMinimalAlphabet( std::set<alphabet::Symbol>&) const { + +} + +bool UnboundedRegExpEpsilon::containsEmptyString() const { + return true; +} + +bool UnboundedRegExpEpsilon::isEmpty() const { + return false; +} + +} /* namespace regexp */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h new file mode 100644 index 0000000000000000000000000000000000000000..d69f3f6701bc302df16a65ec42c1651d910e45a0 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h @@ -0,0 +1,75 @@ +/* + * UnboundedRegExpEpsilon.h + * + * Created on: Jan 30, 2014 + * Author: Jan Travnicek + */ + +#ifndef UNBOUNDED_REG_EXP_EPSILON_H_ +#define UNBOUNDED_REG_EXP_EPSILON_H_ + +#include "UnboundedRegExpElement.h" + +namespace regexp { + +/** + * Represents epsilon in the regular expression. + */ +class UnboundedRegExpEpsilon: public std::element<UnboundedRegExpEpsilon, UnboundedRegExpElement> { +protected: + /** + * @copydoc UnboundedRegExpElement::clone() const + */ + virtual UnboundedRegExpElement* clone() const; + + virtual UnboundedRegExpElement* plunder() &&; + + /** + * @copydoc UnboundedRegExpElement::testSymbol() const + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const; + + /** + * @copydoc UnboundedRegExpElement::attachRegExp() + */ + virtual bool attachRegExp ( const UnboundedRegExp * regexp ); + + /** + * @copydoc UnboundedRegExpElement::computeMinimalAlphabet() + */ + virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; + +public: + + UnboundedRegExpEpsilon(); + UnboundedRegExpEpsilon(const UnboundedRegExpEpsilon& other); + UnboundedRegExpEpsilon(UnboundedRegExpEpsilon&& other) noexcept; + UnboundedRegExpEpsilon& operator=(const UnboundedRegExpEpsilon& other); + UnboundedRegExpEpsilon& operator=(UnboundedRegExpEpsilon&& other) noexcept; + + virtual bool operator<(const UnboundedRegExpElement&) const; + virtual bool operator==(const UnboundedRegExpElement&) const; + virtual bool operator>(const UnboundedRegExpElement&) const; + + virtual bool operator<(const UnboundedRegExpEpsilon&) const; + virtual bool operator==(const UnboundedRegExpEpsilon&) const; + + /** + * @copydoc UnboundedRegExpElement::operator>>() const + */ + virtual void operator>>(std::ostream& out) const; + + /** + * @copydoc UnboundedRegExpElement::containsEmptyString() const + */ + virtual bool containsEmptyString() const; + + /** + * @copydoc UnboundedRegExpElement::isEmpty() const + */ + virtual bool isEmpty() const; +}; + +} /* namespace regexp */ + +#endif /* UNBOUNDED_REG_EXP_EPSILON_H_ */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9e2322a0cf6b205a5344391c8b1bcf83f79c5735 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp @@ -0,0 +1,133 @@ +/* + * UnboundedRegExpIteration.cpp + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#include "UnboundedRegExpIteration.h" +#include "../../exception/AlibException.h" + +namespace regexp { + +UnboundedRegExpIteration::UnboundedRegExpIteration(UnboundedRegExpElement&& element) : element( NULL ) { + this->setElement(std::move(element)); +} + +UnboundedRegExpIteration::UnboundedRegExpIteration(const UnboundedRegExpElement& element) : element( NULL ) { + this->setElement(element); +} + + +UnboundedRegExpIteration::UnboundedRegExpIteration(const UnboundedRegExpIteration& other) : element(other.element->clone()) { + +} + +UnboundedRegExpIteration::UnboundedRegExpIteration(UnboundedRegExpIteration&& other) noexcept : element(other.element) { + other.element = NULL; + this->attachRegExp(NULL); +} + +UnboundedRegExpIteration& UnboundedRegExpIteration::operator=(const UnboundedRegExpIteration& other) { + if (this == &other) { + return *this; + } + + *this = UnboundedRegExpIteration(other); + + return *this; +} + +UnboundedRegExpIteration& UnboundedRegExpIteration::operator=(UnboundedRegExpIteration&& other) { + std::swap(this->element, other.element); + std::swap(this->parentRegExp, other.parentRegExp); + + this->attachRegExp(other.parentRegExp); + + return *this; +} + +regexp::UnboundedRegExpIteration::~UnboundedRegExpIteration() noexcept { + delete element; +} + +const UnboundedRegExpElement & UnboundedRegExpIteration::getElement() const { + return *element; +} + +UnboundedRegExpElement & UnboundedRegExpIteration::getElement() { + return *element; +} + +void UnboundedRegExpIteration::setElement(const UnboundedRegExpElement& element) { + UnboundedRegExpElement* elem = element.clone(); + if(this->parentRegExp && !this->element->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + delete this->element; + this->element = elem; +} + +void UnboundedRegExpIteration::setElement(UnboundedRegExpElement&& element) { + UnboundedRegExpElement* elem = std::move(element).plunder(); + if(this->parentRegExp && !this->element->attachRegExp(this->parentRegExp)) + throw exception::AlibException("Input symbols not in the alphabet."); + delete this->element; + this->element = elem; +} + +UnboundedRegExpElement* UnboundedRegExpIteration::clone() const { + return new UnboundedRegExpIteration(*this); +} + +UnboundedRegExpElement* UnboundedRegExpIteration::plunder() && { + return new UnboundedRegExpIteration(std::move(*this)); +} + +bool UnboundedRegExpIteration::operator<(const UnboundedRegExpElement& other) const { + return other > *this; +} + +bool UnboundedRegExpIteration::operator==(const UnboundedRegExpElement& other) const { + return other == *this; +} + +bool UnboundedRegExpIteration::operator>(const UnboundedRegExpElement& other) const { + return other < *this; +} + +bool UnboundedRegExpIteration::operator<(const UnboundedRegExpIteration& other) const { + return *(this->element) < *(other.element); +} + +bool UnboundedRegExpIteration::operator==(const UnboundedRegExpIteration& other) const { + return *(this->element) == *(other.element); +} + +void UnboundedRegExpIteration::operator>>(std::ostream& out) const { + out << "(RegExpUnboundedRegExpIteration " << *element << ")"; +} + +bool UnboundedRegExpIteration::testSymbol( const alphabet::Symbol & symbol ) const { + return element->testSymbol( symbol ); +} + +bool UnboundedRegExpIteration::attachRegExp(const UnboundedRegExp * regexp ) { + if(this->parentRegExp == regexp) return true; + this->parentRegExp = regexp; + return this->element->attachRegExp(regexp); +} + +void UnboundedRegExpIteration::computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const { + element->computeMinimalAlphabet(alphabet); +} + +bool UnboundedRegExpIteration::containsEmptyString() const { + return true; +} + +bool UnboundedRegExpIteration::isEmpty() const { + return false; +} + +} /* namespace regexp */ + diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h new file mode 100644 index 0000000000000000000000000000000000000000..7a8fe4e3ace30aab2ce5383474346c3c880abaa9 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h @@ -0,0 +1,98 @@ +/* + * UnboundedRegExpIteration.h + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#ifndef UNBOUNDED_REG_EXP_ITERATION_H_ +#define UNBOUNDED_REG_EXP_ITERATION_H_ + +#include "UnboundedRegExpElement.h" +#include "UnboundedRegExpEmpty.h" + +namespace regexp { + +/** + * Represents iteration operator in the regular expression. Contains one UnboundedRegExpElement + * as operand. + */ +class UnboundedRegExpIteration: public std::element<UnboundedRegExpIteration, UnboundedRegExpElement> { +protected: + UnboundedRegExpElement* element; + + /** + * @copydoc UnboundedRegExpElement::clone() const + */ + virtual UnboundedRegExpElement* clone() const; + + virtual UnboundedRegExpElement* plunder() &&; + + /** + * @copydoc UnboundedRegExpElement::testSymbol() const + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const; + + /** + * @copydoc UnboundedRegExpElement::attachRegExp() + */ + virtual bool attachRegExp ( const UnboundedRegExp * regexp ); + + /** + * @copydoc UnboundedRegExpElement::computeMinimalAlphabet() + */ + virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; + +public: + explicit UnboundedRegExpIteration(UnboundedRegExpElement&&); + explicit UnboundedRegExpIteration(const UnboundedRegExpElement&); + + UnboundedRegExpIteration(const UnboundedRegExpIteration& other); + UnboundedRegExpIteration(UnboundedRegExpIteration&& other) noexcept; + UnboundedRegExpIteration& operator =(const UnboundedRegExpIteration& other); + UnboundedRegExpIteration& operator =(UnboundedRegExpIteration&& other); + virtual ~UnboundedRegExpIteration() noexcept; + + /** + * @return element + */ + const UnboundedRegExpElement & getElement() const; + + /** + * @return element + */ + UnboundedRegExpElement & getElement(); + + /** + * @param element to iterate + */ + void setElement(const UnboundedRegExpElement& element); + + void setElement(UnboundedRegExpElement&& element); + + virtual bool operator<(const UnboundedRegExpElement&) const; + virtual bool operator==(const UnboundedRegExpElement&) const; + virtual bool operator>(const UnboundedRegExpElement&) const; + + virtual bool operator<(const UnboundedRegExpIteration&) const; + virtual bool operator==(const UnboundedRegExpIteration&) const; + + /** + * @copydoc UnboundedRegExpElement::operator>>() const + */ + virtual void operator>>(std::ostream& out) const; + + /** + * @copydoc UnboundedRegExpElement::containsEmptyString() const + */ + virtual bool containsEmptyString() const; + + /** + * @copydoc UnboundedRegExpElement::isEmpty() const + */ + virtual bool isEmpty() const; +}; + +} /* namespace regexp */ + +#endif /* UNBOUNDED_REG_EXP_ITERATION_H_ */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp new file mode 100644 index 0000000000000000000000000000000000000000..268abb7585d6b299126249b29dcfea29d1642b63 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp @@ -0,0 +1,116 @@ +/* + * UnboundedRegExpSymbol.cpp + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#include "UnboundedRegExpSymbol.h" + +namespace regexp { + +UnboundedRegExpSymbol::UnboundedRegExpSymbol(const UnboundedRegExpSymbol& other) : symbol(other.symbol) { + +} + +UnboundedRegExpSymbol::UnboundedRegExpSymbol(UnboundedRegExpSymbol&& other) noexcept : symbol(std::move(other.symbol)) { + this->attachRegExp(NULL); +} + +UnboundedRegExpSymbol& UnboundedRegExpSymbol::operator=(const UnboundedRegExpSymbol& other) { + if (this == &other) { + return *this; + } + + *this = UnboundedRegExpSymbol(other); + + return *this; +} + +UnboundedRegExpSymbol& UnboundedRegExpSymbol::operator=(UnboundedRegExpSymbol&& other) { + std::swap(this->symbol, other.symbol); + std::swap(this->parentRegExp, other.parentRegExp); + + this->attachRegExp(other.parentRegExp); + + return *this; +} + +UnboundedRegExpSymbol::UnboundedRegExpSymbol(const alphabet::Symbol& symbol) : + symbol(symbol) { +} + +UnboundedRegExpSymbol::UnboundedRegExpSymbol(alphabet::Symbol&& symbol) : + symbol(std::move(symbol)) { +} + +UnboundedRegExpElement* UnboundedRegExpSymbol::clone() const { + return new UnboundedRegExpSymbol(*this); +} + +UnboundedRegExpElement* UnboundedRegExpSymbol::plunder() && { + return new UnboundedRegExpSymbol(std::move(*this)); +} + +bool UnboundedRegExpSymbol::operator==(const alphabet::Symbol& other) const { + return this->symbol == other; +} + +bool operator==(const alphabet::Symbol& first, const UnboundedRegExpSymbol& second) { + return first == second.symbol; +} + +bool UnboundedRegExpSymbol::operator<(const UnboundedRegExpElement& other) const { + return other > *this; +} + +bool UnboundedRegExpSymbol::operator==(const UnboundedRegExpElement& other) const { + return other == *this; +} + +bool UnboundedRegExpSymbol::operator>(const UnboundedRegExpElement& other) const { + return other < *this; +} + + +bool UnboundedRegExpSymbol::operator<(const UnboundedRegExpSymbol& other) const { + return symbol < other.symbol; +} + +bool UnboundedRegExpSymbol::operator==(const UnboundedRegExpSymbol& other) const { + return symbol == other.symbol; +} + +void UnboundedRegExpSymbol::operator>>(std::ostream& out) const { + out << "(UnboundedRegExpSymbol " << symbol << ")"; +} + +bool UnboundedRegExpSymbol::containsEmptyString() const { + return false; +} + +bool UnboundedRegExpSymbol::isEmpty() const { + return false; +} + +bool UnboundedRegExpSymbol::testSymbol( const alphabet::Symbol & symbol ) const { + return symbol == this->symbol; +} + +bool UnboundedRegExpSymbol::attachRegExp(const UnboundedRegExp * regexp ) { + if(this->parentRegExp == regexp) return true; + this->parentRegExp = regexp; + if(regexp == NULL) return true; + return this->parentRegExp->getAlphabet().find(this->symbol) != this->parentRegExp->getAlphabet().end(); +} + +void UnboundedRegExpSymbol::computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const { + alphabet.insert(this->symbol); +} + +const alphabet::Symbol& UnboundedRegExpSymbol::getSymbol() const { + return this->symbol; +} + +} /* namespace regexp */ + diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h new file mode 100644 index 0000000000000000000000000000000000000000..f282d312c6df358c4a8eb810c74dea03afa635b9 --- /dev/null +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h @@ -0,0 +1,88 @@ +/* + * UnboundedRegExpSymbol.h + * + * Created on: Nov 23, 2013 + * Author: Martin Zak + */ + +#ifndef UNBOUNDED_REG_EXP_SYMBOL_H_ +#define UNBOUNDED_REG_EXP_SYMBOL_H_ + +#include "../../label/Label.h" +#include "UnboundedRegExpElement.h" +#include "../../alphabet/LabeledSymbol.h" + +namespace regexp { + +/** + * Represents symbol in the regular expression. Contains name of the symbol. + */ +class UnboundedRegExpSymbol : public std::element<UnboundedRegExpSymbol, UnboundedRegExpElement> { +protected: + alphabet::Symbol symbol; + + /** + * @copydoc UnboundedRegExpElement::clone() const + */ + virtual UnboundedRegExpElement* clone() const; + + virtual UnboundedRegExpElement* plunder() &&; + + /** + * @copydoc UnboundedRegExpElement::testSymbol() const + */ + virtual bool testSymbol( const alphabet::Symbol & symbol ) const; + + /** + * @copydoc UnboundedRegExpElement::attachRegExp() + */ + virtual bool attachRegExp ( const UnboundedRegExp * regexp ); + + /** + * @copydoc UnboundedRegExpElement::computeMinimalAlphabet() + */ + virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const; +public: + explicit UnboundedRegExpSymbol(const alphabet::Symbol& symbol); + explicit UnboundedRegExpSymbol(alphabet::Symbol&& symbol); + + UnboundedRegExpSymbol(const UnboundedRegExpSymbol& other); + UnboundedRegExpSymbol(UnboundedRegExpSymbol&& other) noexcept; + UnboundedRegExpSymbol& operator=(const UnboundedRegExpSymbol& other); + UnboundedRegExpSymbol& operator=(UnboundedRegExpSymbol&& other); + + bool operator==(const alphabet::Symbol&) const; + friend bool operator==(const alphabet::Symbol&, const UnboundedRegExpSymbol&); + + virtual bool operator<(const UnboundedRegExpElement&) const; + virtual bool operator==(const UnboundedRegExpElement&) const; + virtual bool operator>(const UnboundedRegExpElement&) const; + + virtual bool operator<(const UnboundedRegExpSymbol&) const; + virtual bool operator==(const UnboundedRegExpSymbol&) const; + + /** + * @copydoc UnboundedRegExpElement::operator>>() const + */ + virtual void operator>>(std::ostream& out) const; + + /** + * @copydoc UnboundedRegExpElement::containsEmptyString() const + */ + virtual bool containsEmptyString() const; + + /** + * Returns the string representation of RegExp Symbol. + */ + const alphabet::Symbol& getSymbol() const; + + /** + * @copydoc UnboundedRegExpElement::isEmpty() const + */ + virtual bool isEmpty() const; +}; + +} /* namespace regexp */ + +#endif /* UNBOUNDED_REG_EXP_SYMBOL_H_ */ + diff --git a/alib2data/test-src/regexp/RegExpTest.cpp b/alib2data/test-src/regexp/RegExpTest.cpp index ce104afd65aa02f901f5929fa7b5fff776e2cc16..2b5036aca012a6779994270a480ecf956f2ab89c 100644 --- a/alib2data/test-src/regexp/RegExpTest.cpp +++ b/alib2data/test-src/regexp/RegExpTest.cpp @@ -4,7 +4,7 @@ #include "sax/SaxParseInterface.h" #include "sax/SaxComposeInterface.h" -#include "regexp/RegExp.h" +#include "regexp/unbounded/UnboundedRegExp.h" #include "regexp/RegExpFromStringParser.h" #include "regexp/RegExpToStringComposer.h" #include "regexp/RegExpFromXMLParser.h" @@ -26,24 +26,28 @@ void RegExpTest::tearDown() { } void RegExpTest::testCopyConstruct() { - regexp::RegExp regexp; + regexp::UnboundedRegExp regexp; regexp.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"))))}); - regexp.setRegExp(regexp::Alternation( - regexp::Concatenation( - regexp::RegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1"))))), - regexp::RegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2"))))) - ), - regexp::Iteration( - regexp::RegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1"))))) - ) - ) - ); - - regexp::RegExp regexp2(regexp); + regexp::UnboundedRegExpSymbol l1 = regexp::UnboundedRegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1"))))); + regexp::UnboundedRegExpSymbol l2 = regexp::UnboundedRegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2"))))); + + regexp::UnboundedRegExpConcatenation con = regexp::UnboundedRegExpConcatenation(); + con.appendElement(l1); + con.appendElement(l2); + + regexp::UnboundedRegExpIteration ite = regexp::UnboundedRegExpIteration(l1); + + regexp::UnboundedRegExpAlternation alt = regexp::UnboundedRegExpAlternation(); + alt.appendElement(con); + alt.appendElement(ite); + + regexp.setRegExp(alt); + + regexp::UnboundedRegExp regexp2(regexp); CPPUNIT_ASSERT( regexp == regexp2 ); - regexp::RegExp regexp3(std::move(regexp)); + regexp::UnboundedRegExp regexp3(std::move(regexp)); CPPUNIT_ASSERT( regexp2 == regexp3 ); } @@ -107,18 +111,25 @@ void RegExpTest::testEqual() { void RegExpTest::testXMLParser() { - regexp::RegExp regexp; - regexp.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"))))}); - regexp.setRegExp(regexp::Alternation( - regexp::Concatenation( - regexp::RegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1"))))), - regexp::RegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2"))))) - ), - regexp::Iteration( - regexp::RegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1"))))) - ) - ) - ); + regexp::UnboundedRegExp unboundedRegexp; + unboundedRegexp.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"))))}); + + regexp::UnboundedRegExpSymbol l1 = regexp::UnboundedRegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1"))))); + regexp::UnboundedRegExpSymbol l2 = regexp::UnboundedRegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2"))))); + + regexp::UnboundedRegExpConcatenation con = regexp::UnboundedRegExpConcatenation(); + con.appendElement(l1); + con.appendElement(l2); + + regexp::UnboundedRegExpIteration ite = regexp::UnboundedRegExpIteration(l1); + + regexp::UnboundedRegExpAlternation alt = regexp::UnboundedRegExpAlternation(); + alt.appendElement(con); + alt.appendElement(ite); + + unboundedRegexp.setRegExp(alt); + + regexp::RegExp regexp(unboundedRegexp); { regexp::RegExpToXMLComposer composer; @@ -142,17 +153,23 @@ void RegExpTest::testXMLParser() { } void RegExpTest::testOrder() { - regexp::RegExpSymbol s1(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1"))))); - regexp::RegExpEmpty e1; - regexp::RegExpEpsilon e2; - regexp::Iteration i1(s1); - - regexp::RegExp alt1(regexp::Alternation(s1, s1)); - regexp::RegExp con1(regexp::Concatenation (s1, s1)); - regexp::RegExp ite1(i1); - regexp::RegExp emp1(e1); - regexp::RegExp eps1(e2); - regexp::RegExp sym1(s1); + regexp::UnboundedRegExpSymbol s1(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1"))))); + regexp::UnboundedRegExpEmpty e1; + regexp::UnboundedRegExpEpsilon e2; + regexp::UnboundedRegExpIteration i1(s1); + regexp::UnboundedRegExpConcatenation a1; + a1.appendElement(s1); + a1.appendElement(s1); + regexp::UnboundedRegExpAlternation c1; + c1.appendElement(s1); + c1.appendElement(s1); + + regexp::UnboundedRegExp alt1(a1); + regexp::UnboundedRegExp con1(c1); + regexp::UnboundedRegExp ite1(i1); + regexp::UnboundedRegExp emp1(e1); + regexp::UnboundedRegExp eps1(e2); + regexp::UnboundedRegExp sym1(s1); CPPUNIT_EXCLUSIVE_OR(alt1 < con1, con1 < alt1); CPPUNIT_EXCLUSIVE_OR(alt1 < ite1, ite1 < alt1); @@ -336,47 +353,103 @@ void RegExpTest::testOrder() { } void RegExpTest::testOrder2() { - regexp::RegExpSymbol s1(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1"))))); - regexp::RegExpSymbol s2(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2"))))); - regexp::RegExpSymbol s3(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("3"))))); - - regexp::RegExpEmpty e1; - regexp::RegExpEpsilon e2; - - regexp::Iteration i1(s1); - regexp::Iteration i2(s2); - regexp::Iteration i3(s3); - - regexp::RegExp alt1(regexp::Alternation(s1, s1)); - regexp::RegExp alt2(regexp::Alternation(s1, s2)); - regexp::RegExp alt3(regexp::Alternation(s1, s3)); - regexp::RegExp alt4(regexp::Alternation(s2, s1)); - regexp::RegExp alt5(regexp::Alternation(s2, s2)); - regexp::RegExp alt6(regexp::Alternation(s2, s3)); - regexp::RegExp alt7(regexp::Alternation(s3, s1)); - regexp::RegExp alt8(regexp::Alternation(s3, s2)); - regexp::RegExp alt9(regexp::Alternation(s3, s3)); - - regexp::RegExp con1(regexp::Concatenation (s1, s1)); - regexp::RegExp con2(regexp::Concatenation (s1, s2)); - regexp::RegExp con3(regexp::Concatenation (s1, s3)); - regexp::RegExp con4(regexp::Concatenation (s2, s1)); - regexp::RegExp con5(regexp::Concatenation (s2, s2)); - regexp::RegExp con6(regexp::Concatenation (s2, s3)); - regexp::RegExp con7(regexp::Concatenation (s3, s1)); - regexp::RegExp con8(regexp::Concatenation (s3, s2)); - regexp::RegExp con9(regexp::Concatenation (s3, s3)); - - regexp::RegExp ite1(i1); - regexp::RegExp ite2(i2); - regexp::RegExp ite3(i3); - - regexp::RegExp emp1(e1); - regexp::RegExp eps1(e2); - - regexp::RegExp sym1(s1); - regexp::RegExp sym2(s2); - regexp::RegExp sym3(s3); + regexp::UnboundedRegExpSymbol s1(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1"))))); + regexp::UnboundedRegExpSymbol s2(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2"))))); + regexp::UnboundedRegExpSymbol s3(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("3"))))); + + regexp::UnboundedRegExpEmpty e1; + regexp::UnboundedRegExpEpsilon e2; + + regexp::UnboundedRegExpIteration i1(s1); + regexp::UnboundedRegExpIteration i2(s2); + regexp::UnboundedRegExpIteration i3(s3); + + regexp::UnboundedRegExpAlternation a1; + a1.appendElement(s1); + a1.appendElement(s1); + regexp::UnboundedRegExpAlternation a2; + a2.appendElement(s1); + a2.appendElement(s2); + regexp::UnboundedRegExpAlternation a3; + a3.appendElement(s1); + a3.appendElement(s3); + regexp::UnboundedRegExpAlternation a4; + a4.appendElement(s2); + a4.appendElement(s1); + regexp::UnboundedRegExpAlternation a5; + a5.appendElement(s2); + a5.appendElement(s2); + regexp::UnboundedRegExpAlternation a6; + a6.appendElement(s2); + a6.appendElement(s3); + regexp::UnboundedRegExpAlternation a7; + a7.appendElement(s3); + a7.appendElement(s1); + regexp::UnboundedRegExpAlternation a8; + a8.appendElement(s3); + a8.appendElement(s2); + regexp::UnboundedRegExpAlternation a9; + a9.appendElement(s3); + a9.appendElement(s3); + + regexp::UnboundedRegExpConcatenation c1; + c1.appendElement(s1); + c1.appendElement(s1); + regexp::UnboundedRegExpConcatenation c2; + c2.appendElement(s1); + c2.appendElement(s2); + regexp::UnboundedRegExpConcatenation c3; + c3.appendElement(s1); + c3.appendElement(s3); + regexp::UnboundedRegExpConcatenation c4; + c4.appendElement(s2); + c4.appendElement(s1); + regexp::UnboundedRegExpConcatenation c5; + c5.appendElement(s2); + c5.appendElement(s2); + regexp::UnboundedRegExpConcatenation c6; + c6.appendElement(s2); + c6.appendElement(s3); + regexp::UnboundedRegExpConcatenation c7; + c7.appendElement(s3); + c7.appendElement(s1); + regexp::UnboundedRegExpConcatenation c8; + c8.appendElement(s3); + c8.appendElement(s2); + regexp::UnboundedRegExpConcatenation c9; + c9.appendElement(s3); + c9.appendElement(s3); + + regexp::UnboundedRegExp alt1(a1); + regexp::UnboundedRegExp alt2(a2); + regexp::UnboundedRegExp alt3(a3); + regexp::UnboundedRegExp alt4(a4); + regexp::UnboundedRegExp alt5(a5); + regexp::UnboundedRegExp alt6(a6); + regexp::UnboundedRegExp alt7(a7); + regexp::UnboundedRegExp alt8(a8); + regexp::UnboundedRegExp alt9(a9); + + regexp::UnboundedRegExp con1(c1); + regexp::UnboundedRegExp con2(c2); + regexp::UnboundedRegExp con3(c3); + regexp::UnboundedRegExp con4(c4); + regexp::UnboundedRegExp con5(c5); + regexp::UnboundedRegExp con6(c6); + regexp::UnboundedRegExp con7(c7); + regexp::UnboundedRegExp con8(c8); + regexp::UnboundedRegExp con9(c9); + + regexp::UnboundedRegExp ite1(i1); + regexp::UnboundedRegExp ite2(i2); + regexp::UnboundedRegExp ite3(i3); + + regexp::UnboundedRegExp emp1(e1); + regexp::UnboundedRegExp eps1(e2); + + regexp::UnboundedRegExp sym1(s1); + regexp::UnboundedRegExp sym2(s2); + regexp::UnboundedRegExp sym3(s3);