From 29df0609ae08aecb2f9622cd109d383fa9387af0 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 7 Jul 2014 21:35:17 +0200
Subject: [PATCH] base implementation of Unknown and Unrestricted G

---
 alib2/src/grammar/Grammar.cpp                 |  78 +++++++++++
 alib2/src/grammar/Grammar.h                   |  47 +++++++
 alib2/src/grammar/GrammarBase.cpp             |  78 +++++++++++
 alib2/src/grammar/GrammarBase.h               |  79 +++++++++++
 alib2/src/grammar/GrammarException.cpp        |  23 ++++
 alib2/src/grammar/GrammarException.h          |  27 ++++
 alib2/src/grammar/UnknownGrammar.cpp          |  79 +++++++++++
 alib2/src/grammar/UnknownGrammar.h            |  60 ++++++++
 alib2/src/grammar/UnknownRule.cpp             | 129 ++++++++++++++++++
 alib2/src/grammar/UnknownRule.h               |  73 ++++++++++
 .../Unrestricted/UnrestrictedGrammar.cpp      |  73 ++++++++++
 .../Unrestricted/UnrestrictedGrammar.h        |  40 ++++++
 ...rminalNonterminalAlphabetInitialSymbol.cpp | 108 +++++++++++++++
 ...TerminalNonterminalAlphabetInitialSymbol.h | 106 ++++++++++++++
 14 files changed, 1000 insertions(+)
 create mode 100644 alib2/src/grammar/Grammar.cpp
 create mode 100644 alib2/src/grammar/Grammar.h
 create mode 100644 alib2/src/grammar/GrammarBase.cpp
 create mode 100644 alib2/src/grammar/GrammarBase.h
 create mode 100644 alib2/src/grammar/GrammarException.cpp
 create mode 100644 alib2/src/grammar/GrammarException.h
 create mode 100644 alib2/src/grammar/UnknownGrammar.cpp
 create mode 100644 alib2/src/grammar/UnknownGrammar.h
 create mode 100644 alib2/src/grammar/UnknownRule.cpp
 create mode 100644 alib2/src/grammar/UnknownRule.h
 create mode 100644 alib2/src/grammar/Unrestricted/UnrestrictedGrammar.cpp
 create mode 100644 alib2/src/grammar/Unrestricted/UnrestrictedGrammar.h
 create mode 100644 alib2/src/grammar/common/TerminalNonterminalAlphabetInitialSymbol.cpp
 create mode 100644 alib2/src/grammar/common/TerminalNonterminalAlphabetInitialSymbol.h

