From e83574cd29fbcb1c1ca1e06fd9f5bcd0fd7ef46c Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sun, 29 Jun 2014 17:44:37 +0200
Subject: [PATCH] simplify parsers with first and next methods

---
 alib2/src/alphabet/SymbolFromStringParser.cpp | 26 +++---
 alib2/src/alphabet/SymbolFromStringParser.h   |  3 +-
 alib2/src/alphabet/SymbolFromXMLParser.cpp    | 10 ++-
 alib2/src/alphabet/SymbolFromXMLParser.h      |  5 +-
 .../src/automaton/AutomatonFromXMLParser.cpp  | 10 ++-
 alib2/src/automaton/AutomatonFromXMLParser.h  |  5 +-
 alib2/src/label/LabelFromStringParser.cpp     | 12 ++-
 alib2/src/label/LabelFromStringParser.h       |  3 +-
 alib2/src/label/LabelFromXMLParser.cpp        | 10 ++-
 alib2/src/label/LabelFromXMLParser.h          |  8 +-
 alib2/src/regexp/RegExpFromStringParser.cpp   | 79 +++++++------------
 alib2/src/regexp/RegExpFromStringParser.h     |  4 +-
 alib2/src/regexp/RegExpFromXMLParser.cpp      | 10 ++-
 alib2/src/regexp/RegExpFromXMLParser.h        |  5 +-
 alib2/src/string/StringFromStringParser.cpp   | 32 +++++---
 alib2/src/string/StringFromStringParser.h     |  4 +-
 16 files changed, 137 insertions(+), 89 deletions(-)

