From 2f8ac1a22ef12fcca343eb9a3eb35bd282ad7849 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Thu, 17 Apr 2014 15:36:07 +0200
Subject: [PATCH] string internal form

---
 alib2/src/string/String.cpp                 | 49 +++++++++++++++
 alib2/src/string/String.h                   | 67 +++++++++++++++++++++
 alib2/src/string/StringParser.cpp           | 50 +++++++++++++++
 alib2/src/string/StringParser.h             | 40 ++++++++++++
 alib2/src/string/StringToStringComposer.cpp | 55 +++++++++++++++++
 alib2/src/string/StringToStringComposer.h   | 34 +++++++++++
 alib2/src/string/StringToXMLComposer.cpp    | 32 ++++++++++
 alib2/src/string/StringToXMLComposer.h      | 34 +++++++++++
 8 files changed, 361 insertions(+)
 create mode 100644 alib2/src/string/String.cpp
 create mode 100644 alib2/src/string/String.h
 create mode 100644 alib2/src/string/StringParser.cpp
 create mode 100644 alib2/src/string/StringParser.h
 create mode 100644 alib2/src/string/StringToStringComposer.cpp
 create mode 100644 alib2/src/string/StringToStringComposer.h
 create mode 100644 alib2/src/string/StringToXMLComposer.cpp
 create mode 100644 alib2/src/string/StringToXMLComposer.h

