diff --git a/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.cpp b/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.cpp
index f2bcd8e8388bf7e22f494821c9d15e033286a9db..ef7cbf02d593f6025234252481b90f842858fae2 100644
--- a/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.cpp
+++ b/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.cpp
@@ -122,7 +122,40 @@ EpsilonNFA FiniteAutomatonFromStringParser::parseEpsilonNFA() {
 NFA FiniteAutomatonFromStringParser::parseNFA() {
 	NFA res;
 
-	return res;
+	FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.token();
+	if(token.type != FiniteAutomatonFromStringLexer::TokenType::NFA) {
+		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();
+		res.addInputSymbol(symbol);
+		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();
+	
+	next() || m_LabelParser.first();
+	parseNFATransition(res, symbols);
+	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;
+
+		parseNFATransition(res, symbols);
+		token = m_FiniteAutomatonLexer.token();
+	}
+
+	return  res;
 }
 
 DFA FiniteAutomatonFromStringParser::parseDFA() {
@@ -190,4 +223,62 @@ void FiniteAutomatonFromStringParser::parseEpsilonNFATransition(EpsilonNFA& res,
 	if(iter != symbols.end()) throw alib::AlibException();
 }
 
+void FiniteAutomatonFromStringParser::parseNFATransition(NFA& res, const std::vector<alphabet::Symbol>& symbols) {
+	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();
+		}
+	}
+
+	State from(m_LabelParser.parse());
+	res.addState(from);
+	if(initial) res.addInitialState(from);
+	if(final) res.addFinalState(from);
+
+	next() || m_LabelParser.first();
+
+	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());
+				res.addState(to);
+				res.addTransition(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 9b35c28dd7315eab98d33c665a1d941b15c01bb0..4fa7cde86a41982820db56695ed8ac7dcd8f49a6 100644
--- a/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.h
+++ b/alib2/src/automaton/FSM/FiniteAutomatonFromStringParser.h
@@ -27,8 +27,8 @@ class FiniteAutomatonFromStringParser {
 	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 parseNFATransition(NFA& res, const std::vector<alphabet::Symbol>& symbols);
+	void parseDFATransition(DFA& res, const std::vector<alphabet::Symbol>& symbols);
 public:
 	FiniteAutomatonFromStringParser(std::stringstream& input);
 
diff --git a/alib2/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp b/alib2/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp
index c024932d7af03c7ab40c83d5e42818b60a1f8d35..9798b1c6cf568c428a22a63786e81c27ec195fe6 100644
--- a/alib2/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp
+++ b/alib2/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp
@@ -6,6 +6,24 @@
 
 namespace automaton {
 
+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);
+
+	for(const alphabet::Symbol& inputSymbol : automaton.getInputAlphabet()) {
+		const std::map<std::pair<State, alphabet::Symbol>, std::set<State> >::iterator toStates = symbolTransitionsFromState.find(std::make_pair(from, inputSymbol));
+		if(toStates == symbolTransitionsFromState.end() || toStates->second.size() == 0) {
+			out << " -";
+		} else {
+			bool sign = false;
+			for(const State& to : toStates->second) {
+				label::LabelToStringComposer composer;
+				out << (sign ? "|" : " ") << composer.compose(to.getName());
+				sign = true;
+			}
+		}
+	}
+}
+
 void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::stringstream& out, const EpsilonNFA& automaton, const State& from) const {
 	std::map<std::pair<State, alphabet::Symbol>, std::set<State> > symbolTransitionsFromState = automaton.getSymbolTransitionsFromState(from);
 
@@ -46,6 +64,28 @@ std::string FiniteAutomatonToStringComposer::compose(const DFA& automaton) const
 std::string FiniteAutomatonToStringComposer::compose(const NFA& automaton) const {
 	std::stringstream out;
 
+	out << "NFA";
+	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.getInitialStates().find(*iterState) != automaton.getInitialStates().end()) {
+			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 aa5ef2872bf7d2460d03f0b768c7cecd5ed6f9a3..78d8f070480f44e75de54771b2ca1ff2d7290364 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 NFA& automaton, const State& from) const;
 	void composeTransitionsFromState(std::stringstream& out, const EpsilonNFA& automaton, const State& from) const;
 
 public:
diff --git a/alib2/test-src/automaton/AutomatonTest.cpp b/alib2/test-src/automaton/AutomatonTest.cpp
index 11c938d218bb7a37fd0041cf54e666e5a2dd04ad..853a0e3aa6447bab336123e6cbbb88dcc17cbf42 100644
--- a/alib2/test-src/automaton/AutomatonTest.cpp
+++ b/alib2/test-src/automaton/AutomatonTest.cpp
@@ -89,26 +89,52 @@ void AutomatonTest::testDFAParser() {
 }
 
 void AutomatonTest::FSMStringParserTest() {
-	std::string input = "ENFA a b c d #E\n"
-			    ">0 3|4 5 1|3|4 - 2\n"
-			    "1 2 - - - -\n"
-			    "2 3 - - - -\n"
-			    "3 - - 4 - -\n"
-			    "4 - 5 - - 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 );
+	{
+		std::string input = "ENFA a b c d #E\n"
+				    ">0 3|4 5 1|3|4 - 2\n"
+				    "1 2 - - - -\n"
+				    "2 3 - - - -\n"
+				    "3 - - 4 - -\n"
+				    "4 - 5 - - 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 );
+	}
+	{
+		std::string input = "NFA a b c d\n"
+				    ">0 3|4 5 1|3|4 -\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 );
+	}
 }