diff --git a/alib2/src/alphabet/SymbolFromStringParser.cpp b/alib2/src/alphabet/SymbolFromStringParser.cpp
index 6ef1a26384..f80584c19c 100644
--- a/alib2/src/alphabet/SymbolFromStringParser.cpp
+++ b/alib2/src/alphabet/SymbolFromStringParser.cpp
@@ -37,13 +37,11 @@ Symbol SymbolFromStringParser::parse(const std::set<FEATURES>& features) {
 }
 
 Symbol SymbolFromStringParser::parseValue() {
-	SymbolFromStringLexer::Token token = m_SymbolLexer.next().token();
-	if(token.type == SymbolFromStringLexer::TokenType::ERROR) {
-		m_LabelParser.m_Lexer.next();
-	}
+	first() || m_LabelParser.first();
+
 	Symbol res = parse();
 
-	token = m_SymbolLexer.next().token();
+	SymbolFromStringLexer::Token token = m_SymbolLexer.next().token();
 	if(token.type == SymbolFromStringLexer::TokenType::TEOF) {
 		return std::move(res);
 	} else {
@@ -51,21 +49,21 @@ Symbol SymbolFromStringParser::parseValue() {
 	}
 }
 
-Symbol* SymbolFromStringParser::parsePointer() {
+bool SymbolFromStringParser::first() {
 	SymbolFromStringLexer::Token token = m_SymbolLexer.next().token();
 	if(token.type == SymbolFromStringLexer::TokenType::BLANK || token.type == SymbolFromStringLexer::TokenType::BOTTOM) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+Symbol* SymbolFromStringParser::parsePointer() {
+	if(first() || (m_SymbolLexer.token().type == SymbolFromStringLexer::TokenType::ERROR && m_LabelParser.first())) {
 		return new Symbol(parse());
-	} else if(token.type == SymbolFromStringLexer::TokenType::ERROR) {
-		label::LabelFromStringLexer::Token token2 = m_LabelParser.m_Lexer.next().token();
-		if(token2.type == label::LabelFromStringLexer::TokenType::STRING || token2.type == label::LabelFromStringLexer::TokenType::CHAR || token2.type == label::LabelFromStringLexer::TokenType::INTEGER) {
-			return new Symbol(parse());
-		} else {
-			return NULL;
-		}
 	} else {
 		return NULL;
 	}
-
 }
 
 } /* namespace alphabet */
diff --git a/alib2/src/alphabet/SymbolFromStringParser.h b/alib2/src/alphabet/SymbolFromStringParser.h
index cd3d46cd6b..59050e04eb 100644
--- a/alib2/src/alphabet/SymbolFromStringParser.h
+++ b/alib2/src/alphabet/SymbolFromStringParser.h
@@ -34,11 +34,12 @@ class SymbolFromStringParser {
 	
 	SymbolFromStringLexer m_SymbolLexer;
 	label::LabelFromStringParser m_LabelParser;
-	Symbol* parsePointer();
 	Symbol parse();
 	Symbol parse(const std::set<FEATURES>& features);
 public:
+	bool first();
 	SymbolFromStringParser(std::stringstream&);
+	Symbol* parsePointer();
 	Symbol parseValue();
 	friend class string::StringFromStringParser;
 	friend class regexp::RegExpFromStringParser;
diff --git a/alib2/src/alphabet/SymbolFromXMLParser.cpp b/alib2/src/alphabet/SymbolFromXMLParser.cpp
index bd4226ffba..ecedbacee7 100644
--- a/alib2/src/alphabet/SymbolFromXMLParser.cpp
+++ b/alib2/src/alphabet/SymbolFromXMLParser.cpp
@@ -75,8 +75,16 @@ Symbol SymbolFromXMLParser::parseValue(std::list<sax::Token>& input) const {
 	}
 }
 
-Symbol* SymbolFromXMLParser::parsePointer(std::list<sax::Token>& input) const {
+bool SymbolFromXMLParser::first(std::list<sax::Token>& input) const {
 	if(isToken(input, sax::Token::TokenType::START_ELEMENT, "LabeledSymbol") || isToken(input, sax::Token::TokenType::START_ELEMENT, "BlankSymbol") || isToken(input, sax::Token::TokenType::START_ELEMENT, "BottomOfTheStackSymbol")) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+Symbol* SymbolFromXMLParser::parsePointer(std::list<sax::Token>& input) const {
+	if(first(input)) {
 		return new Symbol(parse(input));
 	} else {
 		return NULL;
diff --git a/alib2/src/alphabet/SymbolFromXMLParser.h b/alib2/src/alphabet/SymbolFromXMLParser.h
index be0b411348..0c94b90089 100644
--- a/alib2/src/alphabet/SymbolFromXMLParser.h
+++ b/alib2/src/alphabet/SymbolFromXMLParser.h
@@ -47,6 +47,9 @@ class SymbolFromXMLParser : public sax::FromXMLParser {
 	Symbol parseBlankSymbol(std::list<sax::Token>& input) const;
 	Symbol parseBottomOfTheStackSymbol(std::list<sax::Token>& input) const;
 	Symbol parseEndSymbol(std::list<sax::Token>& input) const;
+public:
+	bool first(std::list<sax::Token>& input) const;
+
 	/**
 	 * Parses the XML tokens and returns symbol. The input is destroyed in the process.
 	 * @param input XML tokens represented as list of tokens
@@ -54,7 +57,7 @@ class SymbolFromXMLParser : public sax::FromXMLParser {
 	 * @throws ParserException when tokens do not represent Symbol but first token seemd as a symbol
 	 */
 	Symbol* parsePointer(std::list<sax::Token>& input) const;
-public:
+	
 	/**
 	 * Parses the XML tokens and returns symbol. The input is destroyed in the process.
 	 * @param input XML tokens represented as list of tokens
diff --git a/alib2/src/automaton/AutomatonFromXMLParser.cpp b/alib2/src/automaton/AutomatonFromXMLParser.cpp
index 9279d3f482..e3addc309e 100644
--- a/alib2/src/automaton/AutomatonFromXMLParser.cpp
+++ b/alib2/src/automaton/AutomatonFromXMLParser.cpp
@@ -48,8 +48,16 @@ Automaton AutomatonFromXMLParser::parseValue(std::list<sax::Token>& input) const
 	}
 }
 
-Automaton* AutomatonFromXMLParser::parsePointer(std::list<sax::Token>& input) const {
+bool AutomatonFromXMLParser::first(std::list<sax::Token>& input) const {
 	if(isToken(input, sax::Token::TokenType::START_ELEMENT, "automaton") || isToken(input, sax::Token::TokenType::START_ELEMENT, "EpsilonNFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "NFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "DFA")) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+Automaton* AutomatonFromXMLParser::parsePointer(std::list<sax::Token>& input) const {
+	if(first(input)) {
 		return new Automaton(parse(input));
 	} else {
 		return NULL;
diff --git a/alib2/src/automaton/AutomatonFromXMLParser.h b/alib2/src/automaton/AutomatonFromXMLParser.h
index 504ea8b53a..2ec021aa8e 100644
--- a/alib2/src/automaton/AutomatonFromXMLParser.h
+++ b/alib2/src/automaton/AutomatonFromXMLParser.h
@@ -66,8 +66,11 @@ protected:
 
 	Automaton parse(std::list<sax::Token>& input) const;
 	Automaton parse(std::list<sax::Token>& input, const std::set<FEATURES>& features) const;
-	Automaton* parsePointer(std::list<sax::Token>& input) const;
 public:
+	bool first(std::list<sax::Token>& input) const;
+
+	Automaton* parsePointer(std::list<sax::Token>& input) const;
+
 	/**
 	 * Parses the xml and returns the automaton. The input is destroyed in the process.
 	 * @param input XML represented as list of Tokens
diff --git a/alib2/src/label/LabelFromStringParser.cpp b/alib2/src/label/LabelFromStringParser.cpp
index 908a47125f..048552197c 100644
--- a/alib2/src/label/LabelFromStringParser.cpp
+++ b/alib2/src/label/LabelFromStringParser.cpp
@@ -36,7 +36,7 @@ Label LabelFromStringParser::parse(const std::set<FEATURES>& features) {
 }
 
 Label LabelFromStringParser::parseValue() {
-	m_Lexer.next();
+	first();
 	Label res = parse();
 	
 	LabelFromStringLexer::Token token = m_Lexer.next().token();
@@ -47,9 +47,17 @@ Label LabelFromStringParser::parseValue() {
 	}
 }
 
-Label* LabelFromStringParser::parsePointer() {
+bool LabelFromStringParser::first() {
 	LabelFromStringLexer::Token token = m_Lexer.next().token();
 	if(token.type == LabelFromStringLexer::TokenType::STRING || token.type == LabelFromStringLexer::TokenType::CHAR || token.type == LabelFromStringLexer::TokenType::INTEGER) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+Label* LabelFromStringParser::parsePointer() {
+	if(first()) {
 		return new Label(parse());
 	} else {
 		return NULL;
diff --git a/alib2/src/label/LabelFromStringParser.h b/alib2/src/label/LabelFromStringParser.h
index 3b36cdc4a6..4cb0787acc 100644
--- a/alib2/src/label/LabelFromStringParser.h
+++ b/alib2/src/label/LabelFromStringParser.h
@@ -39,10 +39,11 @@ class LabelFromStringParser {
 	LabelFromStringLexer m_Lexer;
 	Label parse(const std::set<FEATURES>&);
 	Label parse();
-	Label* parsePointer();
 
 public:
+	bool first();
 	LabelFromStringParser(std::stringstream&);
+	Label* parsePointer();
 	Label parseValue();
 	friend class alphabet::SymbolFromStringParser;
 	friend class regexp::RegExpFromStringParser;
diff --git a/alib2/src/label/LabelFromXMLParser.cpp b/alib2/src/label/LabelFromXMLParser.cpp
index 3b7ebdb4ae..1b09a440d3 100644
--- a/alib2/src/label/LabelFromXMLParser.cpp
+++ b/alib2/src/label/LabelFromXMLParser.cpp
@@ -52,8 +52,16 @@ Label LabelFromXMLParser::parseValue(std::list<sax::Token>& input) const {
 	}
 }
 
-Label* LabelFromXMLParser::parsePointer(std::list<sax::Token>& input) const {
+bool LabelFromXMLParser::first(std::list<sax::Token>& input) const {
 	if(isToken(input, sax::Token::TokenType::START_ELEMENT, "IntegerLabel") || isToken(input, sax::Token::TokenType::START_ELEMENT, "StringLabel") || isToken(input, sax::Token::TokenType::START_ELEMENT, "CharacterLabel")) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+Label* LabelFromXMLParser::parsePointer(std::list<sax::Token>& input) const {
+	if(first(input)) {
 		return new Label(parse(input));
 	} else {
 		return NULL;
diff --git a/alib2/src/label/LabelFromXMLParser.h b/alib2/src/label/LabelFromXMLParser.h
index 4374f6534a..b2ee3d9fd3 100644
--- a/alib2/src/label/LabelFromXMLParser.h
+++ b/alib2/src/label/LabelFromXMLParser.h
@@ -35,8 +35,12 @@ namespace label {
  */
 class LabelFromXMLParser : public sax::FromXMLParser {
 	Label parse(std::list<sax::Token>& input, const std::set<FEATURES>&) const;
+	
 	Label parse(std::list<sax::Token>& input) const;
 
+public:
+	bool first(std::list<sax::Token>& input) const;
+
 	/**
 	 * Parses the XML tokens and returns label. The input is destroyed in the process.
 	 * @param input XML tokens represented as list of tokens
@@ -44,7 +48,7 @@ class LabelFromXMLParser : public sax::FromXMLParser {
 	 * @throws ParserException when tokens do not represent Label but first token seemd as a label
 	 */
 	Label* parsePointer(std::list<sax::Token>& input) const;
-public:
+	
 	/**
 	 * Parses the XML tokens and returns label. The input is destroyed in the process.
 	 * @param input XML tokens represented as list of tokens
@@ -52,7 +56,9 @@ public:
 	 * @throws ParserException when tokens do not represent Label
 	 */
 	Label parseValue(std::list<sax::Token>& input) const;
+
 	friend class alphabet::SymbolFromXMLParser;
+
 	friend class automaton::AutomatonFromXMLParser;
 };
 
diff --git a/alib2/src/regexp/RegExpFromStringParser.cpp b/alib2/src/regexp/RegExpFromStringParser.cpp
index 5af3a1e1a7..73699c84ce 100644
--- a/alib2/src/regexp/RegExpFromStringParser.cpp
+++ b/alib2/src/regexp/RegExpFromStringParser.cpp
@@ -21,16 +21,10 @@ RegExp RegExpFromStringParser::parse(const std::set<FEATURES>& features) {
 }
 
 RegExp RegExpFromStringParser::parseValue() {
-	RegExpFromStringLexer::Token token = m_RegexpLexer.next().token();
-	if(token.type == RegExpFromStringLexer::TokenType::ERROR) {
-		alphabet::SymbolFromStringLexer::Token token = m_SymbolParser.m_SymbolLexer.next().token();
-		if(token.type == alphabet::SymbolFromStringLexer::TokenType::ERROR) {
-			m_SymbolParser.m_LabelParser.m_Lexer.next();
-		}
-	}
+	first() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first();
 	RegExp res = parse();
 
-	token = m_RegexpLexer.token();
+	RegExpFromStringLexer::Token token = m_RegexpLexer.token();
 	if(token.type == RegExpFromStringLexer::TokenType::TEOF) {
 		return std::move(res);
 	} else {
@@ -38,28 +32,30 @@ RegExp RegExpFromStringParser::parseValue() {
 	}
 }
 
-RegExp* RegExpFromStringParser::parsePointer() {
+bool RegExpFromStringParser::first() {
 	RegExpFromStringLexer::Token token = m_RegexpLexer.next().token();
 	if(token.type == RegExpFromStringLexer::TokenType::EMPTY || token.type == RegExpFromStringLexer::TokenType::EPS || token.type == RegExpFromStringLexer::TokenType::LPAR) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+bool RegExpFromStringParser::next() {
+	RegExpFromStringLexer::Token token = m_RegexpLexer.next().token();
+	if(token.type == RegExpFromStringLexer::TokenType::EMPTY || token.type == RegExpFromStringLexer::TokenType::EPS || token.type == RegExpFromStringLexer::TokenType::LPAR || token.type == RegExpFromStringLexer::TokenType::STAR || token.type == RegExpFromStringLexer::TokenType::RPAR || token.type == RegExpFromStringLexer::TokenType::PLUS) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+RegExp* RegExpFromStringParser::parsePointer() {
+	if(first() || (m_RegexpLexer.token().type == RegExpFromStringLexer::TokenType::ERROR && m_SymbolParser.first()) || (m_SymbolParser.m_SymbolLexer.token().type == alphabet::SymbolFromStringLexer::TokenType::ERROR && m_SymbolParser.m_LabelParser.first())) {
 		return new RegExp(parse());
-	} else if(token.type == RegExpFromStringLexer::TokenType::ERROR) {
-		alphabet::SymbolFromStringLexer::Token token = m_SymbolParser.m_SymbolLexer.next().token();
-		if(token.type == alphabet::SymbolFromStringLexer::TokenType::BLANK || token.type == alphabet::SymbolFromStringLexer::TokenType::BOTTOM || token.type == alphabet::SymbolFromStringLexer::TokenType::END) {
-			return new RegExp(parse());
-		} else if(token.type == alphabet::SymbolFromStringLexer::TokenType::ERROR) {
-			label::LabelFromStringLexer::Token token = m_SymbolParser.m_LabelParser.m_Lexer.next().token();
-			if(token.type == label::LabelFromStringLexer::TokenType::STRING || token.type == label::LabelFromStringLexer::TokenType::CHAR || token.type == label::LabelFromStringLexer::TokenType::INTEGER) {
-				return new RegExp(parse());
-			} else {
-				return NULL;
-			}
-		} else {
-			return NULL;
-		}
 	} else {
 		return NULL;
 	}
-
 }
 
 RegExpElement* RegExpFromStringParser::alternation() {
@@ -69,13 +65,7 @@ RegExpElement* RegExpFromStringParser::alternation() {
 RegExpElement* RegExpFromStringParser::alternationCont(RegExpElement* left) {
 	RegExpFromStringLexer::Token token = m_RegexpLexer.token();
 	if(token.type == RegExpFromStringLexer::TokenType::PLUS) {
-		RegExpFromStringLexer::Token token = m_RegexpLexer.next().token();
-		if(token.type == RegExpFromStringLexer::TokenType::ERROR) {
-			alphabet::SymbolFromStringLexer::Token token = m_SymbolParser.m_SymbolLexer.next().token();
-			if(token.type == alphabet::SymbolFromStringLexer::TokenType::ERROR) {
-				m_SymbolParser.m_LabelParser.m_Lexer.next();
-			}
-		}
+		first() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first();
 
 		try {
 			RegExpElement* right = this->concatenation();
@@ -97,13 +87,7 @@ RegExpElement* RegExpFromStringParser::alternationCont(RegExpElement* left) {
 RegExpElement* RegExpFromStringParser::alternationContCont(Alternation* res) {
 	RegExpFromStringLexer::Token token = m_RegexpLexer.token();
 	if(token.type == RegExpFromStringLexer::TokenType::PLUS) {
-		RegExpFromStringLexer::Token token = m_RegexpLexer.next().token();
-		if(token.type == RegExpFromStringLexer::TokenType::ERROR) {
-			alphabet::SymbolFromStringLexer::Token token = m_SymbolParser.m_SymbolLexer.next().token();
-			if(token.type == alphabet::SymbolFromStringLexer::TokenType::ERROR) {
-				m_SymbolParser.m_LabelParser.m_Lexer.next();
-			}
-		}
+		first() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first();
 
 		try {
 			RegExpElement* next = this->concatenation();
@@ -168,13 +152,8 @@ RegExpElement* RegExpFromStringParser::concatenationContCont(Concatenation* res)
 RegExpElement* RegExpFromStringParser::factor() {
 	RegExpFromStringLexer::Token token = m_RegexpLexer.token();
 	if(token.type == RegExpFromStringLexer::TokenType::LPAR) {
-		RegExpFromStringLexer::Token token = m_RegexpLexer.next().token();
-		if(token.type == RegExpFromStringLexer::TokenType::ERROR) {
-			alphabet::SymbolFromStringLexer::Token token = m_SymbolParser.m_SymbolLexer.next().token();
-			if(token.type == alphabet::SymbolFromStringLexer::TokenType::ERROR) {
-				m_SymbolParser.m_LabelParser.m_Lexer.next();
-			}
-		}
+		first() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first();
+	
 		RegExpElement* base = this->alternation();
 		token = m_RegexpLexer.token();
 		if(token.type != RegExpFromStringLexer::TokenType::RPAR) throw alib::AlibException();
@@ -192,13 +171,9 @@ RegExpElement* RegExpFromStringParser::factor() {
 }
 
 RegExpElement* RegExpFromStringParser::star(RegExpElement* elem) {
-	RegExpFromStringLexer::Token token = m_RegexpLexer.next().token();
-	if(token.type == RegExpFromStringLexer::TokenType::ERROR) {
-		alphabet::SymbolFromStringLexer::Token token = m_SymbolParser.m_SymbolLexer.next().token();
-		if(token.type == alphabet::SymbolFromStringLexer::TokenType::ERROR) {
-			m_SymbolParser.m_LabelParser.m_Lexer.next();
-		}
-	}
+	next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first();
+
+	RegExpFromStringLexer::Token token = m_RegexpLexer.token();
 	if(token.type == RegExpFromStringLexer::TokenType::STAR) {
 		Iteration* iter = new Iteration(std::move(*elem));
 		delete elem;
diff --git a/alib2/src/regexp/RegExpFromStringParser.h b/alib2/src/regexp/RegExpFromStringParser.h
index f12db58fa6..af1457ee14 100644
--- a/alib2/src/regexp/RegExpFromStringParser.h
+++ b/alib2/src/regexp/RegExpFromStringParser.h
@@ -34,8 +34,10 @@ class RegExpFromStringParser {
 
 	RegExp parse();
 	RegExp parse(const std::set<FEATURES>& features);
-	RegExp* parsePointer();
+	bool next();
 public:
+	bool first();
+	RegExp* parsePointer();
 	RegExpFromStringParser(std::stringstream&);
 	RegExp parseValue();
 
diff --git a/alib2/src/regexp/RegExpFromXMLParser.cpp b/alib2/src/regexp/RegExpFromXMLParser.cpp
index ef747b99e4..0b6d12ed36 100644
--- a/alib2/src/regexp/RegExpFromXMLParser.cpp
+++ b/alib2/src/regexp/RegExpFromXMLParser.cpp
@@ -43,8 +43,16 @@ RegExp RegExpFromXMLParser::parseValue(std::list<sax::Token>& input) const {
 	}
 }
 
-RegExp* RegExpFromXMLParser::parsePointer(std::list<sax::Token>& input) const {
+bool RegExpFromXMLParser::first(std::list<sax::Token>& input) const {
 	if(isToken(input, sax::Token::TokenType::START_ELEMENT, "regexp")) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+RegExp* RegExpFromXMLParser::parsePointer(std::list<sax::Token>& input) const {
+	if(first(input)) {
 		return new RegExp(parse(input));
 	} else {
 		return NULL;
diff --git a/alib2/src/regexp/RegExpFromXMLParser.h b/alib2/src/regexp/RegExpFromXMLParser.h
index 5d868d9a03..04907e3adc 100644
--- a/alib2/src/regexp/RegExpFromXMLParser.h
+++ b/alib2/src/regexp/RegExpFromXMLParser.h
@@ -33,8 +33,11 @@ class RegExpFromXMLParser : public sax::FromXMLParser {
 
 	RegExp parse(std::list<sax::Token>& input) const;
 	RegExp parse(std::list<sax::Token>& input, const std::set<FEATURES>& features) const;
-	RegExp* parsePointer(std::list<sax::Token>& input) const;
 public:
+	bool first(std::list<sax::Token>& input) const;
+
+	RegExp* parsePointer(std::list<sax::Token>& input) const;
+	
 	/**
 	 * Parses the XML and returns regular expression. The input is destroyed in the process.
 	 * @param input XML represented as list of tokens
diff --git a/alib2/src/string/StringFromStringParser.cpp b/alib2/src/string/StringFromStringParser.cpp
index d57e0e8d36..e0e9fa1921 100644
--- a/alib2/src/string/StringFromStringParser.cpp
+++ b/alib2/src/string/StringFromStringParser.cpp
@@ -44,7 +44,7 @@ String StringFromStringParser::parse(const std::set<FEATURES>& features) {
 }
 
 String StringFromStringParser::parseValue() {
-	m_StringLexer.next();
+	first();
 	String res = parse();
 
 	StringFromStringLexer::Token token = m_StringLexer.next().token();
@@ -55,9 +55,27 @@ String StringFromStringParser::parseValue() {
 	}
 }
 
-String* StringFromStringParser::parsePointer() {
+bool StringFromStringParser::first() {
 	StringFromStringLexer::Token token = m_StringLexer.next().token();
 	if(token.type == StringFromStringLexer::TokenType::EPSILON || token.type == StringFromStringLexer::TokenType::LESS || token.type == StringFromStringLexer::TokenType::QUOTE) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+bool StringFromStringParser::next() {
+	StringFromStringLexer::Token token = m_StringLexer.next().token();
+	if(token.type == StringFromStringLexer::TokenType::EPSILON || token.type == StringFromStringLexer::TokenType::LESS || token.type == StringFromStringLexer::TokenType::QUOTE || token.type == StringFromStringLexer::TokenType::GREATER) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+String* StringFromStringParser::parsePointer() {
+	StringFromStringLexer::Token token = m_StringLexer.next().token();
+	if(first()) {
 		return new String(parse());
 	} else {
 		return NULL;
@@ -67,13 +85,9 @@ String* StringFromStringParser::parsePointer() {
 std::vector<alphabet::Symbol> StringFromStringParser::parseContent() {
 	std::vector<alphabet::Symbol> data;
 	do {
-		StringFromStringLexer::Token token = m_StringLexer.next().token();
-		if(token.type == StringFromStringLexer::TokenType::ERROR) {
-			alphabet::SymbolFromStringLexer::Token token = m_SymbolParser.m_SymbolLexer.next().token();
-			if(token.type == alphabet::SymbolFromStringLexer::TokenType::ERROR) {
-				m_SymbolParser.m_LabelParser.m_Lexer.next();
-			}
-		}
+		next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first();
+
+		StringFromStringLexer::Token token = m_StringLexer.token();
 		if(token.type == StringFromStringLexer::TokenType::GREATER || token.type == StringFromStringLexer::TokenType::QUOTE)
 			return data;
 		data.push_back(m_SymbolParser.parse());
diff --git a/alib2/src/string/StringFromStringParser.h b/alib2/src/string/StringFromStringParser.h
index 9f1fc4e1c3..8bc0c10ad7 100644
--- a/alib2/src/string/StringFromStringParser.h
+++ b/alib2/src/string/StringFromStringParser.h
@@ -26,8 +26,10 @@ class StringFromStringParser {
 
 	String parse();
 	String parse(const std::set<FEATURES>& features);
-	String* parsePointer();
+	bool next();
 public:
+	bool first();
+	String* parsePointer();
 	StringFromStringParser(std::stringstream&);
 	String parseValue();
 
-- 
GitLab