diff --git a/alib2algo_experimental/src/grammar/parsing/First.cpp b/alib2algo_experimental/src/grammar/parsing/First.cpp index 0cb7718c5eb83c4840120d0da9f756312868fa77..b182a1922666036bfea7b41057593d59cfa0783e 100644 --- a/alib2algo_experimental/src/grammar/parsing/First.cpp +++ b/alib2algo_experimental/src/grammar/parsing/First.cpp @@ -23,115 +23,25 @@ namespace grammar { namespace parsing { -ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > First::first ( const ext::set < DefaultSymbolType > & terminals, const ext::set < DefaultSymbolType > & nonterminals, const ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > & firstOfNonterminal, const ext::vector < DefaultSymbolType > & rhs ) { - // 1. FIRST(\varepsilon) = { \varepsilon } - if ( rhs.size ( ) == 0 ) { - return { string::Epsilon < >::EPSILON }; - } - - // 2. FIRST(a) = { a } forall a \in T - else if ( terminals.count ( rhs[0] ) ) { - return { rhs[0] }; - } - - // 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 ) ) { - 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 < DefaultSymbolType, string::Epsilon < > > > res = firstOfNonterminal.find ( rhs[0] )->second; - res.erase ( string::Epsilon < >::EPSILON ); - - ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > next = first ( terminals, nonterminals, firstOfNonterminal, ext::vector < DefaultSymbolType > ( rhs.begin ( ) + 1, rhs.end ( ) ) ); - res.insert ( next.begin ( ), next.end ( ) ); - return res; - } else { - throw exception::CommonException ( "Cant be reached" ); - } -} - -ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > First::first ( const ext::set < DefaultSymbolType > & terminals, const ext::set < DefaultSymbolType > & nonterminals, const ext::map < DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > > & rules ) { - /* - * - * 1. foreach A \in N: first(A) = \emptyset - * 2. foreach A \rightarrow \alpha: - * first(A) = first(A) \cup FIRST(\alpha) - * 3. repeat step 2 if at least one set first(A) has changed - * - */ - ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > firstOfNonterminal1; - - for ( const DefaultSymbolType & nonterminal : nonterminals ) - firstOfNonterminal1[nonterminal]; - - ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > firstOfNonterminal2 = firstOfNonterminal1; - - do { - for ( const std::pair < const DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > > & rule : rules ) - for ( const ext::vector < DefaultSymbolType > & rhs : rule.second ) { - ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > newFirst = first ( terminals, nonterminals, firstOfNonterminal1, rhs ); - firstOfNonterminal2[rule.first].insert ( newFirst.begin ( ), newFirst.end ( ) ); - } - - if ( firstOfNonterminal1 == firstOfNonterminal2 ) break; - - firstOfNonterminal1 = std::move ( firstOfNonterminal2 ); - firstOfNonterminal2.clear ( ); - - } while ( true ); - - return firstOfNonterminal1; -} - -template < class T > -ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > First::first ( const T & grammar ) { - ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) ); - - ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > res; - - for ( const std::pair < const DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > > & rule : grammar.getRawRules ( ) ) - for ( const ext::vector < DefaultSymbolType > & rhs : rule.second ) - res.insert ( std::make_pair ( rhs, first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), firstNt, rhs ) ) ); - - return res; -} - -template < class T > -ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > First::first ( const T & grammar, const ext::vector < DefaultSymbolType > & rhs ) { - ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) ); - - return first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), firstNt, rhs ); -} - -auto FirstCFG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::CFG < > > ( First::first ); -auto FirstEpsilonFreeCFG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::EpsilonFreeCFG < > > ( First::first ); -auto FirstGNF = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::GNF < > > ( First::first ); -auto FirstCNF = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::CNF < > > ( First::first ); -auto FirstLG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::LG < > > ( First::first ); -auto FirstLeftLG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::LeftLG < > > ( First::first ); -auto FirstLeftRG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::LeftRG < > > ( First::first ); -auto FirstRightLG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::RightLG < > > ( First::first ); -auto FirstRightRG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::RightRG < > > ( First::first ); - -ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > First::first ( const grammar::Grammar & grammar ) { - return FirstBase1::dispatch ( grammar.getData ( ) ); -} - -auto FirstCFG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::CFG < > > ( First::first ); -auto FirstEpsilonFreeCFG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::EpsilonFreeCFG < > > ( First::first ); -auto FirstGNF2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::GNF < > > ( First::first ); -auto FirstCNF2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::CNF < > > ( First::first ); -auto FirstLG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::LG < > > ( First::first ); -auto FirstLeftLG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::LeftLG < > > ( First::first ); -auto FirstLeftRG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::LeftRG < > > ( First::first ); -auto FirstRightLG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::RightLG < > > ( First::first ); -auto FirstRightRG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::RightRG < > > ( First::first ); - -ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > First::first ( const grammar::Grammar & grammar, const ext::vector < DefaultSymbolType > & rhs ) { - return FirstBase2::dispatch ( grammar.getData ( ), rhs ); -} +auto FirstCFG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::CFG < > & > ( First::first ); +auto FirstEpsilonFreeCFG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::EpsilonFreeCFG < > & > ( First::first ); +auto FirstGNF = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::GNF < > & > ( First::first ); +auto FirstCNF = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::CNF < > & > ( First::first ); +auto FirstLG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::LG < > & > ( First::first ); +auto FirstLeftLG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::LeftLG < > & > ( First::first ); +auto FirstLeftRG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::LeftRG < > & > ( First::first ); +auto FirstRightLG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::RightLG < > & > ( First::first ); +auto FirstRightRG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::RightRG < > & > ( First::first ); + +auto FirstCFG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::CFG < > &, const ext::vector < DefaultSymbolType > & > ( First::first ); +auto FirstEpsilonFreeCFG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::EpsilonFreeCFG < > &, const ext::vector < DefaultSymbolType > & > ( First::first ); +auto FirstGNF2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::GNF < > &, const ext::vector < DefaultSymbolType > & > ( First::first ); +auto FirstCNF2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::CNF < > &, const ext::vector < DefaultSymbolType > & > ( First::first ); +auto FirstLG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::LG < > &, const ext::vector < DefaultSymbolType > & > ( First::first ); +auto FirstLeftLG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::LeftLG < > &, const ext::vector < DefaultSymbolType > & > ( First::first ); +auto FirstLeftRG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::LeftRG < > &, const ext::vector < DefaultSymbolType > & > ( First::first ); +auto FirstRightLG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::RightLG < > &, const ext::vector < DefaultSymbolType > & > ( First::first ); +auto FirstRightRG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::RightRG < > &, const ext::vector < DefaultSymbolType > & > ( First::first ); } /* namespace parsing */ diff --git a/alib2algo_experimental/src/grammar/parsing/First.h b/alib2algo_experimental/src/grammar/parsing/First.h index b63bf80963ad9f55fbd4f1eb247314c68d3291e1..a1fcf5c1d211aac3ad1a712c3242a66bab23abc0 100644 --- a/alib2algo_experimental/src/grammar/parsing/First.h +++ b/alib2algo_experimental/src/grammar/parsing/First.h @@ -8,10 +8,8 @@ #ifndef FIRST_H_ #define FIRST_H_ -#include <core/multipleDispatch.hpp> -#include <grammar/Grammar.h> -#include <alphabet/Symbol.h> #include <string/Epsilon.h> +#include <grammar/Grammar.h> #include <vector> #include <set> #include <variant> @@ -20,32 +18,106 @@ namespace grammar { namespace parsing { -class First; - -typedef ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > FirstResult1; -typedef alib::SingleDispatch < First, FirstResult1, const grammar::GrammarBase & > FirstBase1; - -typedef ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > FirstResult2; -typedef alib::SingleDispatch < First, FirstResult2, const grammar::GrammarBase &, const ext::vector < DefaultSymbolType > & > FirstBase2; - -class First : public FirstBase1, public FirstBase2 { - static ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > first ( const ext::set < DefaultSymbolType > & terminals, const ext::set < DefaultSymbolType > & nonterminals, const ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > & firstOfNonterminal, const ext::vector < DefaultSymbolType > & rhs ); +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::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > first ( const ext::set < DefaultSymbolType > & terminals, const ext::set < DefaultSymbolType > & nonterminals, const ext::map < DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > > & rules ); + 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 ); public: - template < class T > - static FirstResult1 first ( const T & grammar ); - - template < class T > - static FirstResult2 first ( const T & grammar, const ext::vector < DefaultSymbolType > & rhs ); - - static FirstResult1 first ( const grammar::Grammar & grammar ); - - static FirstResult2 first ( const grammar::Grammar & grammar, const ext::vector < DefaultSymbolType > & rhs ); + 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 ); + 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 ); }; +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 ) { + // 1. FIRST(\varepsilon) = { \varepsilon } + if ( rhs.size ( ) == 0 ) { + return { string::Epsilon < >::EPSILON }; + } + + // 2. FIRST(a) = { a } forall a \in T + else if ( terminals.count ( rhs[0] ) ) { + return { rhs[0] }; + } + + // 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 ) ) { + 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 ); + + ext::set < ext::variant < SymbolType, string::Epsilon < > > > next = first ( terminals, nonterminals, firstOfNonterminal, ext::vector < SymbolType > ( rhs.begin ( ) + 1, rhs.end ( ) ) ); + res.insert ( next.begin ( ), next.end ( ) ); + return res; + } else { + throw exception::CommonException ( "Cant be reached" ); + } +} + +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 ) { + /* + * + * 1. foreach A \in N: first(A) = \emptyset + * 2. foreach A \rightarrow \alpha: + * first(A) = first(A) \cup FIRST(\alpha) + * 3. repeat step 2 if at least one set first(A) has changed + * + */ + ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > firstOfNonterminal1; + + for ( const SymbolType & nonterminal : nonterminals ) + firstOfNonterminal1[nonterminal]; + + ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > 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 ); + firstOfNonterminal2[rule.first].insert ( newFirst.begin ( ), newFirst.end ( ) ); + } + + if ( firstOfNonterminal1 == firstOfNonterminal2 ) + break; + + firstOfNonterminal1 = std::move ( firstOfNonterminal2 ); + firstOfNonterminal2.clear ( ); + + } while ( true ); + + return firstOfNonterminal1; +} + +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 < > > > > res; + + for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & rule : grammar.getRawRules ( ) ) + for ( const ext::vector < SymbolType > & rhs : rule.second ) + res.insert ( std::make_pair ( rhs, first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), firstNt, rhs ) ) ); + + return res; +} + +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 ( ) ); + + return first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), firstNt, rhs ); +} + } /* namespace parsing */ } /* namespace grammar */ diff --git a/alib2algo_experimental/src/grammar/parsing/Follow.cpp b/alib2algo_experimental/src/grammar/parsing/Follow.cpp index fd1345a495d369b5c796ebc0b34ccbb1073cc003..e204ce31822809f59fcb34fb6afebb15a82b17d4 100644 --- a/alib2algo_experimental/src/grammar/parsing/Follow.cpp +++ b/alib2algo_experimental/src/grammar/parsing/Follow.cpp @@ -6,10 +6,6 @@ */ #include "Follow.h" -#include "First.h" -#include <algorithm> -#include <string/Epsilon.h> -#include <iterator> #include <grammar/ContextFree/CFG.h> #include <grammar/ContextFree/EpsilonFreeCFG.h> @@ -20,106 +16,31 @@ #include <grammar/Regular/LeftRG.h> #include <grammar/Regular/RightLG.h> #include <grammar/Regular/RightRG.h> -#include <exception/CommonException.h> #include <registration/AlgoRegistration.hpp> namespace grammar { namespace parsing { -template < class T > -void Follow::follow ( const T & grammar, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > & followSet ) { - for ( const std::pair < const DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > > & rule : grammar.getRawRules ( ) ) { - const DefaultSymbolType & X = rule.first; - - for ( const ext::vector < DefaultSymbolType > & rhs : rule.second ) - // every nt in rhs is Y - for ( ext::vector < DefaultSymbolType >::const_iterator it = rhs.begin ( ); it != rhs.end ( ); it++ ) { - const DefaultSymbolType & Y = * it; - - if ( !grammar.getNonterminalAlphabet ( ).count ( Y ) ) continue; - - ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > firstBeta = First::first ( grammar, ext::vector < DefaultSymbolType > ( std::next ( it ), rhs.end ( ) ) ); - - if ( firstBeta.count ( string::Epsilon < >::EPSILON ) ) { - firstBeta.erase ( string::Epsilon < >::EPSILON ); - followSet[Y].insert ( followSet[X].begin ( ), followSet[X].end ( ) ); - } - - followSet[Y].insert ( firstBeta.begin ( ), firstBeta.end ( ) ); - } - - } -} - -template < class T > -ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > Follow::follow ( const T & grammar ) { - /* - * 1. Follow(S) = { \varepsilon } - * Follow(A) = {} forall A \in N, A \neq S - * 2. Forall p \in P: - * if p == X -> \alpha Y \beta - * Follow(Y) = Follow(Y) \cup (First(\beta) \setminus { \varepsilon}) - * if p == X -> \alpha Y \beta \wedge \varepsilon \in First(\beta) - * Follow(Y) = Follow(Y) \cup Follow(X) - * 3. goto 2 if any follow set was changed in prev step. - */ - - ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > followSet1; - - for ( const DefaultSymbolType & symb : grammar.getNonterminalAlphabet ( ) ) - followSet1[symb]; - - followSet1[grammar.getInitialSymbol ( )] = { string::Epsilon < >::EPSILON }; - - ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > followSet2 = followSet1; - - do { - follow ( grammar, followSet2 ); - - if ( followSet1 == followSet2 ) break; - - followSet1 = followSet2; - } while ( true ); - - return followSet1; -} - -template < class T > -ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > Follow::follow ( const T & grammar, const DefaultSymbolType & nt ) { - if ( !grammar.getNonterminalAlphabet ( ).count ( nt ) ) - throw exception::CommonException ( "Follow: Given symbol is not nonterminal." ); - - return follow ( grammar )[nt]; -} - -auto FollowCFG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::CFG < > > ( Follow::follow ); -auto FollowEpsilonFreeCFG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::EpsilonFreeCFG < > > ( Follow::follow ); -auto FollowGNF = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::GNF < > > ( Follow::follow ); -auto FollowCNF = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::CNF < > > ( Follow::follow ); -auto FollowLG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::LG < > > ( Follow::follow ); -auto FollowLeftLG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::LeftLG < > > ( Follow::follow ); -auto FollowLeftRG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::LeftRG < > > ( Follow::follow ); -auto FollowRightLG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::RightLG < > > ( Follow::follow ); -auto FollowRightRG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::RightRG < > > ( Follow::follow ); - -ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > Follow::follow ( const grammar::Grammar & grammar ) { - return FollowBase1::dispatch ( grammar.getData ( ) ); -} - -auto FollowCFG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::CFG < > > ( Follow::follow ); -auto FollowEpsilonFreeCFG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::EpsilonFreeCFG < > > ( Follow::follow ); -auto FollowGNF2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::GNF < > > ( Follow::follow ); -auto FollowCNF2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::CNF < > > ( Follow::follow ); -auto FollowLG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::LG < > > ( Follow::follow ); -auto FollowLeftLG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::LeftLG < > > ( Follow::follow ); -auto FollowLeftRG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::LeftRG < > > ( Follow::follow ); -auto FollowRightLG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::RightLG < > > ( Follow::follow ); -auto FollowRightRG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::RightRG < > > ( Follow::follow ); - -ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > Follow::follow ( const grammar::Grammar & grammar, const DefaultSymbolType & nt ) { - return FollowBase2::dispatch ( grammar.getData ( ), nt ); -} +auto FollowCFG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::CFG < > & > ( Follow::follow ); +auto FollowEpsilonFreeCFG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::EpsilonFreeCFG < > & > ( Follow::follow ); +auto FollowGNF = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::GNF < > & > ( Follow::follow ); +auto FollowCNF = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::CNF < > & > ( Follow::follow ); +auto FollowLG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::LG < > & > ( Follow::follow ); +auto FollowLeftLG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::LeftLG < > & > ( Follow::follow ); +auto FollowLeftRG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::LeftRG < > & > ( Follow::follow ); +auto FollowRightLG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::RightLG < > & > ( Follow::follow ); +auto FollowRightRG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::RightRG < > & > ( Follow::follow ); + +auto FollowCFG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::CFG < > &, const DefaultSymbolType & > ( Follow::follow ); +auto FollowEpsilonFreeCFG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::EpsilonFreeCFG < > &, const DefaultSymbolType & > ( Follow::follow ); +auto FollowGNF2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::GNF < > &, const DefaultSymbolType & > ( Follow::follow ); +auto FollowCNF2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::CNF < > &, const DefaultSymbolType & > ( Follow::follow ); +auto FollowLG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::LG < > &, const DefaultSymbolType & > ( Follow::follow ); +auto FollowLeftLG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::LeftLG < > &, const DefaultSymbolType & > ( Follow::follow ); +auto FollowLeftRG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::LeftRG < > &, const DefaultSymbolType & > ( Follow::follow ); +auto FollowRightLG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::RightLG < > &, const DefaultSymbolType & > ( Follow::follow ); +auto FollowRightRG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::RightRG < > &, const DefaultSymbolType & > ( Follow::follow ); } /* namespace parsing */ diff --git a/alib2algo_experimental/src/grammar/parsing/Follow.h b/alib2algo_experimental/src/grammar/parsing/Follow.h index 958517999e5d4c23795988b08c63604eab920a7f..b7ac8452b5037eaf0fab77987ae5f8e288fe1270 100644 --- a/alib2algo_experimental/src/grammar/parsing/Follow.h +++ b/alib2algo_experimental/src/grammar/parsing/Follow.h @@ -8,56 +8,102 @@ #ifndef FOLLOW_H_ #define FOLLOW_H_ -#include <core/multipleDispatch.hpp> -#include <grammar/Grammar.h> -#include <alphabet/Symbol.h> -#include <string/Epsilon.h> #include <vector> #include <set> #include <variant> +#include <algorithm> +#include <iterator> + +#include <exception/CommonException.h> + +#include <grammar/Grammar.h> +#include <string/Epsilon.h> + +#include "First.h" namespace grammar { namespace parsing { -class Follow; +class Follow { + template < class T, class SymbolType > + static void follow ( const T & grammar, ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > & 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 ); + + template < class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > > + static ext::set < ext::variant < SymbolType, string::Epsilon < > > > follow ( const T & grammar, const SymbolType & nt ); +}; -typedef ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > FollowResult1; -typedef alib::SingleDispatch < Follow, FollowResult1, const grammar::GrammarBase & > FollowBase1; +template < class T, class SymbolType > +void Follow::follow ( const T & grammar, ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > & followSet ) { + for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & rule : grammar.getRawRules ( ) ) { + const SymbolType & X = rule.first; -typedef ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > FollowResult2; -typedef alib::SingleDispatch < Follow, FollowResult2, const grammar::GrammarBase &, const DefaultSymbolType & > FollowBase2; + for ( const ext::vector < SymbolType > & rhs : rule.second ) + // every nt in rhs is Y + for ( typename ext::vector < SymbolType >::const_iterator it = rhs.begin ( ); it != rhs.end ( ); it++ ) { + const SymbolType & Y = * it; -class Follow : public FollowBase1, public FollowBase2 { - template < class T > - static void follow ( const T & grammar, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > & followSet ); + if ( !grammar.getNonterminalAlphabet ( ).count ( Y ) ) + continue; - static Follow & getInstance ( ) { - static Follow res; + ext::set < ext::variant < SymbolType, string::Epsilon < > > > firstBeta = First::first ( grammar, ext::vector < SymbolType > ( std::next ( it ), rhs.end ( ) ) ); + + if ( firstBeta.count ( string::Epsilon < >::EPSILON ) ) { + firstBeta.erase ( string::Epsilon < >::EPSILON ); + followSet[Y].insert ( followSet[X].begin ( ), followSet[X].end ( ) ); + } + + followSet[Y].insert ( firstBeta.begin ( ), firstBeta.end ( ) ); + } - return res; } +} -public: - static FollowResult1 follow ( const grammar::Grammar & grammar ); +template < class T, class SymbolType > +ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > Follow::follow ( const T & grammar ) { + /* + * 1. Follow(S) = { \varepsilon } + * Follow(A) = {} forall A \in N, A \neq S + * 2. Forall p \in P: + * if p == X -> \alpha Y \beta + * Follow(Y) = Follow(Y) \cup (First(\beta) \setminus { \varepsilon}) + * if p == X -> \alpha Y \beta \wedge \varepsilon \in First(\beta) + * Follow(Y) = Follow(Y) \cup Follow(X) + * 3. goto 2 if any follow set was changed in prev step. + */ - static FollowResult2 follow ( const grammar::Grammar & grammar, const DefaultSymbolType & nt ); + ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > followSet1; - template < class T > - static FollowResult1 follow ( const T & grammar ); + for ( const SymbolType & symb : grammar.getNonterminalAlphabet ( ) ) + followSet1[symb]; - template < class T > - static FollowResult2 follow ( const T & grammar, const DefaultSymbolType & nt ); + followSet1[grammar.getInitialSymbol ( )] = { string::Epsilon < >::EPSILON }; - static FollowBase1 & getInstance1 ( ) { - return getInstance ( ); - } + ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > followSet2 = followSet1; - static FollowBase2 & getInstance2 ( ) { - return getInstance ( ); - } + do { + follow ( grammar, followSet2 ); -}; + if ( followSet1 == followSet2 ) + break; + + followSet1 = followSet2; + } while ( true ); + + return followSet1; +} + +template < class T, class SymbolType > +ext::set < ext::variant < SymbolType, string::Epsilon < > > > Follow::follow ( const T & grammar, const SymbolType & nt ) { + if ( !grammar.getNonterminalAlphabet ( ).count ( nt ) ) + throw exception::CommonException ( "Follow: Given symbol is not nonterminal." ); + + return follow ( grammar )[nt]; +} } /* namespace parsing */ diff --git a/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.cpp b/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.cpp index 9c04c5c6b5f1fd2231591686ead5410ff40db07c..e8e061dad535947e443d526007391d5d6f9aad17 100644 --- a/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.cpp +++ b/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.cpp @@ -6,8 +6,6 @@ */ #include "LL1ParseTable.h" -#include "First.h" -#include "Follow.h" #include <grammar/ContextFree/CFG.h> #include <grammar/ContextFree/EpsilonFreeCFG.h> @@ -24,46 +22,15 @@ namespace grammar { namespace parsing { -template < class T > -ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > > LL1ParseTable::parseTable ( const T & grammar ) { - ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > > res; - - ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > first = First::first ( grammar ); - ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > follow = Follow::follow ( grammar ); - - for ( const std::pair < const DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > > & transition : grammar.getRawRules ( ) ) { - const DefaultSymbolType & lhs = transition.first; - - for ( const ext::vector < DefaultSymbolType > & rhs : transition.second ) { - for ( const ext::variant < DefaultSymbolType, string::Epsilon < > > & firstElem : first[rhs] ) { - if ( firstElem.is < string::Epsilon < > > ( ) ) continue; - - res [ ext::make_pair ( firstElem, lhs ) ].insert ( rhs ); - } - - if ( first[rhs].count ( string::Epsilon < >::EPSILON ) ) - for ( const ext::variant < DefaultSymbolType, string::Epsilon < > > & followElem : follow[lhs] ) - res [ ext::make_pair ( followElem, lhs ) ].insert ( rhs ); - - } - } - - return res; -} - -auto LL1ParseTableCFG = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::CFG < > > ( LL1ParseTable::parseTable ); -auto LL1ParseTableEpsilonFreeCFG = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::EpsilonFreeCFG < > > ( LL1ParseTable::parseTable ); -auto LL1ParseTableGNF = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::GNF < > > ( LL1ParseTable::parseTable ); -auto LL1ParseTableCNF = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::CNF < > > ( LL1ParseTable::parseTable ); -auto LL1ParseTableLG = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::LG < > > ( LL1ParseTable::parseTable ); -auto LL1ParseTableLeftLG = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::LeftLG < > > ( LL1ParseTable::parseTable ); -auto LL1ParseTableLeftRG = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::LeftRG < > > ( LL1ParseTable::parseTable ); -auto LL1ParseTableRightLG = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::RightLG < > > ( LL1ParseTable::parseTable ); -auto LL1ParseTableRightRG = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::RightRG < > > ( LL1ParseTable::parseTable ); - -ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > > LL1ParseTable::parseTable ( const grammar::Grammar & grammar ) { - return dispatch ( grammar.getData ( ) ); -} +auto LL1ParseTableCFG = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::CFG < > & > ( LL1ParseTable::parseTable ); +auto LL1ParseTableEpsilonFreeCFG = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::EpsilonFreeCFG < > & > ( LL1ParseTable::parseTable ); +auto LL1ParseTableGNF = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::GNF < > & > ( LL1ParseTable::parseTable ); +auto LL1ParseTableCNF = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::CNF < > & > ( LL1ParseTable::parseTable ); +auto LL1ParseTableLG = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::LG < > & > ( LL1ParseTable::parseTable ); +auto LL1ParseTableLeftLG = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::LeftLG < > & > ( LL1ParseTable::parseTable ); +auto LL1ParseTableLeftRG = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::LeftRG < > & > ( LL1ParseTable::parseTable ); +auto LL1ParseTableRightLG = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::RightLG < > & > ( LL1ParseTable::parseTable ); +auto LL1ParseTableRightRG = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::RightRG < > & > ( LL1ParseTable::parseTable ); } /* namespace parsing */ diff --git a/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h b/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h index af5d6ac199ef1478b2a5c72b6877a2a0353e0f87..d7c0a9da1985aa60d761da91d06dccfcb4f5e96d 100644 --- a/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h +++ b/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h @@ -8,28 +8,56 @@ #ifndef LL_1_PARSE_TABLE_H_ #define LL_1_PARSE_TABLE_H_ -#include <core/multipleDispatch.hpp> -#include <grammar/Grammar.h> -#include <alphabet/Symbol.h> -#include <string/Epsilon.h> #include <vector> #include <variant> #include <set> #include <map> +#include <grammar/Grammar.h> +#include <string/Epsilon.h> + +#include "First.h" +#include "Follow.h" + namespace grammar { namespace parsing { -class LL1ParseTable : public alib::SingleDispatch < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::GrammarBase & > { +class LL1ParseTable { public: - template < class T > - static ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > > parseTable ( const T & grammar ); - - static ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > > parseTable ( const grammar::Grammar & grammar ); + template < class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > > + static ext::map < ext::pair < ext::variant < SymbolType, string::Epsilon < > >, SymbolType >, ext::set < ext::vector < SymbolType > > > parseTable ( const T & grammar ); }; +template < class T, class SymbolType > +ext::map < ext::pair < ext::variant < SymbolType, string::Epsilon < > >, SymbolType >, ext::set < ext::vector < SymbolType > > > LL1ParseTable::parseTable ( const T & grammar ) { + ext::map < ext::pair < ext::variant < SymbolType, string::Epsilon < > >, SymbolType >, ext::set < ext::vector < SymbolType > > > res; + + ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > first = First::first ( grammar ); + ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > follow = Follow::follow ( grammar ); + + for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & transition : grammar.getRawRules ( ) ) { + const SymbolType & lhs = transition.first; + + for ( const ext::vector < SymbolType > & rhs : transition.second ) { + for ( const ext::variant < SymbolType, string::Epsilon < > > & firstElem : first[rhs] ) { + if ( firstElem.template is < string::Epsilon < > > ( ) ) + continue; + + res [ ext::make_pair ( firstElem, lhs ) ].insert ( rhs ); + } + + if ( first[rhs].count ( string::Epsilon < >::EPSILON ) ) + for ( const ext::variant < SymbolType, string::Epsilon < > > & followElem : follow[lhs] ) + res [ ext::make_pair ( followElem, lhs ) ].insert ( rhs ); + + } + } + + return res; +} + } /* namespace parsing */ } /* namespace grammar */ diff --git a/alib2algo_experimental/src/grammar/parsing/LeftFactorize.h b/alib2algo_experimental/src/grammar/parsing/LeftFactorize.h index e13f3db71ea6deb855ad596614cbf2b226317e92..e698e2225b882da54b2a13e9638f45bcd412a160 100644 --- a/alib2algo_experimental/src/grammar/parsing/LeftFactorize.h +++ b/alib2algo_experimental/src/grammar/parsing/LeftFactorize.h @@ -8,7 +8,6 @@ #ifndef LEFT_FACTORIZE_H_ #define LEFT_FACTORIZE_H_ -#include <core/multipleDispatch.hpp> #include <alphabet/Symbol.h> #include <grammar/GrammarFeatures.h> diff --git a/alib2algo_experimental/src/grammar/parsing/SLR1ParseTable.cpp b/alib2algo_experimental/src/grammar/parsing/SLR1ParseTable.cpp index a62e2e21de793b44becec6bbebdf2b657229467b..cd77940f7668f08bb82453aa0f4cb5f4f4a62e13 100644 --- a/alib2algo_experimental/src/grammar/parsing/SLR1ParseTable.cpp +++ b/alib2algo_experimental/src/grammar/parsing/SLR1ParseTable.cpp @@ -45,7 +45,7 @@ LRActionTable SLR1ParseTable::getActionTable ( grammar::CFG < > originalGrammar continue; } - grammar::parsing::FollowResult2 followSet = grammar::parsing::Follow::follow ( augmentedGrammar, leftHandSide ); + ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > followSet = grammar::parsing::Follow::follow ( augmentedGrammar, leftHandSide ); ext::pair < DefaultSymbolType, ext::vector < DefaultSymbolType > > currentRule = { leftHandSide, rightHandSide }; for ( const ext::variant < DefaultSymbolType, string::Epsilon < > > & followSymbol : followSet ) { if ( followSymbol.is < DefaultSymbolType > ( ) ) { diff --git a/alib2algo_experimental/src/grammar/parsing/common/Substitute.h b/alib2algo_experimental/src/grammar/parsing/common/Substitute.h index 398cbb000bf97537f1e6db5dbaac65af9864da59..f6a9ac46e4e58b6afa415cb0a84a34e4a5d24d8c 100644 --- a/alib2algo_experimental/src/grammar/parsing/common/Substitute.h +++ b/alib2algo_experimental/src/grammar/parsing/common/Substitute.h @@ -8,7 +8,6 @@ #ifndef SUBSTITUTE_H_ #define SUBSTITUTE_H_ -#include <core/multipleDispatch.hpp> #include <grammar/GrammarFeatures.h> #include <alphabet/Symbol.h> #include <vector> @@ -17,7 +16,7 @@ namespace grammar { namespace parsing { -class Substitute { +class Substitute { public: static void substitute ( const grammar::CFG < > & orig, grammar::CFG < > & res, const DefaultSymbolType & origLHS, const ext::vector < DefaultSymbolType > & origRHS, ext::vector < DefaultSymbolType >::const_iterator nonterminal );