diff --git a/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.cpp b/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.cpp
index ef7cbf02d593f6025234252481b90f842858fae2..e48d286921a7d71b6a32031349fc33582691dce9 100644
--- a/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.cpp
+++ b/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.cpp
@@ -159,14 +159,62 @@ NFA FiniteAutomatonFromStringParser::parseNFA() {
 }
 
 DFA FiniteAutomatonFromStringParser::parseDFA() {
-	DFA res(State(label::Label(label::IntegerLabel(0))));;
+	
+	FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.token();
+	if(token.type != FiniteAutomatonFromStringLexer::TokenType::DFA) {
+		throw alib::AlibException();
+	}
+	std::vector<alphabet::Symbol> symbols;
+
+	next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first();
+	token = m_FiniteAutomatonLexer.token();
+	while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) {
+		alphabet::Symbol symbol = m_SymbolParser.parse();
+		symbols.push_back(symbol);
+
+		next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first();
+		token = m_FiniteAutomatonLexer.token();
+	}
+
+	token = m_FiniteAutomatonLexer.token();
+	if(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) throw alib::AlibException();
+	
+	State* initialState = NULL;
+	std::set<State> finalStates;
+	std::set<State> states;
+	std::set<std::tuple<State, alphabet::Symbol, State>> transitionFunction;
+	
+	next() || m_LabelParser.first();
+	parseDFATransition(states, symbols, initialState, finalStates, transitionFunction);
+	token = m_FiniteAutomatonLexer.token();
+
+	while(token.type == FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) {
+		next() || m_LabelParser.first();
+		token = m_FiniteAutomatonLexer.token();
+		if(token.type == FiniteAutomatonFromStringLexer::TokenType::TEOF) break;
+
+		parseDFATransition(states, symbols, initialState, finalStates, transitionFunction);
+		token = m_FiniteAutomatonLexer.token();
+	}
+
+	if(initialState == NULL) throw alib::AlibException();
+
+	DFA res(*initialState);
+	delete initialState;
+
+	res.setInputSymbols(std::set<alphabet::Symbol>(symbols.begin(), symbols.end()));
+	res.setStates(states);
+	res.setFinalStates(finalStates);
+	for(const std::tuple<State, alphabet::Symbol, State> transition : transitionFunction) {
+		res.addTransition(std::get<0>(transition), std::get<1>(transition), std::get<2>(transition));
+	}
 
 	return res;
 }
