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