From 211a65cd6f2ce9e8580baa6efbb17a90a7caac37 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Thu, 2 Nov 2017 16:03:15 +0100
Subject: [PATCH] make epsilon templated with symbol in Fi/Fo algo

---
 .../src/grammar/parsing/First.h               | 40 +++++++++----------
 .../src/grammar/parsing/Follow.h              | 24 +++++------
 2 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/alib2algo_experimental/src/grammar/parsing/First.h b/alib2algo_experimental/src/grammar/parsing/First.h
index a1fcf5c1d2..ab544a6416 100644
--- a/alib2algo_experimental/src/grammar/parsing/First.h
+++ b/alib2algo_experimental/src/grammar/parsing/First.h
@@ -20,24 +20,24 @@ namespace parsing {
 
 class First {
 	template < class SymbolType >
-	static ext::set < ext::variant < SymbolType, string::Epsilon < > > > first ( const ext::set < SymbolType > & terminals, const ext::set < SymbolType > & nonterminals, const ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > & firstOfNonterminal, const ext::vector < SymbolType > & rhs );
+	static ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > first ( const ext::set < SymbolType > & terminals, const ext::set < SymbolType > & nonterminals, const ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > & firstOfNonterminal, const ext::vector < SymbolType > & rhs );
 
 	template < class SymbolType >
-	static ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > first ( const ext::set < SymbolType > & terminals, const ext::set < SymbolType > & nonterminals, const ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > & rules );
+	static ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > first ( const ext::set < SymbolType > & terminals, const ext::set < SymbolType > & nonterminals, const ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > & rules );
 
 public:
 	template < class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > >
-	static ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > first ( const T & grammar );
+	static ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > first ( const T & grammar );
 
 	template < class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > >
-	static ext::set < ext::variant < SymbolType, string::Epsilon < > > > first ( const T & grammar, const ext::vector < SymbolType > & rhs );
+	static ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > first ( const T & grammar, const ext::vector < SymbolType > & rhs );
 };
 
 template < class SymbolType >
-ext::set < ext::variant < SymbolType, string::Epsilon < > > > First::first ( const ext::set < SymbolType > & terminals, const ext::set < SymbolType > & nonterminals, const ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > & firstOfNonterminal, const ext::vector < SymbolType > & rhs ) {
+ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > First::first ( const ext::set < SymbolType > & terminals, const ext::set < SymbolType > & nonterminals, const ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > & firstOfNonterminal, const ext::vector < SymbolType > & rhs ) {
 	 // 1. FIRST(\varepsilon) = { \varepsilon }
 	if ( rhs.size ( ) == 0 ) {
-		return { string::Epsilon < >::EPSILON };
+		return { string::Epsilon < SymbolType >::EPSILON };
 	}
 
 	 // 2. FIRST(a) = { a } forall a \in T
@@ -46,16 +46,16 @@ ext::set < ext::variant < SymbolType, string::Epsilon < > > > First::first ( con
 	}
 
 	 // 4. FIRST(A \alpha) = first(A) if A \in N and \varepsilon \notin first(A)
-	else if ( nonterminals.count ( rhs[0] ) && !firstOfNonterminal.find ( rhs[0] )->second.count ( string::Epsilon < >::EPSILON ) ) {
+	else if ( nonterminals.count ( rhs[0] ) && !firstOfNonterminal.find ( rhs[0] )->second.count ( string::Epsilon < SymbolType >::EPSILON ) ) {
 		return firstOfNonterminal.find ( rhs[0] )->second;
 	}
 
 	 // 5. FIRST(A \alpha) = (first(A) - \varepsilon) \cup FIRST(\alpha) if A \in N and \varepsilon \in first(A)
-	else if ( nonterminals.count ( rhs[0] ) && firstOfNonterminal.find ( rhs[0] )->second.count ( string::Epsilon < >::EPSILON ) ) {
-		ext::set < ext::variant < SymbolType, string::Epsilon < > > > res = firstOfNonterminal.find ( rhs[0] )->second;
-		res.erase ( string::Epsilon < >::EPSILON );
+	else if ( nonterminals.count ( rhs[0] ) && firstOfNonterminal.find ( rhs[0] )->second.count ( string::Epsilon < SymbolType >::EPSILON ) ) {
+		ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > res = firstOfNonterminal.find ( rhs[0] )->second;
+		res.erase ( string::Epsilon < SymbolType >::EPSILON );
 
-		ext::set < ext::variant < SymbolType, string::Epsilon < > > > next = first ( terminals, nonterminals, firstOfNonterminal, ext::vector < SymbolType > ( rhs.begin ( ) + 1, rhs.end ( ) ) );
+		ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > next = first ( terminals, nonterminals, firstOfNonterminal, ext::vector < SymbolType > ( rhs.begin ( ) + 1, rhs.end ( ) ) );
 		res.insert ( next.begin ( ), next.end ( ) );
 		return res;
 	} else {
@@ -64,7 +64,7 @@ ext::set < ext::variant < SymbolType, string::Epsilon < > > > First::first ( con
 }
 
 template < class SymbolType >
-ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > First::first ( const ext::set < SymbolType > & terminals, const ext::set < SymbolType > & nonterminals, const ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > & rules ) {
+ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > First::first ( const ext::set < SymbolType > & terminals, const ext::set < SymbolType > & nonterminals, const ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > & rules ) {
 	/*
 	 *
 	 * 1. foreach A \in N: first(A) = \emptyset
@@ -73,17 +73,17 @@ ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < >
 	 * 3. repeat step 2 if at least one set first(A) has changed
 	 *
 	 */
-	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > firstOfNonterminal1;
+	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > firstOfNonterminal1;
 
 	for ( const SymbolType & nonterminal : nonterminals )
 		firstOfNonterminal1[nonterminal];
 
-	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > firstOfNonterminal2 = firstOfNonterminal1;
+	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > firstOfNonterminal2 = firstOfNonterminal1;
 
 	do {
 		for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & rule : rules )
 			for ( const ext::vector < SymbolType > & rhs : rule.second ) {
-				ext::set < ext::variant < SymbolType, string::Epsilon < > > > newFirst = first ( terminals, nonterminals, firstOfNonterminal1, rhs );
+				ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > newFirst = first ( terminals, nonterminals, firstOfNonterminal1, rhs );
 				firstOfNonterminal2[rule.first].insert ( newFirst.begin ( ), newFirst.end ( ) );
 			}
 
@@ -99,10 +99,10 @@ ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < >
 }
 
 template < class T, class SymbolType >
-ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > First::first ( const T & grammar ) {
-	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) );
+ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > First::first ( const T & grammar ) {
+	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) );
 
-	ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > res;
+	ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > res;
 
 	for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & rule : grammar.getRawRules ( ) )
 		for ( const ext::vector < SymbolType > & rhs : rule.second )
@@ -112,8 +112,8 @@ ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, str
 }
 
 template < class T, class SymbolType >
-ext::set < ext::variant < SymbolType, string::Epsilon < > > > First::first ( const T & grammar, const ext::vector < SymbolType > & rhs ) {
-	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) );
+ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > First::first ( const T & grammar, const ext::vector < SymbolType > & rhs ) {
+	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) );
 
 	return first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), firstNt, rhs );
 }