-
-void FiniteAutomatonFromStringParser::parseEpsilonNFATransition(EpsilonNFA& res, const std::vector<std::variant<string::Epsilon, alphabet::Symbol> >& symbols) {
-	bool initial = false;
-	bool final = false;
+	
+void FiniteAutomatonFromStringParser::initialFinalState(bool& initial, bool& final) {
+	initial = false;
+	final = false;
 
 	FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.token();
 	if(token.type == FiniteAutomatonFromStringLexer::TokenType::IN) {
@@ -188,6 +236,14 @@ void FiniteAutomatonFromStringParser::parseEpsilonNFATransition(EpsilonNFA& res,
 			next() || m_LabelParser.first();
 		}
 	}
+}
+
+
+void FiniteAutomatonFromStringParser::parseEpsilonNFATransition(EpsilonNFA& res, const std::vector<std::variant<string::Epsilon, alphabet::Symbol> >& symbols) {
+	bool initial = false;
+	bool final = false;
+
+	initialFinalState(initial, final);
 
 	State from(m_LabelParser.parse());
 	res.addState(from);
@@ -196,6 +252,7 @@ void FiniteAutomatonFromStringParser::parseEpsilonNFATransition(EpsilonNFA& res,
 
 	next() || m_LabelParser.first();
 
+	FiniteAutomatonFromStringLexer::Token token;
 	std::vector<std::variant<string::Epsilon, alphabet::Symbol>>::const_iterator iter = symbols.begin();
 	do {
 		if(iter == symbols.end()) throw alib::AlibException();
@@ -227,26 +284,7 @@ void FiniteAutomatonFromStringParser::parseNFATransition(NFA& res, const std::ve
 	bool initial = false;
 	bool final = false;
 
-	FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.token();
-	if(token.type == FiniteAutomatonFromStringLexer::TokenType::IN) {
-		initial = true;
-		next() || m_LabelParser.first();
-		token = m_FiniteAutomatonLexer.token();
-
-		if(token.type == FiniteAutomatonFromStringLexer::TokenType::OUT) {
-			final = true;
-			next() || m_LabelParser.first();
-		}
-	} else if(token.type == FiniteAutomatonFromStringLexer::TokenType::OUT) {
-		final = true;
-		next() || m_LabelParser.first();
-		token = m_FiniteAutomatonLexer.token();
-
-		if(token.type == FiniteAutomatonFromStringLexer::TokenType::IN) {
-			initial = true;
-			next() || m_LabelParser.first();
-		}
-	}
+	initialFinalState(initial, final);
 
 	State from(m_LabelParser.parse());
 	res.addState(from);
@@ -255,6 +293,7 @@ void FiniteAutomatonFromStringParser::parseNFATransition(NFA& res, const std::ve
 
 	next() || m_LabelParser.first();
 
+	FiniteAutomatonFromStringLexer::Token token;
 	std::vector<alphabet::Symbol>::const_iterator iter = symbols.begin();
 	do {
 		if(iter == symbols.end()) throw alib::AlibException();
@@ -281,4 +320,49 @@ void FiniteAutomatonFromStringParser::parseNFATransition(NFA& res, const std::ve
 	} while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE);
 	if(iter != symbols.end()) throw alib::AlibException();
 }
+
+void FiniteAutomatonFromStringParser::parseDFATransition(std::set<State>& states, const std::vector<alphabet::Symbol>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, alphabet::Symbol, State>>& transitionFunction) {
+	bool initial = false;
+	bool final = false;
+
+	initialFinalState(initial, final);
+
+	State from(m_LabelParser.parse());
+	states.insert(from);
+	if(initial) {
+		if(initialState != NULL) throw alib::AlibException();
+		initialState = new State(from);
+	}
+	if(final) finalStates.insert(from);
+
+	next() || m_LabelParser.first();
+
+	FiniteAutomatonFromStringLexer::Token token;
+	std::vector<alphabet::Symbol>::const_iterator iter = symbols.begin();
+	do {
+		if(iter == symbols.end()) throw alib::AlibException();
+
+		token = m_FiniteAutomatonLexer.token();
+		if(token.type != FiniteAutomatonFromStringLexer::TokenType::NONE) {
+		
+			do {
+				State to(m_LabelParser.parse());
+				states.insert(to);
+				transitionFunction.insert(std::make_tuple(from, *iter, to));
+
+				next() || m_LabelParser.first();
+				token = m_FiniteAutomatonLexer.token();
+				if(token.type != FiniteAutomatonFromStringLexer::TokenType::SEPARATOR) break;
+
+				next() || m_LabelParser.first();
+			} while(true);
+		} else {
+			next() || m_LabelParser.first();
+			token = m_FiniteAutomatonLexer.token();
+		}
+		iter++;
+	} while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE);
+	if(iter != symbols.end()) throw alib::AlibException();
+}
+
 } /* namespace automaton */
diff --git a/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.h b/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.h
index 4fa7cde86a41982820db56695ed8ac7dcd8f49a6..6fdcbd3feb0d40995890a57f634aa513bc35d062 100644
--- a/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.h
+++ b/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.h
@@ -5,9 +5,13 @@
 #include "../../alphabet/SymbolFromStringParser.h"
 #include "../../label/LabelFromStringParser.h"
 
+#include <tuple>
+
 #include "../Automaton.h"
 #include "../AutomatonFeatures.h"
 
+#include "../common/State.h"
+
 #include "../../std/variant.hpp"
 
 #include "../../string/Epsilon.h"
@@ -23,12 +27,14 @@ class FiniteAutomatonFromStringParser {
 	Automaton parse(const std::set<FEATURES>& features);
 	bool next();
 
+	void initialFinalState(bool& initial, bool& final);
+
 	EpsilonNFA parseEpsilonNFA();
 	NFA parseNFA();
 	DFA parseDFA();
 	void parseEpsilonNFATransition(EpsilonNFA& res, const std::vector<std::variant<string::Epsilon, alphabet::Symbol> >& symbols);
 	void parseNFATransition(NFA& res, const std::vector<alphabet::Symbol>& symbols);
-	void parseDFATransition(DFA& res, const std::vector<alphabet::Symbol>& symbols);
+	void parseDFATransition(std::set<State>& states, const std::vector<alphabet::Symbol>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, alphabet::Symbol, State>>& transitionFunction);
 public:
 	FiniteAutomatonFromStringParser(std::stringstream& input);
 
diff --git a/alib2/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp b/alib2/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp
index 9798b1c6cf568c428a22a63786e81c27ec195fe6..c5349181a83d4e6047489dd707b09d0098c62d70 100644
--- a/alib2/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp
+++ b/alib2/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp
@@ -6,6 +6,20 @@
 
 namespace automaton {
 
+void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::stringstream& out, const DFA& automaton, const State& from) const {
+	std::map<std::pair<State, alphabet::Symbol>, State> symbolTransitionsFromState = automaton.getTransitionsFromState(from);
+
+	for(const alphabet::Symbol& inputSymbol : automaton.getInputAlphabet()) {
+		const std::map<std::pair<State, alphabet::Symbol>, State>::iterator toStates = symbolTransitionsFromState.find(std::make_pair(from, inputSymbol));
+		if(toStates == symbolTransitionsFromState.end()) {
+			out << " -";
+		} else {
+			label::LabelToStringComposer composer;
+			out << " " << composer.compose(toStates->second.getName());
+		}
+	}
+}
+
 void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::stringstream& out, const NFA& automaton, const State& from) const {
 	std::map<std::pair<State, alphabet::Symbol>, std::set<State> > symbolTransitionsFromState = automaton.getTransitionsFromState(from);
 
@@ -57,6 +71,28 @@ void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::stringstr
 std::string FiniteAutomatonToStringComposer::compose(const DFA& automaton) const {
 	std::stringstream out;
 
+	out << "DFA";
+	for(auto iterSymbol = automaton.getInputAlphabet().begin(); iterSymbol != automaton.getInputAlphabet().end(); iterSymbol++) {
+		alphabet::SymbolToStringComposer composer;
+		out << " " << composer.compose(*iterSymbol);
+	}
+
+	out << std::endl;
+
+	for(auto iterState = automaton.getStates().begin(); iterState != automaton.getStates().end(); iterState++) {
+		if(automaton.getInitialState() == *iterState) {
+			out << ">";
+		}
+		if(automaton.getFinalStates().find(*iterState) != automaton.getFinalStates().end()) {
+			out << "<";
+		}
+		label::LabelToStringComposer composer;
+		out << composer.compose(iterState->getName());
+
+		composeTransitionsFromState(out, automaton, *iterState);
+
+		out << std::endl;
+	}
 
 	return out.str();
 }
diff --git a/alib2/src/automaton/FSM/FiniteAutomatonToStringComposer.h b/alib2/src/automaton/FSM/FiniteAutomatonToStringComposer.h
index 78d8f070480f44e75de54771b2ca1ff2d7290364..cacb27ec64c93b32622d89a88416f81728cad297 100644
--- a/alib2/src/automaton/FSM/FiniteAutomatonToStringComposer.h
+++ b/alib2/src/automaton/FSM/FiniteAutomatonToStringComposer.h
@@ -20,6 +20,7 @@ class FiniteAutomatonToStringComposer : public AutomatonBase::const_visitor_type
 	void Visit(void*, const PDA& automaton) const;
 	void Visit(void*, const OneTapeDTM& automaton) const;
 
+	void composeTransitionsFromState(std::stringstream& out, const DFA& automaton, const State& from) const;
 	void composeTransitionsFromState(std::stringstream& out, const NFA& automaton, const State& from) const;
 	void composeTransitionsFromState(std::stringstream& out, const EpsilonNFA& automaton, const State& from) const;
 
diff --git a/alib2/test-src/automaton/AutomatonTest.cpp b/alib2/test-src/automaton/AutomatonTest.cpp
index 853a0e3aa6447bab336123e6cbbb88dcc17cbf42..92c3fc58206212180c42e475a6fe74a0bc27ed4f 100644
--- a/alib2/test-src/automaton/AutomatonTest.cpp
+++ b/alib2/test-src/automaton/AutomatonTest.cpp
@@ -135,6 +135,30 @@ void AutomatonTest::FSMStringParserTest() {
 		automaton::FiniteAutomatonFromStringParser parser2(outputs);
 		automaton::Automaton automaton2 = parser2.parseValue();
 
+		CPPUNIT_ASSERT( automaton == automaton2 );
+	}
+	{
+		std::string input = "DFA a b c d\n"
+				    ">0 3 5 1 -\n"
+				    "1 2 - - -\n"
+				    "2 3 - - -\n"
+				    "3 - - 4 -\n"
+				    "4 - 5 - -\n"
+				    "<5 - - - 3\n";
+		std::stringstream inputs(input);
+
+		automaton::FiniteAutomatonFromStringParser parser(inputs);
+		automaton::Automaton automaton = parser.parseValue();
+
+		automaton::FiniteAutomatonToStringComposer composer;
+		std::string output = composer.compose(automaton);
+		std::stringstream outputs(output);
+
+		CPPUNIT_ASSERT( input == output );
+
+		automaton::FiniteAutomatonFromStringParser parser2(outputs);
+		automaton::Automaton automaton2 = parser2.parseValue();
+
 		CPPUNIT_ASSERT( automaton == automaton2 );
 	}
 }