diff --git a/alib2/src/string/String.cpp b/alib2/src/string/String.cpp
new file mode 100644
index 0000000000..ef9065f1a8
--- /dev/null
+++ b/alib2/src/string/String.cpp
@@ -0,0 +1,49 @@
+/*
+ * String.cpp
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Jan Travnicek
+ */
+
+#include "String.h"
+
+namespace string {
+
+String::String() {
+
+}
+
+std::set<alphabet::Symbol> String::getAlphabet() const {
+	std::set<alphabet::Symbol> alphabet;
+	for(const alphabet::Symbol& symbol : m_Data) {
+		alphabet.insert(symbol);
+	}
+	return alphabet;
+}
+
+const std::vector<alphabet::Symbol>& String::getContent() const {
+	return this->m_Data;
+}
+
+void String::appendSymbol(alphabet::Symbol&& symbol) {
+	this->m_Data.push_back(std::move(symbol));
+}
+
+void String::appendSymbol(const alphabet::Symbol& symbol) {
+	this->m_Data.push_back(symbol);
+}
+
+bool String::isEmpty() const {
+	return this->m_Data.size() == 0;
+}
+
+std::ostream& operator <<(std::ostream& out, const String& string) {
+	out << "(String ";
+	for(const alphabet::Symbol& symbol : string.m_Data) {
+		out << symbol;
+	}
+	out << ")";
+	return out;
+}
+
+} /* namespace string */
diff --git a/alib2/src/string/String.h b/alib2/src/string/String.h
new file mode 100644
index 0000000000..37ca349ec9
--- /dev/null
+++ b/alib2/src/string/String.h
@@ -0,0 +1,67 @@
+/*
+ * String.h
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef STRING_H_
+#define STRING_H_
+
+#include <iostream>
+#include <set>
+#include <vector>
+
+#include "../std/visitor.hpp"
+#include "../alphabet/Symbol.h"
+
+namespace string {
+
+/**
+ * Represents regular expression parsed from the XML. Regular expression is stored
+ * as a tree of StringElement.
+ */
+class String : public std::element<String, std::visitor<String> > {
+private:
+	std::vector<alphabet::Symbol> m_Data;
+
+public:
+	String();
+
+	/**
+	 * @return the input alphabet
+	 */
+	std::set<alphabet::Symbol> getAlphabet() const;
+
+	/**
+	 * @return List of symbols forming string (const version).
+	 */
+	const std::vector<alphabet::Symbol>& getContent() const;
+	
+	/**
+	 * @param symbol to append
+	 */
+	void appendSymbol(alphabet::Symbol&& symbol);
+	
+	/**
+	 * @param symbol to append
+	 */
+	void appendSymbol(const alphabet::Symbol& symbol);
+
+	/**
+	 * @return true if string is an empty word (vector length is 0)
+	 */
+	bool isEmpty() const;
+
+	/**
+	 * Prints XML representation of the String to the output stream.
+	 * @param out output stream to which print the String
+	 * @param string String to print
+	 */
+	friend std::ostream& operator<<(std::ostream& out, const String& string);
+
+};
+
+} /* namespace string */
+
+#endif /* STRING_H_ */
diff --git a/alib2/src/string/StringParser.cpp b/alib2/src/string/StringParser.cpp
new file mode 100644
index 0000000000..3729312e60
--- /dev/null
+++ b/alib2/src/string/StringParser.cpp
@@ -0,0 +1,50 @@
+/*
+ * StringParser.cpp
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Martin Zak
+ */
+
+#include "StringParser.h"
+#include "../sax/ParserException.h"
+
+namespace string {
+
+String StringParser::parse(std::list<sax::Token>& input) {
+	popToken(input, sax::Token::START_ELEMENT, "string");
+	String string;
+	parseContent(input, string);
+	popToken(input, sax::Token::END_ELEMENT, "string");
+
+	return string;
+}
+
+void StringParser::parseContent(std::list<sax::Token>& input, String& string) {
+	while (isToken(input, sax::Token::START_ELEMENT, "symbol")) {
+		popToken(input, sax::Token::START_ELEMENT, "symbol");
+		
+		if (input.front().getType() == sax::Token::CHARACTER) {
+			alphabet::Symbol symbol(input.front().getData());
+			input.pop_front();
+			string.appendSymbol(symbol);
+		} else {
+			throw sax::ParserException(sax::Token("", sax::Token::CHARACTER), input.front());
+		}
+		
+		popToken(input, sax::Token::END_ELEMENT, "symbol");
+	}
+}
+
+bool StringParser::isToken(std::list<sax::Token>& input, sax::Token::TokenType type, std::string data) {
+	return input.front().getType() == type && input.front().getData() == data;
+}
+
+void StringParser::popToken(std::list<sax::Token>& input, sax::Token::TokenType type, std::string data) {
+	if (isToken(input, type, data)) {
+		input.pop_front();
+	} else {
+		throw sax::ParserException(sax::Token(data, type), input.front());
+	}
+}
+
+} /* namespace regexp */
diff --git a/alib2/src/string/StringParser.h b/alib2/src/string/StringParser.h
new file mode 100644
index 0000000000..fad7bef3e6
--- /dev/null
+++ b/alib2/src/string/StringParser.h
@@ -0,0 +1,40 @@
+/*
+ * StringParser.h
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef STRING_PARSER_H_
+#define STRING_PARSER_H_
+
+#include <list>
+
+#include "String.h"
+#include "../sax/Token.h"
+
+namespace string {
+
+/**
+ * Parser used to get String from XML parsed into list of tokens.
+ */
+class StringParser {
+protected:
+	static void parseContent(std::list<sax::Token>& input, String& content);
+
+	static bool isToken(std::list<sax::Token> &input, sax::Token::TokenType type, std::string data);
+	static void popToken(std::list<sax::Token> &input, sax::Token::TokenType type, std::string data);
+
+public:
+	/**
+	 * Parses the XML and returns regular expression. The input is destroyed in the process.
+	 * @param input XML represented as list of tokens
+	 * @return String
+	 * @throws ParserException when an error occurs
+	 */
+	static String parse(std::list<sax::Token>& input);
+};
+
+} /* namespace string */
+
+#endif /* STRING_PARSER_H_ */
diff --git a/alib2/src/string/StringToStringComposer.cpp b/alib2/src/string/StringToStringComposer.cpp
new file mode 100644
index 0000000000..748f74072b
--- /dev/null
+++ b/alib2/src/string/StringToStringComposer.cpp
@@ -0,0 +1,55 @@
+/*
+ * StringToStringComposer.cpp
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Jan Travnicek
+ */
+
+#include "StringToStringComposer.h"
+#include <algorithm>
+
+namespace string {
+
+void StringToStringComposer::Visit(std::stringstream& out, const alphabet::Symbol& symbol) {
+	auto testEscape = [](char c) { 
+		if(c == '"' || c == '\\' || c == ' ') return true;
+		return false;
+	};
+	
+	auto replace = [](std::string& str, const std::string& what, const std::string& with) {
+		size_t index = 0;
+		while((index = str.find(what, index)) != std::string::npos) {
+			str.replace(index, what.length(), with);
+			index += with.length();
+		}
+	};
+	
+	if( std::any_of(symbol.getSymbol().begin(), symbol.getSymbol().end(), testEscape) ) {
+		std::string tmp = symbol.getSymbol();
+		replace(tmp, "\\", "\\\\" );
+		replace(tmp, "\"", "\\\"" );
+		out << '"' << tmp << '"';
+	} else {
+		out << symbol.getSymbol();
+	}
+}
+
+void StringToStringComposer::Visit(std::stringstream& out, const String& string) {
+	bool first = true;
+	for(const auto& symbol : string.getContent()) {
+		if(first) 
+			first = false;
+		else
+			out << ' ';
+  
+		Visit(out, symbol);
+	}
+}
+
+std::string StringToStringComposer::compose(const String& string) {
+	std::stringstream out;
+	Visit(out, string);
+	return std::move(out).str();
+}
+
+} /* namespace string */
diff --git a/alib2/src/string/StringToStringComposer.h b/alib2/src/string/StringToStringComposer.h
new file mode 100644
index 0000000000..9546072ac7
--- /dev/null
+++ b/alib2/src/string/StringToStringComposer.h
@@ -0,0 +1,34 @@
+/*
+ * StringToStringComposer.h
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Jan Travnciek
+ */
+
+#ifndef STRING_TO_STRING_COMPOSER_H_
+#define STRING_TO_STRING_COMPOSER_H_
+
+#include <sstream>
+#include "String.h"
+#include "../sax/Token.h"
+
+namespace string {
+
+/**
+ * This class contains methods to print XML representation of string to the output stream.
+ */
+class StringToStringComposer {
+	static void Visit(std::stringstream&, const alphabet::Symbol& symbol);
+	static void Visit(std::stringstream&, const String& string);
+public:
+	/**
+	 * Prints XML representation of String to the output stream.
+	 * @param string String to print
+	 * @param out output stream to which print the String
+	 */
+	std::string compose(const String& string);
+};
+
+} /* namespace string */
+
+#endif /* STRING_TO_STRING_COMPOSER_H_ */
diff --git a/alib2/src/string/StringToXMLComposer.cpp b/alib2/src/string/StringToXMLComposer.cpp
new file mode 100644
index 0000000000..c8fbd88dab
--- /dev/null
+++ b/alib2/src/string/StringToXMLComposer.cpp
@@ -0,0 +1,32 @@
+/*
+ * StringToXMLComposer.cpp
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Jan Travnicek
+ */
+
+#include "StringToXMLComposer.h"
+
+namespace string {
+
+void StringToXMLComposer::Visit(std::list<sax::Token>& out, const alphabet::Symbol& symbol) {
+	out.push_back(sax::Token("symbol", sax::Token::START_ELEMENT));
+	out.push_back(sax::Token(symbol.getSymbol(), sax::Token::CHARACTER));
+	out.push_back(sax::Token("symbol", sax::Token::END_ELEMENT));
+}
+
+void StringToXMLComposer::Visit(std::list<sax::Token>& out, const String& string) {
+	out.push_back(sax::Token("string", sax::Token::START_ELEMENT));
+	for(const auto& symbol : string.getContent()) {
+		Visit(out, symbol);
+	}
+	out.push_back(sax::Token("string", sax::Token::END_ELEMENT));
+}
+
+std::list<sax::Token> StringToXMLComposer::compose(const String& string) {
+	std::list<sax::Token> out;
+	Visit(out, string);
+	return out;
+}
+
+} /* namespace string */
diff --git a/alib2/src/string/StringToXMLComposer.h b/alib2/src/string/StringToXMLComposer.h
new file mode 100644
index 0000000000..f95ad267e7
--- /dev/null
+++ b/alib2/src/string/StringToXMLComposer.h
@@ -0,0 +1,34 @@
+/*
+ * StringToXMLComposer.h
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Jan Travnciek
+ */
+
+#ifndef STRING_TO_XML_COMPOSER_H_
+#define STRING_TO_XML_COMPOSER_H_
+
+#include <list>
+#include "String.h"
+#include "../sax/Token.h"
+
+namespace string {
+
+/**
+ * This class contains methods to print XML representation of string to the output stream.
+ */
+class StringToXMLComposer {
+	static void Visit(std::list<sax::Token>&, const alphabet::Symbol& symbol);
+	static void Visit(std::list<sax::Token>&, const String& string);
+public:
+	/**
+	 * Prints XML representation of String to the output stream.
+	 * @param string String to print
+	 * @param out output stream to which print the String
+	 */
+	std::list<sax::Token> compose(const String& string);
+};
+
+} /* namespace string */
+
+#endif /* STRING_TO_XML_COMPOSER_H_ */
-- 
GitLab