diff --git a/alib2/src/grammar/Grammar.cpp b/alib2/src/grammar/Grammar.cpp
new file mode 100644
index 0000000000..fc0fc1ad5a
--- /dev/null
+++ b/alib2/src/grammar/Grammar.cpp
@@ -0,0 +1,78 @@
+/*
+ * Grammar.cpp
+ *
+ *  Created on: Apr 16, 2013
+ *      Author: Martin Zak
+ */
+
+#include "Grammar.h"
+
+namespace grammar {
+
+Grammar::Grammar(const GrammarBase& grammar) : grammar(grammar.clone()) {
+
+}
+
+Grammar::Grammar(GrammarBase&& grammar) : grammar(std::move(grammar).plunder()) {
+
+}
+
+Grammar::Grammar(const Grammar& other) : grammar(other.getGrammar().clone()) {
+
+}
+
+Grammar::Grammar(Grammar&& other) noexcept : grammar(std::move(other.getGrammar()).plunder()) {
+	other.grammar = NULL;
+}
+
+Grammar& Grammar::operator=(const Grammar& other) {
+	if(this == &other) return *this;
+
+	delete grammar;
+	grammar = other.getGrammar().clone();
+
+	return *this;
+}
+
+Grammar& Grammar::operator=(Grammar&& other) noexcept {
+	std::swap(this->grammar, other.grammar);
+	return *this;
+}
+
+Grammar::~Grammar() {
+	delete grammar;
+}
+
+const GrammarBase& Grammar::getGrammar() const {
+	return *grammar;
+}
+
+GrammarBase& Grammar::getGrammar() {
+	return *grammar;
+}
+
+void Grammar::setGrammar(const GrammarBase& grammar) {
+	delete this->grammar;
+	this->grammar = grammar.clone();
+}
+
+void Grammar::setGrammar(GrammarBase&& grammar) {
+	delete this->grammar;
+	this->grammar = std::move(grammar).plunder();
+}
+
+bool Grammar::operator!=(const Grammar& other) const {
+	return !(*this == other);
+}
+
+bool Grammar::operator==(const Grammar& other) const {
+	return this->getGrammar() == other.getGrammar();
+}
+
+std::ostream& operator<<(std::ostream& os, const Grammar& grammar) {
+	os << grammar.getGrammar();
+	return os;
+}
+
+} /* namespace grammar */
+
diff --git a/alib2/src/grammar/Grammar.h b/alib2/src/grammar/Grammar.h
new file mode 100644
index 0000000000..95ffefe2bd
--- /dev/null
+++ b/alib2/src/grammar/Grammar.h
@@ -0,0 +1,47 @@
+/*
+ * Grammar.h
+ *
+ *  Created on: Apr 10, 2013
+ *      Author: Martin Zak
+ */
+
+#ifndef GRAMMAR_H_
+#define GRAMMAR_H_
+
+#include "../std/visitor.hpp"
+#include "GrammarBase.h"
+
+namespace grammar {
+
+/**
+ * Wrapper around automata.
+ */
+class Grammar {
+protected:
+	GrammarBase* grammar;
+public:
+	explicit Grammar(const GrammarBase& grammar);
+	explicit Grammar(GrammarBase&& grammar);
+	Grammar(const Grammar& other);
+	Grammar(Grammar&&) noexcept;
+	Grammar& operator=(const Grammar& other);
+	Grammar& operator=(Grammar&& other) noexcept;
+	virtual ~Grammar() noexcept;
+
+	const GrammarBase& getGrammar() const;
+	GrammarBase& getGrammar();
+
+	void setGrammar(const GrammarBase& grammar);
+	void setGrammar(GrammarBase&& grammar);
+	
+	bool operator!=(const Grammar& other) const;
+
+	bool operator==(const Grammar& other) const;
+
+	friend std::ostream& operator<<(std::ostream& os, const Grammar& grammar);
+};
+
+} /* namespace grammar */
+
+#endif /* GRAMMAR_H_ */
+
diff --git a/alib2/src/grammar/GrammarBase.cpp b/alib2/src/grammar/GrammarBase.cpp
new file mode 100644
index 0000000000..cda2451564
--- /dev/null
+++ b/alib2/src/grammar/GrammarBase.cpp
@@ -0,0 +1,78 @@
+/*
+ * GrammarBase.cpp
+ *
+ *  Created on: Apr 16, 2013
+ *      Author: Jan Travnicek
+ */
+
+#include "GrammarBase.h"
+
+namespace grammar {
+
+GrammarBase::~GrammarBase() {
+
+}
+
+bool GrammarBase::operator!=(const GrammarBase& other) const {
+	return !(*this == other);
+}
+
+bool GrammarBase::operator==(const UnknownGrammar&) const {
+	return false;
+}
+
+bool GrammarBase::operator==(const LeftLG&) const {
+	return false;
+}
+
+bool GrammarBase::operator==(const LeftRG&) const {
+	return false;
+}
+
+bool GrammarBase::operator==(const RightLG&) const{
+	return false;
+}
+
+bool GrammarBase::operator==(const RightRG&) const{
+	return false;
+}
+
+bool GrammarBase::operator==(const LG&) const {
+	return false;
+}
+
+bool GrammarBase::operator==(const CFG&) const {
+	return false;
+}
+
+bool GrammarBase::operator==(const EpsilonFreeCFG&) const {
+	return false;
+}
+
+bool GrammarBase::operator==(const CNF&) const {
+	return false;
+}
+
+bool GrammarBase::operator==(const GNF&) const {
+	return false;
+}
+
+bool GrammarBase::operator==(const CSG&) const {
+	return false;
+}
+
+bool GrammarBase::operator==(const NonContractingGrammar&) const {
+	return false;
+}
+
+bool GrammarBase::operator==(const UnrestrictedGrammar&) const {
+	return false;
+}
+
+std::ostream& operator<<(std::ostream& os, const GrammarBase& grammar) {
+	grammar >> os;
+	return os;
+}
+
+} /* namespace grammar */
+
diff --git a/alib2/src/grammar/GrammarBase.h b/alib2/src/grammar/GrammarBase.h
new file mode 100644
index 0000000000..21bc658c6f
--- /dev/null
+++ b/alib2/src/grammar/GrammarBase.h
@@ -0,0 +1,79 @@
+/*
+ * GrammarBase.h
+ *
+ *  Created on: Apr 10, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef GRAMMAR_BASE_H_
+#define GRAMMAR_BASE_H_
+
+#include "../std/visitor.hpp"
+#include <iostream>
+
+namespace grammar {
+
+class UnknownGrammar;
+class LeftLG;
+class LeftRG;
+class RightLG;
+class RightRG;
+class LG;
+class CFG;
+class EpsilonFreeCFG;
+class CNF;
+class GNF;
+class CSG;
+class NonContractingGrammar;
+class UnrestrictedGrammar;
+
+/**
+ * Abstract base class for all automata.
+ */
+class GrammarBase : public std::elementBase<UnknownGrammar, LeftLG, LeftRG, RightLG, RightRG, LG, CFG, EpsilonFreeCFG, CNF, GNF, CSG, NonContractingGrammar, UnrestrictedGrammar> {
+public:
+	virtual GrammarBase* clone() const = 0;
+
+	virtual GrammarBase* plunder() && = 0;
+
+	virtual ~GrammarBase() noexcept;
+
+	virtual bool operator!=(const GrammarBase& other) const;
+
+	virtual bool operator==(const UnknownGrammar& other) const;
+
+	virtual bool operator==(const LeftLG& other) const;
+
+	virtual bool operator==(const LeftRG& other) const;
+
+	virtual bool operator==(const RightLG& other) const;
+
+	virtual bool operator==(const RightRG& other) const;
+
+	virtual bool operator==(const LG& other) const;
+
+	virtual bool operator==(const CFG& other) const;
+
+	virtual bool operator==(const EpsilonFreeCFG& other) const;
+
+	virtual bool operator==(const CNF& other) const;
+	
+	virtual bool operator==(const GNF& other) const;
+	
+	virtual bool operator==(const CSG& other) const;
+	
+	virtual bool operator==(const NonContractingGrammar& other) const;
+	
+	virtual bool operator==(const UnrestrictedGrammar& other) const;
+
+	virtual bool operator==(const GrammarBase& other) const = 0;
+
+	friend std::ostream& operator<<(std::ostream& os, const GrammarBase& grammar);
+
+	virtual void operator>>(std::ostream&) const = 0;
+};
+
+} /* namespace grammar */
+
+#endif /* GRAMMAR_BASE_H_ */
+
diff --git a/alib2/src/grammar/GrammarException.cpp b/alib2/src/grammar/GrammarException.cpp
new file mode 100644
index 0000000000..3f139de0de
--- /dev/null
+++ b/alib2/src/grammar/GrammarException.cpp
@@ -0,0 +1,23 @@
+/*
+ * GrammarException.cpp
+ *
+ *  Created on: Apr 1, 2013
+ *      Author: Martin Zak
+ */
+
+#include "GrammarException.h"
+
+namespace grammar {
+
+GrammarException::GrammarException() {
+}
+
+GrammarException::GrammarException(const std::string& cause) :
+		AlibException(cause) {
+}
+
+GrammarException::~GrammarException() throw () {
+
+}
+
+} /* namespace grammar */
diff --git a/alib2/src/grammar/GrammarException.h b/alib2/src/grammar/GrammarException.h
new file mode 100644
index 0000000000..6977f57a56
--- /dev/null
+++ b/alib2/src/grammar/GrammarException.h
@@ -0,0 +1,27 @@
+/*
+ * GrammarException.h
+ *
+ *  Created on: Apr 1, 2013
+ *      Author: Martin Zak
+ */
+
+#ifndef GRAMMAR_EXCEPTION_H_
+#define GRAMMAR_EXCEPTION_H_
+
+#include "../exception/AlibException.h"
+
+namespace grammar {
+
+/**
+ * Exception thrown by an grammar, grammar parser or grammar printer.
+ */
+class GrammarException: public exception::AlibException {
+public:
+	GrammarException();
+	explicit GrammarException(const std::string& cause);
+	virtual ~GrammarException() throw ();
+};
+
+} /* namespace grammar */
+
+#endif /* GRAMMAR_EXCEPTION_H_ */
diff --git a/alib2/src/grammar/UnknownGrammar.cpp b/alib2/src/grammar/UnknownGrammar.cpp
new file mode 100644
index 0000000000..bf6d93da60
--- /dev/null
+++ b/alib2/src/grammar/UnknownGrammar.cpp
@@ -0,0 +1,79 @@
+/*
+ * UnknownGrammar.cpp
+ *
+ *  Created on: Nov 2, 2013
+ *      Author: Martin Zak
+ */
+
+#include "UnknownGrammar.h"
+#include "GrammarException.h"
+
+namespace grammar {
+
+UnknownGrammar::UnknownGrammar() : initialSymbol(NULL) {
+
+}
+
+bool UnknownGrammar::addTerminalSymbol(const alphabet::Symbol& symbol) {
+	return terminalAlphabet.insert(symbol).second;
+}
+
+bool UnknownGrammar::removeTerminalSymbol(const alphabet::Symbol& symbol) {
+	return terminalAlphabet.insert(symbol).second;
+}
+
+const std::set<alphabet::Symbol>& UnknownGrammar::getTerminalAlphabet() const {
+	return terminalAlphabet;
+}
+
+void UnknownGrammar::setTerminalAlphabet(std::set<alphabet::Symbol>& alphabet) {
+	terminalAlphabet = alphabet;
+}
+
+bool UnknownGrammar::addNonterminalSymbol(const alphabet::Symbol& symbol) {
+	return nonterminalAlphabet.insert(symbol).second;
+}
+
+bool UnknownGrammar::removeNonterminalSymbol(const alphabet::Symbol& symbol) {
+	return nonterminalAlphabet.insert(symbol).second;
+}
+
+const std::set<alphabet::Symbol>& UnknownGrammar::getNonterminalAlphabet() const {
+	return nonterminalAlphabet;
+}
+
+void UnknownGrammar::setNonterminalAlphabet(std::set<alphabet::Symbol>& alphabet) {
+	nonterminalAlphabet = alphabet;
+}
+
+void UnknownGrammar::setInitialSymbol(const alphabet::Symbol& symbol) {
+	delete initialSymbol;
+	initialSymbol = new alphabet::Symbol(symbol);
+}
+
+bool UnknownGrammar::hasInitialSymbol() const {
+	return initialSymbol != NULL;
+}
+
+void UnknownGrammar::clearInitialSymbol() {
+	delete initialSymbol;
+	initialSymbol = NULL;
+}
+
+const alphabet::Symbol& UnknownGrammar::getInitialSymbol() const {
+	return *initialSymbol;
+}
+
+int UnknownGrammar::addRule(const UnknownRule& rule) {
+	return rules.insert(rule).second;
+}
+
+int UnknownGrammar::removeRule(const UnknownRule& rule) {
+	return rules.erase(rule);
+}
+
+const std::set<UnknownRule>& UnknownGrammar::getRules() const {
+	return rules;
+}
+
+} /* namespace grammar */
diff --git a/alib2/src/grammar/UnknownGrammar.h b/alib2/src/grammar/UnknownGrammar.h
new file mode 100644
index 0000000000..39efacd1d2
--- /dev/null
+++ b/alib2/src/grammar/UnknownGrammar.h
@@ -0,0 +1,60 @@
+/*
+ * UnknownGrammar.h
+ *
+ *  Created on: Nov 3, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef UNKNOWN_GRAMMAR_H_
+#define UNKNOWN_GRAMMAR_H_
+
+#include "UnknownRule.h"
+#include <set>
+
+namespace grammar {
+
+/**
+ * Class representing unknown grammar which was parsed from the XML.
+ */
+class UnknownGrammar {
+	std::set<alphabet::Symbol> terminalAlphabet;
+	std::set<alphabet::Symbol> nonterminalAlphabet;
+	std::set<UnknownRule> rules;
+	alphabet::Symbol* initialSymbol;
+protected:
+	UnknownGrammar();
+
+	bool addTerminalSymbol(const alphabet::Symbol& symbol);
+
+	bool removeTerminalSymbol(const alphabet::Symbol& symbol);
+
+	const std::set<alphabet::Symbol>& getTerminalAlphabet() const;
+
+	void setTerminalAlphabet(std::set<alphabet::Symbol>& alphabet);
+
+	bool addNonterminalSymbol(const alphabet::Symbol& symbol);
+
+	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
+
+	const std::set<alphabet::Symbol>& getNonterminalAlphabet() const;
+
+	void setNonterminalAlphabet(std::set<alphabet::Symbol>& alphabet);
+
+	void setInitialSymbol(const alphabet::Symbol& symbol);
+
+	bool hasInitialSymbol() const;
+
+	void clearInitialSymbol();
+
+	const alphabet::Symbol& getInitialSymbol() const;
+
+	int addRule(const UnknownRule& rule);
+
+	int removeRule(const UnknownRule& rule);
+
+	const std::set<UnknownRule>& getRules() const;
+
+};
+
+} /* namespace grammar */
+#endif /* UNKNOWN_GRAMMAR_H_ */
diff --git a/alib2/src/grammar/UnknownRule.cpp b/alib2/src/grammar/UnknownRule.cpp
new file mode 100644
index 0000000000..ac68c99fe1
--- /dev/null
+++ b/alib2/src/grammar/UnknownRule.cpp
@@ -0,0 +1,129 @@
+/*
+ * UnknownRule.cpp
+ *
+ *  Created on: Nov 2, 2013
+ *      Author: Martin Zak
+ */
+
+#include "UnknownRule.h"
+#include <algorithm>
+
+namespace grammar {
+
+UnknownRule::UnknownRule() {
+}
+
+UnknownRule::UnknownRule(const list<Symbol>& leftSide, const list<Symbol>& rightSide) :
+		leftSide(leftSide), rightSide(rightSide) {
+}
+
+void grammar::UnknownRule::setLeftSide(const list<Symbol>& leftSide) {
+	this->leftSide = leftSide;
+}
+
+void grammar::UnknownRule::setRightSide(const list<Symbol>& rightSide) {
+	this->rightSide = rightSide;
+}
+
+const list<Symbol>& grammar::UnknownRule::getLeftSide() const {
+	return leftSide;
+}
+
+const list<Symbol>& grammar::UnknownRule::getRightSide() const {
+	return rightSide;
+}
+
+bool UnknownRule::containsSymbol(const Symbol& symbol) const {
+	if (find(leftSide.begin(), leftSide.end(), symbol) != leftSide.end()) {
+		return true;
+	}
+
+	if (find(rightSide.begin(), rightSide.end(), symbol) != rightSide.end()) {
+		return true;
+	}
+
+	return false;
+}
+
+string UnknownRule::toString() const {
+	string output;
+	output += "[";
+	for(auto const& symbol : leftSide) {
+		output += " " + (std::string) symbol.getSymbol();
+	}
+	output += " -> ";
+	for(auto const& symbol : rightSide) {
+		output += " " + (std::string) symbol.getSymbol();
+	}
+
+	output += "]";
+	return output;
+}
+
+bool UnknownRule::operator <(const UnknownRule& other) const {
+	if (leftSide.size() != other.leftSide.size()) {
+		return leftSide.size() < other.leftSide.size();
+	}
+
+	if (rightSide.size() != other.rightSide.size()) {
+		return rightSide.size() < other.rightSide.size();
+	}
+
+	list<Symbol>::const_iterator left = leftSide.begin();
+	list<Symbol>::const_iterator otherLeft = other.leftSide.begin();
+	while (left != leftSide.end()) {
+		if (*left != *otherLeft) {
+			return *left < *otherLeft;
+		}
+		left++;
+		otherLeft++;
+	}
+
+	list<Symbol>::const_iterator right = rightSide.begin();
+	list<Symbol>::const_iterator otherRight = other.rightSide.begin();
+	while (right != rightSide.end()) {
+		if (*right != *otherRight) {
+			return *right < *otherRight;
+		}
+		right++;
+		otherRight++;
+	}
+
+	return false;
+}
+
+bool UnknownRule::operator ==(const UnknownRule& other) const {
+	return equal(leftSide.begin(), leftSide.end(), other.leftSide.begin())
+			&& equal(rightSide.begin(), rightSide.end(), other.rightSide.begin());
+}
+
+bool UnknownRule::operator !=(const UnknownRule& other) const {
+	return !equal(leftSide.begin(), leftSide.end(), other.leftSide.begin())
+			|| !equal(rightSide.begin(), rightSide.end(), other.rightSide.begin());
+}
+
+ostream& operator<<(ostream& out, const UnknownRule& rule) {
+	bool first;
+	out << " leftSide = [";
+
+	first = true;
+	for(list<Symbol>::const_iterator iter = rule.leftSide.begin(); iter != rule.leftSide.end(); iter++) {
+		if(!first) out << ", ";
+		first = false;
+		out << *iter;
+	}
+
+	out << "] rightSide = [";
+
+	first = true;
+	for(list<Symbol>::const_iterator iter = rule.rightSide.begin(); iter != rule.rightSide.end(); iter++) {
+		if(!first) out << ", ";
+		first = false;
+		out << *iter;
+	}
+	out << "]";
+
+	return out;
+}
+
+} /* namespace grammar */
diff --git a/alib2/src/grammar/UnknownRule.h b/alib2/src/grammar/UnknownRule.h
new file mode 100644
index 0000000000..86c5185319
--- /dev/null
+++ b/alib2/src/grammar/UnknownRule.h
@@ -0,0 +1,73 @@
+/*
+ * UnknownRule.h
+ *
+ *  Created on: Nov 2, 2013
+ *      Author: Martin Zak
+ */
+
+#ifndef UNKNOWN_RULE_H_
+#define UNKNOWN_RULE_H_
+
+#include <list>
+#include "../alphabet/Symbol.h"
+
+namespace grammar {
+
+using namespace std;
+using namespace alphabet;
+
+/**
+ * Represents rewrite rule (production) of a Grammar.
+ */
+class UnknownRule {
+private:
+	list<Symbol> leftSide;
+	list<Symbol> rightSide;
+public:
+	UnknownRule();
+	UnknownRule(const list<Symbol>& leftSide, const list<Symbol>& rightSide);
+
+	/**
+	 * Sets left side of the rule.
+	 * @param leftSide list of symbols to set
+	 */
+	void setLeftSide(const list<Symbol>& leftSide);
+
+	/**
+	 * Sets right side of the rule.
+	 * @param rightSide list of symbols to set
+	 */
+	void setRightSide(const list<Symbol>& rightSide);
+
+	/**
+	 * @return list of symbols on the left side of the UnknownRule
+	 */
+	const list<Symbol>& getLeftSide() const;
+
+	/**
+	 * @return list of symbols on the right side of the UnknownRule
+	 */
+	const list<Symbol>& getRightSide() const;
+
+	/**
+	 * Checks that UnknownRule contains given symbol.
+	 * @param symbol Symbol to find
+	 * @return true when UnknownRule contains the symbol, false otherwise
+	 */
+	bool containsSymbol(const Symbol& symbol) const;
+
+	/**
+	 * Converts rule into human readable string.
+	 * @return string in format [ leftSide -> rightSide ]
+	 */
+	string toString() const;
+
+	bool operator <(const UnknownRule& other) const;
+	bool operator ==(const UnknownRule& other) const;
+	bool operator !=(const UnknownRule& other) const;
+
+	friend ostream& operator<<(ostream&, const UnknownRule&);
+};
+
+} /* namespace grammar */
+#endif /* UNKNOWN_RULE_H_ */
diff --git a/alib2/src/grammar/Unrestricted/UnrestrictedGrammar.cpp b/alib2/src/grammar/Unrestricted/UnrestrictedGrammar.cpp
new file mode 100644
index 0000000000..a68e7a1cd7
--- /dev/null
+++ b/alib2/src/grammar/Unrestricted/UnrestrictedGrammar.cpp
@@ -0,0 +1,73 @@
+/*
+ * UnrestrictedGrammar.cpp
+ *
+ *  Created on: Nov 17, 2013
+ *      Author: martin
+ */
+
+#include "UnrestrictedGrammar.h"
+#include "../GrammarException.h"
+#include <algorithm>
+
+namespace grammar {
+
+UnrestrictedGrammar::UnrestrictedGrammar(const alphabet::Symbol& initialSymbol) : TerminalNonterminalAlphabetInitialSymbol(initialSymbol) {
+
+}
+
+UnrestrictedGrammar::UnrestrictedGrammar(const std::set<alphabet::Symbol>& nonterminalAlphabet, const std::set<alphabet::Symbol>& terminalAlphabet, const alphabet::Symbol& initialSymbol) : TerminalNonterminalAlphabetInitialSymbol(initialSymbol) {
+	setNonterminalAlphabet(nonterminalAlphabet);
+	setTerminalAlphabet(terminalAlphabet);
+}
+
+bool UnrestrictedGrammar::removeTerminalSymbol(const alphabet::Symbol& symbol) {
+	for(const std::pair<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>>& rule : rules) {
+		if(std::find(rule.first.begin(), rule.first.end(), symbol) != rule.first.end())
+			throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is used in rule.");
+
+		for(const std::vector<alphabet::Symbol>& rhs : rule.second)
+			if(std::find(rhs.begin(), rhs.end(), symbol) != rhs.end())
+				throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is used in rule.");
+	}
+
+	return terminalAlphabet.erase(symbol);
+}
+
+bool UnrestrictedGrammar::removeNonterminalSymbol(const alphabet::Symbol& symbol) {
+	for(const std::pair<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>>& rule : rules) {
+		if(std::find(rule.first.begin(), rule.first.end(), symbol) != rule.first.end())
+			throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is used in rule.");
+
+		for(const std::vector<alphabet::Symbol>& rhs : rule.second)
+			if(std::find(rhs.begin(), rhs.end(), symbol) != rhs.end())
+				throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is used in rule.");
+	}
+
+	if(initialSymbol == symbol)
+		throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is initial symbol.");
+
+
+	return nonterminalAlphabet.erase(symbol);
+}
+
+bool UnrestrictedGrammar::addRule(const std::vector<alphabet::Symbol>& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	for(const alphabet::Symbol& symbol : leftHandSide)
+		if(terminalAlphabet.find(symbol) == terminalAlphabet.end() && nonterminalAlphabet.find(symbol) == nonterminalAlphabet.end())
+			throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is not neither terminal nor nonterminal symbol");
+
+	for(const alphabet::Symbol& symbol : rightHandSide)
+		if(terminalAlphabet.find(symbol) == terminalAlphabet.end() && nonterminalAlphabet.find(symbol) == nonterminalAlphabet.end())
+			throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is not neither terminal nor nonterminal symbol");
+
+	return rules[leftHandSide].insert(rightHandSide).second;
+}
+
+const std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> UnrestrictedGrammar::getRules() const {
+	return rules;
+}
+
+bool UnrestrictedGrammar::removeRule(const std::vector<alphabet::Symbol>& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
+	return rules[leftHandSide].erase(rightHandSide);
+}
+
+} /* namespace grammar */
diff --git a/alib2/src/grammar/Unrestricted/UnrestrictedGrammar.h b/alib2/src/grammar/Unrestricted/UnrestrictedGrammar.h
new file mode 100644
index 0000000000..f49188ce01
--- /dev/null
+++ b/alib2/src/grammar/Unrestricted/UnrestrictedGrammar.h
@@ -0,0 +1,40 @@
+/*
+ * UnrestrictedGrammar.h
+ *
+ *  Created on: Nov 17, 2013
+ *      Author: martin
+ */
+
+#ifndef UNRESTRICTED_GRAMMAR_H_
+#define UNRESTRICTED_GRAMMAR_H_
+
+#include "../common/TerminalNonterminalAlphabetInitialSymbol.h"
+#include <map>
+
+namespace grammar {
+
+/**
+ * Unrestricted grammar. Type 0 in Chomsky hierarchy. Produces recursively enumerable language.
+ */
+class UnrestrictedGrammar: public TerminalNonterminalAlphabetInitialSymbol {
+	std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> rules;
+
+public:
+	UnrestrictedGrammar(const alphabet::Symbol& initialSymbol);
+
+	UnrestrictedGrammar(const std::set<alphabet::Symbol>& nonTerminalSymbols, const std::set<alphabet::Symbol>& terminalSymbols, const alphabet::Symbol& initialSymbol);
+
+	bool addRule(const std::vector<alphabet::Symbol>& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
+	const std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> getRules() const;
+
+	bool removeRule(const std::vector<alphabet::Symbol>& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
+
+	bool removeTerminalSymbol(const alphabet::Symbol& symbol);
+
+	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
+};
+
+} /* namespace grammar */
+
+#endif /* UNRESTRICTED_GRAMMAR_H_ */
diff --git a/alib2/src/grammar/common/TerminalNonterminalAlphabetInitialSymbol.cpp b/alib2/src/grammar/common/TerminalNonterminalAlphabetInitialSymbol.cpp
new file mode 100644
index 0000000000..25a72e8f28
--- /dev/null
+++ b/alib2/src/grammar/common/TerminalNonterminalAlphabetInitialSymbol.cpp
@@ -0,0 +1,108 @@
+/*
+ * TerminalNonterminalAlphabetAlphabetInitialSymbol.cpp
+ *
+ *  Created on: Nov 2, 2013
+ *      Author: Martin Zak
+ */
+
+#include "TerminalNonterminalAlphabetInitialSymbol.h"
+#include "../GrammarException.h"
+#include "../../alphabet/LabeledSymbol.h"
+#include "../../label/Label.h"
+#include "../../label/NextLabel.h"
+#include "../../alphabet/LabeledSymbol.h"
+#include <limits.h>
+
+namespace grammar {
+
+TerminalNonterminalAlphabetInitialSymbol::TerminalNonterminalAlphabetInitialSymbol(const alphabet::Symbol& initialSymbol) : initialSymbol(initialSymbol) {
+	addTerminalSymbol(initialSymbol);
+}
+
+bool TerminalNonterminalAlphabetInitialSymbol::addTerminalSymbol(const alphabet::Symbol& symbol) {
+	if(nonterminalAlphabet.find(symbol) != nonterminalAlphabet.end()){
+		throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is nonterminal symbol.");
+	}
+
+	return terminalAlphabet.insert(symbol).second;
+}
+
+const std::set<alphabet::Symbol>& TerminalNonterminalAlphabetInitialSymbol::getTerminalAlphabet() const {
+	return terminalAlphabet;
+}
+
+void TerminalNonterminalAlphabetInitialSymbol::setTerminalAlphabet(const std::set<alphabet::Symbol>& alphabet) {
+	std::set<alphabet::Symbol> removed;
+	std::set_difference(terminalAlphabet.begin(), terminalAlphabet.end(), alphabet.begin(), alphabet.end(), std::inserter(removed, removed.end()));
+
+	std::set<alphabet::Symbol> added;
+	std::set_difference(alphabet.begin(), alphabet.end(), terminalAlphabet.begin(), terminalAlphabet.end(), std::inserter(added, added.end()));
+	
+	for(const alphabet::Symbol& removedSymbol : removed) {
+		removeTerminalSymbol(removedSymbol);
+	}
+
+	for(const alphabet::Symbol& addedSymbol : added) {
+		addTerminalSymbol(addedSymbol);
+	}
+}
+
+bool TerminalNonterminalAlphabetInitialSymbol::addNonterminalSymbol(const alphabet::Symbol& symbol) {
+	if(terminalAlphabet.find(symbol) != terminalAlphabet.end()){
+		throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is terminal symbol.");
+	}
+
+	return nonterminalAlphabet.insert(symbol).second;
+}
+
+const std::set<alphabet::Symbol>& TerminalNonterminalAlphabetInitialSymbol::getNonterminalAlphabet() const {
+	return nonterminalAlphabet;
+}
+
+void TerminalNonterminalAlphabetInitialSymbol::setNonterminalAlphabet(const std::set<alphabet::Symbol>& alphabet) {
+	std::set<alphabet::Symbol> removed;
+	std::set_difference(nonterminalAlphabet.begin(), nonterminalAlphabet.end(), alphabet.begin(), alphabet.end(), std::inserter(removed, removed.end()));
+
+	std::set<alphabet::Symbol> added;
+	std::set_difference(alphabet.begin(), alphabet.end(), nonterminalAlphabet.begin(), nonterminalAlphabet.end(), std::inserter(added, added.end()));
+	
+	for(const alphabet::Symbol& removedSymbol : removed) {
+		removeNonterminalSymbol(removedSymbol);
+	}
+
+	for(const alphabet::Symbol& addedSymbol : added) {
+		addNonterminalSymbol(addedSymbol);
+	}
+}
+
+const alphabet::Symbol& TerminalNonterminalAlphabetInitialSymbol::getInitialSymbol() const{
+	return initialSymbol;
+}
+
+void TerminalNonterminalAlphabetInitialSymbol::setInitialSymbol(const alphabet::Symbol& symbol) {
+	if(nonterminalAlphabet.find(symbol) == nonterminalAlphabet.end()) {
+		throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" isn't nonterminal symbol.");
+	}
+
+	initialSymbol = symbol;
+}
+
+alphabet::Symbol TerminalNonterminalAlphabetInitialSymbol::createUniqueSymbol(const alphabet::Symbol& base, const std::set<alphabet::Symbol>& terminalAlphabet, const std::set<alphabet::Symbol>& nonterminalAlphabet) {
+	label::NextLabel nextLabelCreator;
+
+	const alphabet::LabeledSymbol* baseSymbol = dynamic_cast<const alphabet::LabeledSymbol*>(&(base.getSymbol()));
+	if(baseSymbol == NULL)
+		throw GrammarException("Could not create unique symbol with nonlabeled base symbol " + (std::string) base.getSymbol() + "." );
+
+	int i = 0;
+	do {
+		label::Label nextLabel = nextLabelCreator.nextLabel(baseSymbol->getLabel());
+		alphabet::Symbol attempt = alphabet::Symbol(alphabet::LabeledSymbol(nextLabel));
+		if(terminalAlphabet.count(attempt) == 0 && nonterminalAlphabet.count(attempt) == 0)
+			return attempt;
+	} while(++i < INT_MAX);
+
+	throw GrammarException("Could not create unique symbol with base symbol " + (std::string) base.getSymbol() + "." );
+}
+
+} /* namespace grammar */
diff --git a/alib2/src/grammar/common/TerminalNonterminalAlphabetInitialSymbol.h b/alib2/src/grammar/common/TerminalNonterminalAlphabetInitialSymbol.h
new file mode 100644
index 0000000000..0f2372501e
--- /dev/null
+++ b/alib2/src/grammar/common/TerminalNonterminalAlphabetInitialSymbol.h
@@ -0,0 +1,106 @@
+/*
+ * TerminalNonterminalAlphabetInitialSymbol.h
+ *
+ *  Created on: Nov 2, 2013
+ *      Author: Martin Zak
+ */
+
+#ifndef TERMINAL_NONTERMINAL_ALPHABET_INITIAL_SYMBOL_H_
+#define TERMINAL_NONTERMINAL_ALPHABET_INITIAL_SYMBOL_H_
+
+#include <set>
+#include <list>
+#include <algorithm>
+
+#include "../../alphabet/Symbol.h"
+
+namespace grammar {
+
+/**
+ * Abstract class representing grammar. Implements methods for manipulation
+ * with terminal and nonterminal symbols. Only method, which is not implemented
+ * is grammar specific isValidRule.
+ */
+class TerminalNonterminalAlphabetInitialSymbol {
+protected:
+	std::set<alphabet::Symbol> terminalAlphabet;
+	std::set<alphabet::Symbol> nonterminalAlphabet;
+	alphabet::Symbol initialSymbol;
+
+public:
+	TerminalNonterminalAlphabetInitialSymbol(const alphabet::Symbol& initialSymbol);
+
+	/**
+	 * Adds terminal symbol to the terminal alphabet.
+	 * @param symbol Symbol to add
+	 * @throws GrammarException when symbol is already a nonterminal symbol
+	 */
+	bool addTerminalSymbol(const alphabet::Symbol& symbol);
+
+	/**
+	 * Removes terminal symbol from the terminal alphabet.
+	 * @param symbol Symbol to remove
+	 * @throws GrammarException when symbol is used in rule
+	 */
+	virtual bool removeTerminalSymbol(const alphabet::Symbol& symbol) = 0;
+
+	/**
+	 * return set of terminal symbols
+	 */
+	const std::set<alphabet::Symbol>& getTerminalAlphabet() const;
+
+	/**
+	 * Sets the terminal alphabet
+	 */
+	void setTerminalAlphabet(const std::set<alphabet::Symbol>& alphabet);
+
+	/**
+	 * Adds nonterminal symbol to the alphabet of nonterminals.
+	 * @param symbol Symbol to add
+	 * @throws GrammarException when symbol is already a terminal
+	 */
+	bool addNonterminalSymbol(const alphabet::Symbol& symbol);
+
+	/**
+	 * Removes nonterminal symbol from the grammar.
+	 * @param symbol Symbol to remove
+	 * @throws GrammarException when symbol is used in rule
+	 */
+	virtual bool removeNonterminalSymbol(const alphabet::Symbol& symbol) = 0;
+
+	/**
+	 * @return set of nonterminal symbols
+	 */
+	const std::set<alphabet::Symbol>& getNonterminalAlphabet() const;
+
+	/**
+	 * Sets the terminal alphabet
+	 */
+	void setNonterminalAlphabet(const std::set<alphabet::Symbol>& alphabet);
+
+	/**
+	 * @return start symbol
+	 */
+	const alphabet::Symbol& getInitialSymbol() const;
+
+	/**
+	 * Sets the initial symbol.
+	 * @param symbol nonterminal Symbol
+	 * @throws GrammarException when symbol isn't a nonterminal symbol
+	 */
+	void setInitialSymbol(const alphabet::Symbol& symbol);
+
+	/**
+	 * Creates and adds unique state to grammar. If given state name is
+	 * already used, appends apostrophe or integer suffix
+	 * @param name name of the state
+	 * @throws AutomatonException if symbol could not be created
+	 * @return created symbol
+	 */
+	static alphabet::Symbol createUniqueSymbol(const alphabet::Symbol& base, const std::set<alphabet::Symbol>& Terminals, const std::set<alphabet::Symbol>& nonterminals);
+
+};
+
+} /* namespace grammar */
+
+#endif /* TERMINAL_NONTERMINAL_ALPHABET_INITIAL_SYMBOL_H_ */
-- 
GitLab