diff --git a/alib2algo_experimental/src/grammar/parsing/Follow.h b/alib2algo_experimental/src/grammar/parsing/Follow.h
index b7ac8452b5..955481bcb0 100644
--- a/alib2algo_experimental/src/grammar/parsing/Follow.h
+++ b/alib2algo_experimental/src/grammar/parsing/Follow.h
@@ -27,18 +27,18 @@ namespace parsing {
 
 class Follow {
 	template < class T, class SymbolType >
-	static void follow ( const T & grammar, ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > & followSet );
+	static void follow ( const T & grammar, ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > & followSet );
 
 public:
 	template < class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > >
-	static ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > follow ( const T & grammar );
+	static ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > follow ( const T & grammar );
 
 	template < class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > >
-	static ext::set < ext::variant < SymbolType, string::Epsilon < > > > follow ( const T & grammar, const SymbolType & nt );
+	static ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > follow ( const T & grammar, const SymbolType & nt );
 };
 
 template < class T, class SymbolType >
-void Follow::follow ( const T & grammar, ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > & followSet ) {
+void Follow::follow ( const T & grammar, ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > & followSet ) {
 	for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & rule : grammar.getRawRules ( ) ) {
 		const SymbolType & X = rule.first;
 
@@ -50,10 +50,10 @@ void Follow::follow ( const T & grammar, ext::map < SymbolType, ext::set < ext::
 				if ( !grammar.getNonterminalAlphabet ( ).count ( Y ) )
 					continue;
 
-				ext::set < ext::variant < SymbolType, string::Epsilon < > > > firstBeta = First::first ( grammar, ext::vector < SymbolType > ( std::next ( it ), rhs.end ( ) ) );
+				ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > firstBeta = First::first ( grammar, ext::vector < SymbolType > ( std::next ( it ), rhs.end ( ) ) );
 
-				if ( firstBeta.count ( string::Epsilon < >::EPSILON ) ) {
-					firstBeta.erase ( string::Epsilon < >::EPSILON );
+				if ( firstBeta.count ( string::Epsilon < SymbolType >::EPSILON ) ) {
+					firstBeta.erase ( string::Epsilon < SymbolType >::EPSILON );
 					followSet[Y].insert ( followSet[X].begin ( ), followSet[X].end ( ) );
 				}
 
@@ -64,7 +64,7 @@ void Follow::follow ( const T & grammar, ext::map < SymbolType, ext::set < ext::
 }
 
 template < class T, class SymbolType >
-ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > Follow::follow ( const T & grammar ) {
+ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > Follow::follow ( const T & grammar ) {
 	/*
 	 * 1. Follow(S) = { \varepsilon }
 	 *    Follow(A) = {} forall A \in N, A \neq S
@@ -76,14 +76,14 @@ ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < >
 	 * 3. goto 2 if any follow set was changed in prev step.
 	 */
 
-	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > followSet1;
+	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > followSet1;
 
 	for ( const SymbolType & symb : grammar.getNonterminalAlphabet ( ) )
 		followSet1[symb];
 
-	followSet1[grammar.getInitialSymbol ( )] = { string::Epsilon < >::EPSILON };
+	followSet1[grammar.getInitialSymbol ( )] = { string::Epsilon < SymbolType >::EPSILON };
 
-	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > followSet2 = followSet1;
+	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > followSet2 = followSet1;
 
 	do {
 		follow ( grammar, followSet2 );
@@ -98,7 +98,7 @@ ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < >
 }
 
 template < class T, class SymbolType >
-ext::set < ext::variant < SymbolType, string::Epsilon < > > > Follow::follow ( const T & grammar, const SymbolType & nt ) {
+ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > Follow::follow ( const T & grammar, const SymbolType & nt ) {
 	if ( !grammar.getNonterminalAlphabet ( ).count ( nt ) )
 		throw exception::CommonException ( "Follow: Given symbol is not nonterminal." );
 
-- 
GitLab