diff --git a/alib/src/regexp/Alternation.cpp b/alib/src/regexp/Alternation.cpp index 721641b07e4d1de737e4ee9cc4b2bfe50e8bff43..e5fe8a1ee70636030372ad6f5eebffc8dae70bf2 100644 --- a/alib/src/regexp/Alternation.cpp +++ b/alib/src/regexp/Alternation.cpp @@ -13,65 +13,41 @@ Alternation::Alternation() { } Alternation::Alternation(const Alternation& other) { - for (auto element : other.first) { - first.push_back(element->clone()); - } - for (auto element : other.second) { - second.push_back(element->clone()); + for (auto element : other.elements) { + elements.push_back(element->clone()); } } Alternation& Alternation::operator =(const Alternation& other) { - for (auto element : first) { - delete element; + if (this == &other) { + return *this; } - first.clear(); - for (auto element : second) { + for (auto element : elements) { delete element; } - first.clear(); + elements.clear(); - for (auto element : other.first) { - first.push_back(element->clone()); - } - for (auto element : other.second) { - second.push_back(element->clone()); + for (auto element : other.elements) { + elements.push_back(element->clone()); } + + return *this; } Alternation::~Alternation() { - for (auto element : first) { - delete element; - } - first.clear(); - - for (auto element : second) { + for (auto element : elements) { delete element; } - first.clear(); + elements.clear(); } -list<RegExpElement*>& Alternation::getFirst() { - return first; +list<RegExpElement*>& Alternation::getElements() { + return elements; } -list<RegExpElement*>& Alternation::getSecond() { - return second; -} - -RegExpElement* Alternation::clone() { - Alternation* toReturn = new Alternation(); - - for (auto element : first) { - toReturn->getFirst().push_back(element->clone()); - } - - for (auto element : second) { - toReturn->getSecond().push_back(element->clone()); - } - - return toReturn; +RegExpElement* Alternation::clone() const { + return new Alternation(*this); } } /* namespace regexp */ diff --git a/alib/src/regexp/Alternation.h b/alib/src/regexp/Alternation.h index 8ea6abee3f1625bfd965f49cc8a60d2d9b1d6e92..acd530bd611e5159c89e72868f9d291fc52426b9 100644 --- a/alib/src/regexp/Alternation.h +++ b/alib/src/regexp/Alternation.h @@ -17,18 +17,16 @@ using namespace std; class Alternation: public RegExpElement { private: - list<RegExpElement*> first; - list<RegExpElement*> second; + list<RegExpElement*> elements; public: Alternation(); Alternation(const Alternation& other); Alternation& operator = (const Alternation& other); ~Alternation(); - list<RegExpElement*>& getFirst(); - list<RegExpElement*>& getSecond(); + list<RegExpElement*>& getElements(); - RegExpElement* clone(); + RegExpElement* clone() const; }; } /* namespace regexp */ diff --git a/alib/src/regexp/Concatenation.cpp b/alib/src/regexp/Concatenation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bf4637c1784d470f5378112540e580f260b45446 --- /dev/null +++ b/alib/src/regexp/Concatenation.cpp @@ -0,0 +1,53 @@ +/* + * Concatenation.cpp + * + * Created on: Nov 27, 2013 + * Author: martin + */ + +#include "Concatenation.h" + +namespace regexp { + +Concatenation::Concatenation() { +} + +Concatenation::Concatenation(const Concatenation& other) { + for (auto element : other.elements) { + elements.push_back(element->clone()); + } +} + +Concatenation& Concatenation::operator =(const Concatenation& other) { + if(this == &other) { + return *this; + } + + for (auto element : elements) { + delete element; + } + elements.clear(); + + for (auto element : other.elements) { + elements.push_back(element->clone()); + } + + return *this; +} + +Concatenation::~Concatenation() { + for (auto element : elements) { + delete element; + } + elements.clear(); +} + +list<RegExpElement*>& Concatenation::getElements() { + return elements; +} + +RegExpElement* Concatenation::clone() const { + return new Concatenation(*this); +} + +} /* namespace regexp */ diff --git a/alib/src/regexp/Concatenation.h b/alib/src/regexp/Concatenation.h new file mode 100644 index 0000000000000000000000000000000000000000..ec914dfa8f49b551e198be1966993f342a816ce5 --- /dev/null +++ b/alib/src/regexp/Concatenation.h @@ -0,0 +1,34 @@ +/* + * Concatenation.h + * + * Created on: Nov 27, 2013 + * Author: martin + */ + +#ifndef CONCATENATION_H_ +#define CONCATENATION_H_ + +#include <list> +#include "RegExpElement.h" + +namespace regexp { + +using namespace std; + +class Concatenation: public RegExpElement { +private: + list<RegExpElement*> elements; +public: + Concatenation(); + Concatenation(const Concatenation& other); + Concatenation& operator = (const Concatenation& other); + ~Concatenation(); + + list<RegExpElement*>& getElements(); + + RegExpElement* clone() const; + +}; + +} /* namespace regexp */ +#endif /* CONCATENATION_H_ */ diff --git a/alib/src/regexp/Iteration.cpp b/alib/src/regexp/Iteration.cpp index f43c577dc5463ec6fc28af48af2db75e0b3615b6..f787e11bbd23d1e0f648b91a03ab6a9e288fa37c 100644 --- a/alib/src/regexp/Iteration.cpp +++ b/alib/src/regexp/Iteration.cpp @@ -6,46 +6,59 @@ */ #include "Iteration.h" +#include <cstdio> namespace regexp { Iteration::Iteration() { + element = NULL; } Iteration::Iteration(const Iteration& other) { - for (auto element : other.elements) { - elements.push_back(element->clone()); + if (other.element != NULL) { + element = other.element->clone(); + } else { + element = NULL; } + } Iteration& Iteration::operator=(const Iteration& other) { - for (auto element : elements) { + if (this == &other) { + return *this; + } + + if (element != NULL) { delete element; } - elements.clear(); - for (auto element : other.elements) { - elements.push_back(element->clone()); + if (other.element != NULL) { + element = other.element->clone(); + } else { + element = NULL; } + + return *this; } regexp::Iteration::~Iteration() { - for (auto element : elements) { + if (element != NULL) { delete element; } - elements.clear(); + + element = NULL; } -list<RegExpElement*>& regexp::Iteration::getElements() { - return elements; +RegExpElement* Iteration::getElement() { + return element; } -RegExpElement* Iteration::clone() { - Iteration* toReturn = new Iteration(); - for (auto element : elements) { - toReturn->getElements().push_back(element->clone()); - } - return toReturn; +void Iteration::setElement(RegExpElement* element) { + this->element = element; +} + +RegExpElement* Iteration::clone() const { + return new Iteration(*this); } } /* namespace regexp */ diff --git a/alib/src/regexp/Iteration.h b/alib/src/regexp/Iteration.h index d07a5dad07c3e69ec41861449c8608698af71cc1..5bb63df0088505f777f2737a8c82bf383fb1efee 100644 --- a/alib/src/regexp/Iteration.h +++ b/alib/src/regexp/Iteration.h @@ -17,14 +17,17 @@ using namespace std; class Iteration : public RegExpElement { private: - list<RegExpElement*> elements; + RegExpElement* element; public: Iteration(); Iteration(const Iteration& other); Iteration& operator = (const Iteration& other); ~Iteration(); - list<RegExpElement*>& getElements(); - RegExpElement* clone(); + + RegExpElement* getElement(); + void setElement(RegExpElement* element); + + RegExpElement* clone() const; }; } /* namespace regexp */ diff --git a/alib/src/regexp/RegExp.cpp b/alib/src/regexp/RegExp.cpp index cdcf4ae055fd812b6e8d64f661371e98df781b5a..92641f64ab2cbd000b06812647a3fa039ced5953 100644 --- a/alib/src/regexp/RegExp.cpp +++ b/alib/src/regexp/RegExp.cpp @@ -13,38 +13,57 @@ namespace regexp { RegExp::RegExp() { + regExp = NULL; } RegExp::RegExp(const RegExp& other) { - for (auto element : other.regexp) { - regexp.push_back(element->clone()); + if (other.regExp != NULL) { + regExp = other.regExp->clone(); + } else { + regExp = NULL; } } -RegExp::RegExp(const list<RegExpElement*>& regexp) : - regexp(regexp) { +RegExp::RegExp(const RegExpElement* regExp) { + if (regExp != NULL) { + this->regExp = regExp->clone(); + } else { + this->regExp = NULL; + } } RegExp& RegExp::operator =(const RegExp& other) { - for (auto element : regexp) { - delete element; + if (this == &other) { + return *this; + } + + if (regExp != NULL) { + delete regExp; } - regexp.clear(); - for (auto element : other.regexp) { - regexp.push_back(element->clone()); + if (other.regExp != NULL) { + regExp = other.regExp->clone(); + } else { + regExp = NULL; } + + return *this; } RegExp::~RegExp() { - for (auto element : regexp) { - delete element; + if (regExp != NULL) { + delete regExp; } - regexp.clear(); + + regExp = NULL; +} + +RegExpElement* RegExp::getRegExp() { + return regExp; } -list<RegExpElement*>& RegExp::getRegExp() { - return regexp; +void RegExp::setRegExp(RegExpElement* regExp) { + this->regExp = regExp; } void RegExp::toXML(ostream& out) { diff --git a/alib/src/regexp/RegExp.h b/alib/src/regexp/RegExp.h index 94e0c433200dae48351d6469e66f94e9e9c8da47..b41a8dfad5b8832700a465778c40b9b0777d0b88 100644 --- a/alib/src/regexp/RegExp.h +++ b/alib/src/regexp/RegExp.h @@ -19,20 +19,18 @@ using namespace std; class RegExp { private: - list<RegExpElement*> regexp; + RegExpElement* regExp; public: RegExp(); - RegExp(const list<RegExpElement*>& regexp) ; + RegExp(const RegExpElement* regExp) ; RegExp(const RegExp& other); RegExp& operator = (const RegExp& other); ~RegExp(); - list<RegExpElement*>& getRegExp(); - - - + RegExpElement* getRegExp(); + void setRegExp(RegExpElement* regExp); void toXML(ostream& out); }; diff --git a/alib/src/regexp/RegExpElement.h b/alib/src/regexp/RegExpElement.h index 225f3ef48a2d19f9f3eddb68d9bc265b39bd6deb..eea9fb5f4da651d14f60daac79c04b6f932c466f 100644 --- a/alib/src/regexp/RegExpElement.h +++ b/alib/src/regexp/RegExpElement.h @@ -15,7 +15,7 @@ using namespace std; class RegExpElement { public: virtual ~RegExpElement(); - virtual RegExpElement* clone() = 0; + virtual RegExpElement* clone() const = 0; }; } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpParser.cpp b/alib/src/regexp/RegExpParser.cpp index 01e380cff2eedbbd4cc190e95e1f42cc46ce283d..24d02f0f52853ac660834956dd0d3296427f93e3 100644 --- a/alib/src/regexp/RegExpParser.cpp +++ b/alib/src/regexp/RegExpParser.cpp @@ -11,49 +11,59 @@ namespace regexp { RegExp RegExpParser::parse(list<Token>& input) { - list<RegExpElement*> elements; + popToken(input, Token::START_ELEMENT, "regexp"); + RegExp regexp; + regexp.setRegExp(parseElement(input)); + popToken(input, Token::END_ELEMENT, "regexp"); - try { - popToken(input, Token::START_ELEMENT, "regexp"); - - parseContent(input, elements); - - popToken(input, Token::END_ELEMENT, "regexp"); - return RegExp(elements); - } catch (ParserException& e) { - for (auto element : elements) { - delete element; - } - throw e; - } + return regexp; } -Iteration* RegExpParser::parseIteration(list<Token>& input) { - popToken(input, Token::START_ELEMENT, "iteration"); - - Iteration* iteration = new Iteration(); - parseContent(input,iteration->getElements()); - - popToken(input, Token::END_ELEMENT, "iteration"); - return iteration; +RegExpElement* RegExpParser::parseElement(list<Token>& input) { + if (isToken(input, Token::START_ELEMENT, "symbol")) { + return parseSymbol(input); + } else if (isToken(input, Token::START_ELEMENT, "iteration")) { + return parseIteration(input); + } else if (isToken(input, Token::START_ELEMENT, "alternation")) { + return parseAlternation(input); + } else if (isToken(input, Token::START_ELEMENT, "concatenation")) { + return parseConcatenation(input); + } else { + return NULL; + } } Alternation* RegExpParser::parseAlternation(list<Token>& input) { popToken(input, Token::START_ELEMENT, "alternation"); Alternation* alternation = new Alternation; - popToken(input, Token::START_ELEMENT, "first"); - parseContent(input, alternation->getFirst()); - popToken(input, Token::END_ELEMENT, "first"); - - popToken(input, Token::START_ELEMENT, "second"); - parseContent(input, alternation->getSecond()); - popToken(input, Token::END_ELEMENT, "second"); + parseContent(input, alternation->getElements()); popToken(input, Token::END_ELEMENT, "alternation"); return alternation; } +Concatenation* RegExpParser::parseConcatenation(list<Token>& input) { + popToken(input, Token::START_ELEMENT, "concatenation"); + + Concatenation* concatenation = new Concatenation(); + parseContent(input, concatenation->getElements()); + + popToken(input, Token::END_ELEMENT, "concatenation"); + return concatenation; + +} + +Iteration* RegExpParser::parseIteration(list<Token>& input) { + popToken(input, Token::START_ELEMENT, "iteration"); + + Iteration* iteration = new Iteration(); + iteration->setElement(parseElement(input)); + + popToken(input, Token::END_ELEMENT, "iteration"); + return iteration; +} + void RegExpParser::parseContent(list<Token>& input, list<RegExpElement*>& elements) { while (true) { if (isToken(input, Token::START_ELEMENT, "symbol")) { @@ -62,6 +72,8 @@ void RegExpParser::parseContent(list<Token>& input, list<RegExpElement*>& elemen elements.push_back(parseIteration(input)); } else if (isToken(input, Token::START_ELEMENT, "alternation")) { elements.push_back(parseAlternation(input)); + } else if (isToken(input, Token::START_ELEMENT, "concatenation")) { + elements.push_back(parseConcatenation(input)); } else { return; } diff --git a/alib/src/regexp/RegExpParser.h b/alib/src/regexp/RegExpParser.h index 3181ca47e98790abeb53e0985ec7721b2cc2f196..7e41a6d6fb04653739336ccdb8124e0ac2b57e7b 100644 --- a/alib/src/regexp/RegExpParser.h +++ b/alib/src/regexp/RegExpParser.h @@ -11,8 +11,10 @@ #include "RegExp.h" #include "../sax/Token.h" #include "RegExpSymbol.h" -#include "Iteration.h" + #include "Alternation.h" +#include "Concatenation.h" +#include "Iteration.h" namespace regexp { @@ -23,9 +25,12 @@ public: static RegExp parse(list<Token>& input); protected: static void parseContent(list<Token>& input, list<RegExpElement*>& elements); + static RegExpElement* parseElement(list<Token>& input); + static RegExpSymbol* parseSymbol(list<Token> &input, string tagName="symbol"); static Iteration* parseIteration(list<Token> &input); static Alternation* parseAlternation(list<Token> &input); + static Concatenation* parseConcatenation(list<Token> &input); static bool isToken(list<Token> &input, Token::TokenType type, string data); static void popToken(list<Token> &input, Token::TokenType type, string data); }; diff --git a/alib/src/regexp/RegExpPrinter.cpp b/alib/src/regexp/RegExpPrinter.cpp index 962df86e679ea1f02dbe4746f78de800264e8ace..b9b5a35b1964987ab37e2b0f57d4d3295de44bc4 100644 --- a/alib/src/regexp/RegExpPrinter.cpp +++ b/alib/src/regexp/RegExpPrinter.cpp @@ -13,51 +13,60 @@ const string RegExpPrinter::INDENTATION = "\t"; void RegExpPrinter::toXML(RegExp& regexp, ostream& out) { out << "<regexp>\n"; - printContent(regexp.getRegExp(), out, INDENTATION); + printElement(regexp.getRegExp(), out, INDENTATION); out << "</regexp>\n"; } +void RegExpPrinter::printElement(RegExpElement* element, ostream& out, string prefix) { + Alternation* alternation = dynamic_cast<Alternation*>(element); + if (alternation) { + printAlternation(alternation, out, prefix); + return; + } + + Concatenation* concatenation = dynamic_cast<Concatenation*>(element); + if(concatenation) { + printConcatenation(concatenation,out, prefix); + return; + } + + Iteration* iteration = dynamic_cast<Iteration*>(element); + if (iteration) { + printIteration(iteration, out, prefix); + return; + } + + RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>(element); + if (symbol) { + printSymbol(symbol, out, prefix); + return; + } + +} + void RegExpPrinter::printContent(list<RegExpElement*>& content, ostream& out, string prefix) { for (auto element : content) { - Alternation* alternation = dynamic_cast<Alternation*>(element); - if (alternation) { - printAlternation(alternation, out, prefix); - continue; - } - - Iteration* iteration = dynamic_cast<Iteration*>(element); - if (iteration) { - printIteration(iteration, out, prefix); - continue; - } - - RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>(element); - if (symbol) { - printSymbol(symbol, out, prefix); - continue; - } + printElement(element, out, prefix); } } void RegExpPrinter::printAlternation(Alternation* alternation, ostream& out, string prefix) { - string doubleIndentation = prefix + INDENTATION + INDENTATION; out << prefix << "<alternation>\n"; + printContent(alternation->getElements(), out, prefix + INDENTATION); + out << prefix << "</alternation>\n"; +} - out << prefix << INDENTATION << "<first>\n"; - printContent(alternation->getFirst(), out, doubleIndentation); - out << prefix << INDENTATION << "</first>\n"; - - out << prefix << INDENTATION << "<second>\n"; - printContent(alternation->getSecond(), out, doubleIndentation); - out << prefix << INDENTATION << "</second>\n"; +void RegExpPrinter::printConcatenation(Concatenation* concatenation, ostream& out, string prefix) { + out << prefix <<"<concatenation>\n"; + printContent(concatenation->getElements(), out, prefix + INDENTATION); + out << prefix <<"</concatenation>\n"; - out << prefix << "</alternation>\n"; } void RegExpPrinter::printIteration(Iteration* iteration, ostream& out, string prefix) { out << prefix << "<iteration>\n"; - printContent(iteration->getElements(), out, prefix + INDENTATION); + printElement(iteration->getElement(), out, prefix + INDENTATION); out << prefix << "</iteration>\n"; } diff --git a/alib/src/regexp/RegExpPrinter.h b/alib/src/regexp/RegExpPrinter.h index e1e39981758cb65a0d5938925d9e4c7d1afbcafc..23b9e447d8a8460bf888b6449d063b6326f87771 100644 --- a/alib/src/regexp/RegExpPrinter.h +++ b/alib/src/regexp/RegExpPrinter.h @@ -11,6 +11,7 @@ #include <ostream> #include "RegExp.h" #include "Alternation.h" +#include "Concatenation.h" #include "Iteration.h" #include "RegExpSymbol.h" @@ -21,8 +22,11 @@ using namespace std; class RegExpPrinter { protected: static const string INDENTATION; + static void printElement(RegExpElement* element, ostream& out, string prefix); static void printContent(list<RegExpElement*>& content, ostream& out, string prefix); static void printAlternation(Alternation* alternation, ostream& out, string prefix); + static void printConcatenation(Concatenation* concatenation, ostream& out, string prefix); + static void printIteration(Iteration* iteration, ostream& out, string prefix); static void printSymbol(RegExpSymbol* symbol, ostream& out, string prefix); diff --git a/alib/src/regexp/RegExpSymbol.cpp b/alib/src/regexp/RegExpSymbol.cpp index ed17cfd453c0c63210be297192163b3a76acc97f..95f5642371bfae32c6b138bb31bc3bff2da28b3c 100644 --- a/alib/src/regexp/RegExpSymbol.cpp +++ b/alib/src/regexp/RegExpSymbol.cpp @@ -17,7 +17,7 @@ RegExpSymbol::RegExpSymbol(const string& symbol) : Symbol(symbol) { } -RegExpElement* RegExpSymbol::clone() { +RegExpElement* RegExpSymbol::clone() const { return new RegExpSymbol(this->symbol); } diff --git a/alib/src/regexp/RegExpSymbol.h b/alib/src/regexp/RegExpSymbol.h index b07319284f31a41862ab24a5d3c522d5b736fce3..bdd10ffeedfb1bad2303158830482fc4667e9c85 100644 --- a/alib/src/regexp/RegExpSymbol.h +++ b/alib/src/regexp/RegExpSymbol.h @@ -21,7 +21,7 @@ class RegExpSymbol: public RegExpElement, public Symbol { public: RegExpSymbol(); RegExpSymbol(const string& symbol); - RegExpElement* clone(); + RegExpElement* clone() const; }; } /* namespace regexp */ diff --git a/examples/regexp/regexp.xml b/examples/regexp/regexp.xml index f1d847322a47edb3d91e7d57cf0be41d538ffa4d..c33f89cb530ed6b70c959ebfd282fcfc9d12f48e 100644 --- a/examples/regexp/regexp.xml +++ b/examples/regexp/regexp.xml @@ -1,17 +1,12 @@ <regexp> - <symbol>0</symbol> - <symbol>1</symbol> - <iteration> + <concatenation> <symbol>0</symbol> - <symbol>0</symbol> - </iteration> - - <alternation> - <first> + <iteration> + <symbol>1</symbol> + </iteration> + <alternation> <symbol>11</symbol> - </first> - <second> <symbol>10</symbol> - </second> - </alternation> + </alternation> + </concatenation> </regexp> diff --git a/examples/regexp/regexp2.xml b/examples/regexp/regexp2.xml index 4da5d19420850eb57976b7b6fc982ce7e5abff42..5f1a2f789679131f73d7d97498958de7cef8a801 100644 --- a/examples/regexp/regexp2.xml +++ b/examples/regexp/regexp2.xml @@ -1,27 +1,21 @@ <regexp> - <symbol>0</symbol> - <symbol>1</symbol> - <iteration> + <concatenation> + <symbol>0</symbol> + <symbol>1</symbol> + <iteration> + <alternation> + <symbol>0</symbol> + <symbol>1</symbol> + </alternation> + </iteration> + <alternation> - <first> - <symbol>0</symbol> - </first> - <second> - <symbol>1</symbol> - </second> + <iteration> + <symbol>11</symbol> + </iteration> + <iteration> + <symbol>10</symbol> + </iteration> </alternation> - </iteration> - - <alternation> - <first> - <iteration> - <symbol>11</symbol> - </iteration> - </first> - <second> - <iteration> - <symbol>10</symbol> - </iteration> - </second> - </alternation> + </concatenation> </regexp> diff --git a/examples/regexp/regexp3.xml b/examples/regexp/regexp3.xml index 7359cb498971420771518bf0a82dfe803a03617f..9bc9b5335b8f1174b3418311488bb7cfcdece86f 100644 --- a/examples/regexp/regexp3.xml +++ b/examples/regexp/regexp3.xml @@ -9,11 +9,13 @@ <iteration> <iteration> <iteration> - <symbol>We</symbol> - <symbol>have</symbol> - <symbol>to</symbol> - <symbol>go</symbol> - <symbol>deeper</symbol> + <concatenation> + <symbol>We</symbol> + <symbol>have</symbol> + <symbol>to</symbol> + <symbol>go</symbol> + <symbol>deeper</symbol> + </concatenation> </iteration> </iteration> </iteration>