From 55153c9630f10e663ec0b32b3229b0164922c4d6 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Wed, 14 Oct 2015 20:02:58 +0200 Subject: [PATCH] format changed files --- alib2algo/src/grammar/parsing/First.cpp | 147 +++---- alib2algo/src/grammar/parsing/First.h | 36 +- alib2algo/src/grammar/parsing/Follow.cpp | 82 ++-- alib2algo/src/grammar/parsing/Follow.h | 16 +- .../test-src/grammar/parsing/FirstTest.cpp | 360 ++++++++++-------- .../test-src/grammar/parsing/FirstTest.h | 23 +- .../test-src/grammar/parsing/FollowTest.cpp | 240 ++++++------ 7 files changed, 485 insertions(+), 419 deletions(-) diff --git a/alib2algo/src/grammar/parsing/First.cpp b/alib2algo/src/grammar/parsing/First.cpp index 61d290a235..5ceb536b9b 100644 --- a/alib2algo/src/grammar/parsing/First.cpp +++ b/alib2algo/src/grammar/parsing/First.cpp @@ -22,32 +22,36 @@ namespace grammar { namespace parsing { -std::set<std::variant<alphabet::Symbol, string::Epsilon>> First::first(const std::set<alphabet::Symbol>& terminals, const std::set<alphabet::Symbol>& nonterminals, const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& firstOfNonterminal, const std::vector<alphabet::Symbol>& 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)) { - std::set<std::variant<alphabet::Symbol, string::Epsilon>> res = firstOfNonterminal.find(rhs[0])->second; - res.erase(string::Epsilon::EPSILON); - - std::set<std::variant<alphabet::Symbol, string::Epsilon>> next = first(terminals, nonterminals, firstOfNonterminal, std::vector<alphabet::Symbol>(rhs.begin() + 1, rhs.end())); - res.insert(next.begin(), next.end()); +std::set < std::variant < alphabet::Symbol, string::Epsilon > > First::first ( const std::set < alphabet::Symbol > & terminals, const std::set < alphabet::Symbol > & nonterminals, const std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > & firstOfNonterminal, const std::vector < alphabet::Symbol > & 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 ) ) { + std::set < std::variant < alphabet::Symbol, string::Epsilon > > res = firstOfNonterminal.find ( rhs[0] )->second; + res.erase ( string::Epsilon::EPSILON ); + + std::set < std::variant < alphabet::Symbol, string::Epsilon > > next = first ( terminals, nonterminals, firstOfNonterminal, std::vector < alphabet::Symbol > ( rhs.begin ( ) + 1, rhs.end ( ) ) ); + res.insert ( next.begin ( ), next.end ( ) ); return res; - } else - throw exception::AlibException("Cant be reached"); + } else { + throw exception::AlibException ( "Cant be reached" ); + } } -std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> First::first(const std::set<alphabet::Symbol>& terminals, const std::set<alphabet::Symbol>& nonterminals, const std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>>& rules) { +std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > First::first ( const std::set < alphabet::Symbol > & terminals, const std::set < alphabet::Symbol > & nonterminals, const std::map < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > > & rules ) { /* * * 1. foreach A \in N: first(A) = \emptyset @@ -56,77 +60,76 @@ std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsil * 3. repeat step 2 if at least one set first(A) has changed * */ - std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> firstOfNonterminal1; - for(const alphabet::Symbol& nonterminal : nonterminals) + std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > firstOfNonterminal1; + + for ( const alphabet::Symbol & nonterminal : nonterminals ) firstOfNonterminal1[nonterminal]; - std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> firstOfNonterminal2 = firstOfNonterminal1; + std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > firstOfNonterminal2 = firstOfNonterminal1; do { - for(const std::pair<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>>& rule : rules) { - for(const std::vector<alphabet::Symbol>& rhs : rule.second) { - std::set<std::variant<alphabet::Symbol, string::Epsilon>> newFirst = first(terminals, nonterminals, firstOfNonterminal1, rhs); - firstOfNonterminal2[rule.first].insert(newFirst.begin(), newFirst.end()); + for ( const std::pair < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > > & rule : rules ) + for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) { + std::set < std::variant < alphabet::Symbol, string::Epsilon > > newFirst = first ( terminals, nonterminals, firstOfNonterminal1, rhs ); + firstOfNonterminal2[rule.first].insert ( newFirst.begin ( ), newFirst.end ( ) ); } - } - if(firstOfNonterminal1 == firstOfNonterminal2) break; + if ( firstOfNonterminal1 == firstOfNonterminal2 ) break; - firstOfNonterminal1 = std::move(firstOfNonterminal2); - firstOfNonterminal2.clear(); + firstOfNonterminal1 = std::move ( firstOfNonterminal2 ); + firstOfNonterminal2.clear ( ); - } while(true); + } while ( true ); return firstOfNonterminal1; } -template<class T> -std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> First::first( const T & grammar ) { - std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> firstNt = first(grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet(), grammar.getRawRules()); +template < class T > +std::map < std::vector < alphabet::Symbol >, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > First::first ( const T & grammar ) { + std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) ); - std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> res; - for(const std::pair<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>>& rule : grammar.getRawRules()) { - for(const std::vector<alphabet::Symbol>& rhs : rule.second) { - res.insert(make_pair(rhs, first(grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet(), firstNt, rhs))); - } - } + std::map < std::vector < alphabet::Symbol >, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > res; + + for ( const std::pair < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > > & rule : grammar.getRawRules ( ) ) + for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) + res.insert ( make_pair ( rhs, first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), firstNt, rhs ) ) ); return res; } -template<class T> -std::set<std::variant<alphabet::Symbol, string::Epsilon>> First::first(const T& grammar, const std::vector<alphabet::Symbol>& rhs) { - std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> firstNt = first(grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet(), grammar.getRawRules()); +template < class T > +std::set < std::variant < alphabet::Symbol, string::Epsilon > > First::first ( const T & grammar, const std::vector < alphabet::Symbol > & rhs ) { + std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) ); - return first(grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet(), firstNt, rhs); + return first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), firstNt, rhs ); } -auto FirstCFG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::CFG>(First::getInstance1(), First::first); -auto FirstEpsilonFreeCFG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::EpsilonFreeCFG>(First::getInstance1(), First::first); -auto FirstGNF = FirstBase1::RegistratorWrapper<FirstResult1, grammar::GNF>(First::getInstance1(), First::first); -auto FirstCNF = FirstBase1::RegistratorWrapper<FirstResult1, grammar::CNF>(First::getInstance1(), First::first); -auto FirstLG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::LG>(First::getInstance1(), First::first); -auto FirstLeftLG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::LeftLG>(First::getInstance1(), First::first); -auto FirstLeftRG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::LeftRG>(First::getInstance1(), First::first); -auto FirstRightLG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::RightLG>(First::getInstance1(), First::first); -auto FirstRightRG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::RightRG>(First::getInstance1(), First::first); - -std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> First::first(const grammar::Grammar& grammar) { - return getInstance1().dispatch(grammar.getData()); +auto FirstCFG = FirstBase1::RegistratorWrapper < FirstResult1, grammar::CFG > ( First::getInstance1 ( ), First::first ); +auto FirstEpsilonFreeCFG = FirstBase1::RegistratorWrapper < FirstResult1, grammar::EpsilonFreeCFG > ( First::getInstance1 ( ), First::first ); +auto FirstGNF = FirstBase1::RegistratorWrapper < FirstResult1, grammar::GNF > ( First::getInstance1 ( ), First::first ); +auto FirstCNF = FirstBase1::RegistratorWrapper < FirstResult1, grammar::CNF > ( First::getInstance1 ( ), First::first ); +auto FirstLG = FirstBase1::RegistratorWrapper < FirstResult1, grammar::LG > ( First::getInstance1 ( ), First::first ); +auto FirstLeftLG = FirstBase1::RegistratorWrapper < FirstResult1, grammar::LeftLG > ( First::getInstance1 ( ), First::first ); +auto FirstLeftRG = FirstBase1::RegistratorWrapper < FirstResult1, grammar::LeftRG > ( First::getInstance1 ( ), First::first ); +auto FirstRightLG = FirstBase1::RegistratorWrapper < FirstResult1, grammar::RightLG > ( First::getInstance1 ( ), First::first ); +auto FirstRightRG = FirstBase1::RegistratorWrapper < FirstResult1, grammar::RightRG > ( First::getInstance1 ( ), First::first ); + +std::map < std::vector < alphabet::Symbol >, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > First::first ( const grammar::Grammar & grammar ) { + return getInstance1 ( ).dispatch ( grammar.getData ( ) ); } -auto FirstCFG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::CFG>(First::getInstance2(), First::first); -auto FirstEpsilonFreeCFG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::EpsilonFreeCFG>(First::getInstance2(), First::first); -auto FirstGNF2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::GNF>(First::getInstance2(), First::first); -auto FirstCNF2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::CNF>(First::getInstance2(), First::first); -auto FirstLG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::LG>(First::getInstance2(), First::first); -auto FirstLeftLG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::LeftLG>(First::getInstance2(), First::first); -auto FirstLeftRG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::LeftRG>(First::getInstance2(), First::first); -auto FirstRightLG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::RightLG>(First::getInstance2(), First::first); -auto FirstRightRG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::RightRG>(First::getInstance2(), First::first); - -std::set<std::variant<alphabet::Symbol, string::Epsilon>> First::first(const grammar::Grammar& grammar, const std::vector<alphabet::Symbol>& rhs) { - return getInstance2().dispatch(grammar.getData(), rhs); +auto FirstCFG2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::CFG > ( First::getInstance2 ( ), First::first ); +auto FirstEpsilonFreeCFG2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::EpsilonFreeCFG > ( First::getInstance2 ( ), First::first ); +auto FirstGNF2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::GNF > ( First::getInstance2 ( ), First::first ); +auto FirstCNF2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::CNF > ( First::getInstance2 ( ), First::first ); +auto FirstLG2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::LG > ( First::getInstance2 ( ), First::first ); +auto FirstLeftLG2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::LeftLG > ( First::getInstance2 ( ), First::first ); +auto FirstLeftRG2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::LeftRG > ( First::getInstance2 ( ), First::first ); +auto FirstRightLG2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::RightLG > ( First::getInstance2 ( ), First::first ); +auto FirstRightRG2 = FirstBase2::RegistratorWrapper < FirstResult2, grammar::RightRG > ( First::getInstance2 ( ), First::first ); + +std::set < std::variant < alphabet::Symbol, string::Epsilon > > First::first ( const grammar::Grammar & grammar, const std::vector < alphabet::Symbol > & rhs ) { + return getInstance2 ( ).dispatch ( grammar.getData ( ), rhs ); } } /* namespace parsing */ diff --git a/alib2algo/src/grammar/parsing/First.h b/alib2algo/src/grammar/parsing/First.h index c01373e1a2..282ea1b477 100644 --- a/alib2algo/src/grammar/parsing/First.h +++ b/alib2algo/src/grammar/parsing/First.h @@ -20,40 +20,42 @@ namespace grammar { namespace parsing { -typedef std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> FirstResult1; -typedef std::SingleDispatch<FirstResult1, grammar::GrammarBase> FirstBase1; +typedef std::map < std::vector < alphabet::Symbol >, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > FirstResult1; +typedef std::SingleDispatch < FirstResult1, grammar::GrammarBase > FirstBase1; -typedef std::set<std::variant<alphabet::Symbol, string::Epsilon>> FirstResult2; -typedef std::SingleDispatchLastStaticParam<FirstResult2, grammar::GrammarBase, const std::vector<alphabet::Symbol>&> FirstBase2; +typedef std::set < std::variant < alphabet::Symbol, string::Epsilon > > FirstResult2; +typedef std::SingleDispatchLastStaticParam < FirstResult2, grammar::GrammarBase, const std::vector < alphabet::Symbol > & > FirstBase2; class First : public FirstBase1, public FirstBase2 { - static std::set<std::variant<alphabet::Symbol, string::Epsilon>> first(const std::set<alphabet::Symbol>& terminals, const std::set<alphabet::Symbol>& nonterminals, const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& firstOfNonterminal, const std::vector<alphabet::Symbol>& rhs); + static std::set < std::variant < alphabet::Symbol, string::Epsilon > > first ( const std::set < alphabet::Symbol > & terminals, const std::set < alphabet::Symbol > & nonterminals, const std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > & firstOfNonterminal, const std::vector < alphabet::Symbol > & rhs ); - static std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> first(const std::set<alphabet::Symbol>& terminals, const std::set<alphabet::Symbol>& nonterminals, const std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>>& rules); + static std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > first ( const std::set < alphabet::Symbol > & terminals, const std::set < alphabet::Symbol > & nonterminals, const std::map < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > > & rules ); - static First& getInstance() { + static First & getInstance ( ) { static First res; + return res; } public: - template<class T> - static FirstResult1 first( const T & grammar ); + template < class T > + static FirstResult1 first ( const T & grammar ); - template<class T> - static FirstResult2 first(const T& grammar, const std::vector<alphabet::Symbol>& rhs); + template < class T > + static FirstResult2 first ( const T & grammar, const std::vector < alphabet::Symbol > & rhs ); - static FirstResult1 first(const grammar::Grammar& grammar); + static FirstResult1 first ( const grammar::Grammar & grammar ); - static FirstResult2 first(const grammar::Grammar& grammar, const std::vector<alphabet::Symbol>& rhs); + static FirstResult2 first ( const grammar::Grammar & grammar, const std::vector < alphabet::Symbol > & rhs ); - static FirstBase1& getInstance1() { - return getInstance(); + static FirstBase1 & getInstance1 ( ) { + return getInstance ( ); } - static FirstBase2& getInstance2() { - return getInstance(); + static FirstBase2 & getInstance2 ( ) { + return getInstance ( ); } + }; } /* namespace parsing */ diff --git a/alib2algo/src/grammar/parsing/Follow.cpp b/alib2algo/src/grammar/parsing/Follow.cpp index dfc2ec98a8..cd4a99e343 100644 --- a/alib2algo/src/grammar/parsing/Follow.cpp +++ b/alib2algo/src/grammar/parsing/Follow.cpp @@ -26,33 +26,35 @@ namespace grammar { namespace parsing { -template<class T> -void Follow::follow(const T& grammar, std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& followSet) { - for(const std::pair<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>>& rule : grammar.getRawRules()) { - const alphabet::Symbol& X = rule.first; - for(const std::vector<alphabet::Symbol>& rhs : rule.second) { - // every nt in rhs is Y - for(std::vector<alphabet::Symbol>::const_iterator it = rhs.begin(); it != rhs.end(); it++) { - const alphabet::Symbol& Y = *it; - if(!grammar.getNonterminalAlphabet().count(Y)) continue; - - std::set<std::variant<alphabet::Symbol, string::Epsilon>> firstBeta = First::first(grammar, std::vector<alphabet::Symbol>(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()); +template < class T > +void Follow::follow ( const T & grammar, std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > & followSet ) { + for ( const std::pair < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > > & rule : grammar.getRawRules ( ) ) { + const alphabet::Symbol & X = rule.first; + + for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) + // every nt in rhs is Y + for ( std::vector < alphabet::Symbol >::const_iterator it = rhs.begin ( ); it != rhs.end ( ); it++ ) { + const alphabet::Symbol & Y = * it; + + if ( !grammar.getNonterminalAlphabet ( ).count ( Y ) ) continue; + + std::set < std::variant < alphabet::Symbol, string::Epsilon > > firstBeta = First::first ( grammar, std::vector < alphabet::Symbol > ( 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()); + followSet[Y].insert ( firstBeta.begin ( ), firstBeta.end ( ) ); } - } + } } -template<class T> -std::set<std::variant<alphabet::Symbol, string::Epsilon>> Follow::follow(const T& grammar, const alphabet::Symbol& nt) { - if(!grammar.getNonterminalAlphabet().count(nt)) - throw exception::AlibException("Follow: Given symbol is not nonterminal."); +template < class T > +std::set < std::variant < alphabet::Symbol, string::Epsilon > > Follow::follow ( const T & grammar, const alphabet::Symbol & nt ) { + if ( !grammar.getNonterminalAlphabet ( ).count ( nt ) ) + throw exception::AlibException ( "Follow: Given symbol is not nonterminal." ); /* * 1. Follow(S) = { \varepsilon } @@ -65,38 +67,38 @@ std::set<std::variant<alphabet::Symbol, string::Epsilon>> Follow::follow(const T * 3. goto 2 if any follow set was changed in prev step. */ - std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> followSet1; + std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > followSet1; - for(const alphabet::Symbol& symb : grammar.getNonterminalAlphabet()) + for ( const alphabet::Symbol & symb : grammar.getNonterminalAlphabet ( ) ) followSet1[symb]; - followSet1[grammar.getInitialSymbol()] = {string::Epsilon::EPSILON}; + followSet1[grammar.getInitialSymbol ( )] = { string::Epsilon::EPSILON }; - std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> followSet2 = followSet1; + std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > followSet2 = followSet1; do { - follow(grammar, followSet2); + follow ( grammar, followSet2 ); - if(followSet1 == followSet2) break; + if ( followSet1 == followSet2 ) break; followSet1 = followSet2; - } while(true); + } while ( true ); return followSet1[nt]; } -auto FollowCFG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::CFG>(Follow::getInstance(), Follow::follow); -auto FollowEpsilonFreeCFG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::EpsilonFreeCFG>(Follow::getInstance(), Follow::follow); -auto FollowGNF = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::GNF>(Follow::getInstance(), Follow::follow); -auto FollowCNF = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::CNF>(Follow::getInstance(), Follow::follow); -auto FollowLG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::LG>(Follow::getInstance(), Follow::follow); -auto FollowLeftLG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::LeftLG>(Follow::getInstance(), Follow::follow); -auto FollowLeftRG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::LeftRG>(Follow::getInstance(), Follow::follow); -auto FollowRightLG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::RightLG>(Follow::getInstance(), Follow::follow); -auto FollowRightRG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::RightRG>(Follow::getInstance(), Follow::follow); - -std::set<std::variant<alphabet::Symbol, string::Epsilon>> Follow::follow(const grammar::Grammar& grammar, const alphabet::Symbol& nt) { - return getInstance().dispatch(grammar.getData(), nt); +auto FollowCFG = Follow::RegistratorWrapper < std::set < std::variant < alphabet::Symbol, string::Epsilon > >, grammar::CFG > ( Follow::getInstance ( ), Follow::follow ); +auto FollowEpsilonFreeCFG = Follow::RegistratorWrapper < std::set < std::variant < alphabet::Symbol, string::Epsilon > >, grammar::EpsilonFreeCFG > ( Follow::getInstance ( ), Follow::follow ); +auto FollowGNF = Follow::RegistratorWrapper < std::set < std::variant < alphabet::Symbol, string::Epsilon > >, grammar::GNF > ( Follow::getInstance ( ), Follow::follow ); +auto FollowCNF = Follow::RegistratorWrapper < std::set < std::variant < alphabet::Symbol, string::Epsilon > >, grammar::CNF > ( Follow::getInstance ( ), Follow::follow ); +auto FollowLG = Follow::RegistratorWrapper < std::set < std::variant < alphabet::Symbol, string::Epsilon > >, grammar::LG > ( Follow::getInstance ( ), Follow::follow ); +auto FollowLeftLG = Follow::RegistratorWrapper < std::set < std::variant < alphabet::Symbol, string::Epsilon > >, grammar::LeftLG > ( Follow::getInstance ( ), Follow::follow ); +auto FollowLeftRG = Follow::RegistratorWrapper < std::set < std::variant < alphabet::Symbol, string::Epsilon > >, grammar::LeftRG > ( Follow::getInstance ( ), Follow::follow ); +auto FollowRightLG = Follow::RegistratorWrapper < std::set < std::variant < alphabet::Symbol, string::Epsilon > >, grammar::RightLG > ( Follow::getInstance ( ), Follow::follow ); +auto FollowRightRG = Follow::RegistratorWrapper < std::set < std::variant < alphabet::Symbol, string::Epsilon > >, grammar::RightRG > ( Follow::getInstance ( ), Follow::follow ); + +std::set < std::variant < alphabet::Symbol, string::Epsilon > > Follow::follow ( const grammar::Grammar & grammar, const alphabet::Symbol & nt ) { + return getInstance ( ).dispatch ( grammar.getData ( ), nt ); } } /* namespace parsing */ diff --git a/alib2algo/src/grammar/parsing/Follow.h b/alib2algo/src/grammar/parsing/Follow.h index e5d6a0800a..9e965dabb6 100644 --- a/alib2algo/src/grammar/parsing/Follow.h +++ b/alib2algo/src/grammar/parsing/Follow.h @@ -20,20 +20,22 @@ namespace grammar { namespace parsing { -class Follow : public std::SingleDispatchLastStaticParam<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::GrammarBase, const alphabet::Symbol&> { - template<class T> - static void follow(const T& grammar, std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& followSet); +class Follow : public std::SingleDispatchLastStaticParam < std::set < std::variant < alphabet::Symbol, string::Epsilon > >, grammar::GrammarBase, const alphabet::Symbol & > { + template < class T > + static void follow ( const T & grammar, std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > & followSet ); public: - static std::set<std::variant<alphabet::Symbol, string::Epsilon>> follow(const grammar::Grammar& grammar, const alphabet::Symbol& nt); + static std::set < std::variant < alphabet::Symbol, string::Epsilon > > follow ( const grammar::Grammar & grammar, const alphabet::Symbol & nt ); - template<class T> - static std::set<std::variant<alphabet::Symbol, string::Epsilon>> follow(const T& grammar, const alphabet::Symbol& nt); + template < class T > + static std::set < std::variant < alphabet::Symbol, string::Epsilon > > follow ( const T & grammar, const alphabet::Symbol & nt ); - static Follow& getInstance() { + static Follow & getInstance ( ) { static Follow res; + return res; } + }; } /* namespace parsing */ diff --git a/alib2algo/test-src/grammar/parsing/FirstTest.cpp b/alib2algo/test-src/grammar/parsing/FirstTest.cpp index f80149c9b3..a6b554db64 100644 --- a/alib2algo/test-src/grammar/parsing/FirstTest.cpp +++ b/alib2algo/test-src/grammar/parsing/FirstTest.cpp @@ -4,191 +4,231 @@ #include "string/Epsilon.h" #include "grammar/ContextFree/CFG.h" -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FirstTest, "grammar" ); -CPPUNIT_TEST_SUITE_REGISTRATION( FirstTest ); +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION ( FirstTest, "grammar" ); +CPPUNIT_TEST_SUITE_REGISTRATION ( FirstTest ); -void FirstTest::setUp() { +void FirstTest::setUp ( ) { } -void FirstTest::tearDown() { +void FirstTest::tearDown ( ) { } -void FirstTest::testFirst() { +void FirstTest::testFirst ( ) { { - alphabet::Symbol nE = alphabet::symbolFrom('E'); - alphabet::Symbol nT = alphabet::symbolFrom('T'); - alphabet::Symbol nF = alphabet::symbolFrom('F'); - - alphabet::Symbol tP = alphabet::symbolFrom('+'); - alphabet::Symbol tS = alphabet::symbolFrom('*'); - alphabet::Symbol tL = alphabet::symbolFrom('('); - alphabet::Symbol tR = alphabet::symbolFrom(')'); - alphabet::Symbol tA = alphabet::symbolFrom('a'); - - grammar::CFG grammar(nE); - grammar.setTerminalAlphabet(std::set<alphabet::Symbol>{tP, tS, tL, tR, tA}); - grammar.setNonterminalAlphabet(std::set<alphabet::Symbol>{nE, nT, nF}); - - std::vector<alphabet::Symbol> rhsE1({nE, tP, nT}); - std::vector<alphabet::Symbol> rhsE2({nT}); - std::vector<alphabet::Symbol> rhsT1({nT, tS, nF}); - std::vector<alphabet::Symbol> rhsT2({nF}); - std::vector<alphabet::Symbol> rhsF1({tA}); - std::vector<alphabet::Symbol> rhsF2({tL, nE, tR}); - - grammar.addRule(nE, rhsE1); - grammar.addRule(nE, rhsE2); - grammar.addRule(nT, rhsT1); - grammar.addRule(nT, rhsT2); - grammar.addRule(nF, rhsF1); - grammar.addRule(nF, rhsF2); + alphabet::Symbol nE = alphabet::symbolFrom ( 'E' ); + alphabet::Symbol nT = alphabet::symbolFrom ( 'T' ); + alphabet::Symbol nF = alphabet::symbolFrom ( 'F' ); + + alphabet::Symbol tP = alphabet::symbolFrom ( '+' ); + alphabet::Symbol tS = alphabet::symbolFrom ( '*' ); + alphabet::Symbol tL = alphabet::symbolFrom ( '(' ); + alphabet::Symbol tR = alphabet::symbolFrom ( ')' ); + alphabet::Symbol tA = alphabet::symbolFrom ( 'a' ); + + grammar::CFG grammar ( nE ); + grammar.setTerminalAlphabet ( std::set < alphabet::Symbol > { tP, tS, tL, tR, tA } ); + grammar.setNonterminalAlphabet ( std::set < alphabet::Symbol > { nE, nT, nF } ); + + std::vector < alphabet::Symbol > rhsE1 ( { nE, tP, nT } ); + std::vector < alphabet::Symbol > rhsE2 ( { nT } ); + std::vector < alphabet::Symbol > rhsT1 ( { nT, tS, nF } ); + std::vector < alphabet::Symbol > rhsT2 ( { nF } ); + std::vector < alphabet::Symbol > rhsF1 ( { tA } ); + std::vector < alphabet::Symbol > rhsF2 ( { tL, nE, tR } ); + + grammar.addRule ( nE, rhsE1 ); + grammar.addRule ( nE, rhsE2 ); + grammar.addRule ( nT, rhsT1 ); + grammar.addRule ( nT, rhsT2 ); + grammar.addRule ( nF, rhsF1 ); + grammar.addRule ( nF, rhsF2 ); + + // -------------------------------------------------- + std::map < std::vector < alphabet::Symbol >, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > first; + + first[rhsE1] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tA, tL + } + first[rhsE2] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tA, tL + } + first[rhsT1] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tA, tL + } + first[rhsT2] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tA, tL + } + first[rhsF1] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tA + } + first[rhsF2] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tL + } // -------------------------------------------------- - std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> first; - first[rhsE1] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tA, tL}; - first[rhsE2] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tA, tL}; - first[rhsT1] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tA, tL}; - first[rhsT2] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tA, tL}; - first[rhsF1] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tA}; - first[rhsF2] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tL}; + std::map < std::vector < alphabet::Symbol >, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > firstAlgo; - // -------------------------------------------------- - - std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> firstAlgo; + for ( const auto & rule : grammar.getRawRules ( ) ) + for ( const auto & rhs : rule.second ) + firstAlgo[rhs] = grammar::parsing::First::first ( grammar, rhs ); - for(const auto& rule : grammar.getRawRules()) - for(const auto& rhs : rule.second) - firstAlgo[rhs] = grammar::parsing::First::first(grammar, rhs); - - CPPUNIT_ASSERT(first == firstAlgo); + CPPUNIT_ASSERT ( first == firstAlgo ); } { - alphabet::Symbol nS = alphabet::symbolFrom('S'); - alphabet::Symbol nA = alphabet::symbolFrom('A'); - alphabet::Symbol nB = alphabet::symbolFrom('B'); - alphabet::Symbol nC = alphabet::symbolFrom('C'); - alphabet::Symbol nD = alphabet::symbolFrom('D'); - alphabet::Symbol nE = alphabet::symbolFrom('E'); - alphabet::Symbol nF = alphabet::symbolFrom('F'); - - alphabet::Symbol tA = alphabet::symbolFrom('a'); - alphabet::Symbol tB = alphabet::symbolFrom('b'); - alphabet::Symbol tC = alphabet::symbolFrom('c'); - alphabet::Symbol tD = alphabet::symbolFrom('d'); - alphabet::Symbol tE = alphabet::symbolFrom('e'); - - grammar::CFG grammar(nS); - grammar.setTerminalAlphabet(std::set<alphabet::Symbol>{tA, tB, tC, tD, tE}); - grammar.setNonterminalAlphabet(std::set<alphabet::Symbol>{nS, nA, nB, nC, nD, nE, nF}); - - std::vector<alphabet::Symbol> rhsS1({nB, tD, nS}); - std::vector<alphabet::Symbol> rhsS2({tD, tD, nC}); - std::vector<alphabet::Symbol> rhsS3({tC, nA}); - std::vector<alphabet::Symbol> rhsA1({tA, tE, nE}); - std::vector<alphabet::Symbol> rhsA2({tB, tB, nE}); - std::vector<alphabet::Symbol> rhsB1({tA, nF}); - std::vector<alphabet::Symbol> rhsB2({tB, tB, nD}); - std::vector<alphabet::Symbol> rhsC1({tA, nB, tD}); - std::vector<alphabet::Symbol> rhsC2({tE, nA}); - std::vector<alphabet::Symbol> rhsD1({tC, tA, nF}); - std::vector<alphabet::Symbol> rhsE1({tC, tA, tE, nE}); - std::vector<alphabet::Symbol> rhsE2({}); - std::vector<alphabet::Symbol> rhsF1({tE, nD}); - std::vector<alphabet::Symbol> rhsF2({}); - - grammar.addRule(nS, rhsS1); - grammar.addRule(nS, rhsS2); - grammar.addRule(nS, rhsS3); - grammar.addRule(nA, rhsA1); - grammar.addRule(nA, rhsA2); - grammar.addRule(nB, rhsB1); - grammar.addRule(nB, rhsB2); - grammar.addRule(nC, rhsC1); - grammar.addRule(nC, rhsC2); - grammar.addRule(nD, rhsD1); - grammar.addRule(nE, rhsE1); - grammar.addRule(nE, rhsE2); - grammar.addRule(nF, rhsF1); - grammar.addRule(nF, rhsF2); - - // -------------------------------------------------- - std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> first; - - first[rhsS1] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tA, tB}; - first[rhsS2] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tD}; - first[rhsS3] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tC}; - first[rhsA1] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tA}; - first[rhsA2] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tB}; - first[rhsB1] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tA}; - first[rhsB2] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tB}; - first[rhsC1] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tA}; - first[rhsC2] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tE}; - first[rhsD1] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tC}; - first[rhsE1] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tC}; - first[rhsE2] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{string::Epsilon::EPSILON}; - first[rhsF1] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tE}; - first[rhsF2] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{string::Epsilon::EPSILON}; + alphabet::Symbol nS = alphabet::symbolFrom ( 'S' ); + alphabet::Symbol nA = alphabet::symbolFrom ( 'A' ); + alphabet::Symbol nB = alphabet::symbolFrom ( 'B' ); + alphabet::Symbol nC = alphabet::symbolFrom ( 'C' ); + alphabet::Symbol nD = alphabet::symbolFrom ( 'D' ); + alphabet::Symbol nE = alphabet::symbolFrom ( 'E' ); + alphabet::Symbol nF = alphabet::symbolFrom ( 'F' ); + + alphabet::Symbol tA = alphabet::symbolFrom ( 'a' ); + alphabet::Symbol tB = alphabet::symbolFrom ( 'b' ); + alphabet::Symbol tC = alphabet::symbolFrom ( 'c' ); + alphabet::Symbol tD = alphabet::symbolFrom ( 'd' ); + alphabet::Symbol tE = alphabet::symbolFrom ( 'e' ); + + grammar::CFG grammar ( nS ); + grammar.setTerminalAlphabet ( std::set < alphabet::Symbol > { tA, tB, tC, tD, tE } ); + grammar.setNonterminalAlphabet ( std::set < alphabet::Symbol > { nS, nA, nB, nC, nD, nE, nF } ); + + std::vector < alphabet::Symbol > rhsS1 ( { nB, tD, nS } ); + std::vector < alphabet::Symbol > rhsS2 ( { tD, tD, nC } ); + std::vector < alphabet::Symbol > rhsS3 ( { tC, nA } ); + std::vector < alphabet::Symbol > rhsA1 ( { tA, tE, nE } ); + std::vector < alphabet::Symbol > rhsA2 ( { tB, tB, nE } ); + std::vector < alphabet::Symbol > rhsB1 ( { tA, nF } ); + std::vector < alphabet::Symbol > rhsB2 ( { tB, tB, nD } ); + std::vector < alphabet::Symbol > rhsC1 ( { tA, nB, tD } ); + std::vector < alphabet::Symbol > rhsC2 ( { tE, nA } ); + std::vector < alphabet::Symbol > rhsD1 ( { tC, tA, nF } ); + std::vector < alphabet::Symbol > rhsE1 ( { tC, tA, tE, nE } ); + std::vector < alphabet::Symbol > rhsE2 ( { } ); + std::vector < alphabet::Symbol > rhsF1 ( { tE, nD } ); + std::vector < alphabet::Symbol > rhsF2 ( { } ); + + grammar.addRule ( nS, rhsS1 ); + grammar.addRule ( nS, rhsS2 ); + grammar.addRule ( nS, rhsS3 ); + grammar.addRule ( nA, rhsA1 ); + grammar.addRule ( nA, rhsA2 ); + grammar.addRule ( nB, rhsB1 ); + grammar.addRule ( nB, rhsB2 ); + grammar.addRule ( nC, rhsC1 ); + grammar.addRule ( nC, rhsC2 ); + grammar.addRule ( nD, rhsD1 ); + grammar.addRule ( nE, rhsE1 ); + grammar.addRule ( nE, rhsE2 ); + grammar.addRule ( nF, rhsF1 ); + grammar.addRule ( nF, rhsF2 ); + + // -------------------------------------------------- + std::map < std::vector < alphabet::Symbol >, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > first; + + first[rhsS1] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tA, tB + } + first[rhsS2] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tD + } + first[rhsS3] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tC + } + first[rhsA1] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tA + } + first[rhsA2] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tB + } + first[rhsB1] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tA + } + first[rhsB2] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tB + } + first[rhsC1] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tA + } + first[rhsC2] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tE + } + first[rhsD1] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tC + } + first[rhsE1] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tC + } + first[rhsE2] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + string::Epsilon::EPSILON + } + first[rhsF1] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tE + } + first[rhsF2] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + string::Epsilon::EPSILON + } // -------------------------------------------------- - std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> firstAlgo; + std::map < std::vector < alphabet::Symbol >, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > firstAlgo; - for(const auto& rule : grammar.getRawRules()) - for(const auto& rhs : rule.second) - firstAlgo[rhs] = grammar::parsing::First::first(grammar, rhs); + for ( const auto & rule : grammar.getRawRules ( ) ) + for ( const auto & rhs : rule.second ) + firstAlgo[rhs] = grammar::parsing::First::first ( grammar, rhs ); - CPPUNIT_ASSERT(first == firstAlgo); + CPPUNIT_ASSERT ( first == firstAlgo ); } } -void FirstTest::testFirst2() { - alphabet::Symbol A = alphabet::symbolFrom('A'); - alphabet::Symbol c = alphabet::symbolFrom('c'); - alphabet::Symbol d = alphabet::symbolFrom('d'); +void FirstTest::testFirst2 ( ) { + alphabet::Symbol A = alphabet::symbolFrom ( 'A' ); + alphabet::Symbol c = alphabet::symbolFrom ( 'c' ); + alphabet::Symbol d = alphabet::symbolFrom ( 'd' ); - grammar::CFG grammar(A); - grammar.setTerminalAlphabet({c, d}); - grammar.setNonterminalAlphabet({{A}}); - grammar.setInitialSymbol(A); + grammar::CFG grammar ( A ); - grammar.addRule(A, std::vector<alphabet::Symbol>{ A, c }); - grammar.addRule(A, std::vector<alphabet::Symbol>{ d }); + grammar.setTerminalAlphabet ( { c, d } ); + grammar.setNonterminalAlphabet ( { { A } + } ); + grammar.setInitialSymbol ( A ); - std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> res = {{{d}, {d}}, {{A, c}, {d}}}; - CPPUNIT_ASSERT(res == grammar::parsing::First::first(grammar)); -} + grammar.addRule ( A, std::vector < alphabet::Symbol > { A, c } ); + grammar.addRule ( A, std::vector < alphabet::Symbol > { d } ); -void FirstTest::testFirst3() { - alphabet::Symbol S = alphabet::symbolFrom('S'); - alphabet::Symbol A = alphabet::symbolFrom('A'); - alphabet::Symbol B = alphabet::symbolFrom('B'); - alphabet::Symbol a = alphabet::symbolFrom('a'); - alphabet::Symbol b = alphabet::symbolFrom('b'); - alphabet::Symbol c = alphabet::symbolFrom('c'); - alphabet::Symbol d = alphabet::symbolFrom('d'); - alphabet::Symbol f = alphabet::symbolFrom('f'); - - grammar::CFG grammar(S); - grammar.setTerminalAlphabet({a, b, c, d, f}); - grammar.setNonterminalAlphabet({{S, A, B}}); - grammar.setInitialSymbol(S); - - grammar.addRule(S, std::vector<alphabet::Symbol>{ A, a }); - grammar.addRule(S, std::vector<alphabet::Symbol>{ b, S }); - grammar.addRule(A, std::vector<alphabet::Symbol>{ c, A, d }); - grammar.addRule(A, std::vector<alphabet::Symbol>{ B }); - grammar.addRule(B, std::vector<alphabet::Symbol>{ f, S }); - grammar.addRule(B, std::vector<alphabet::Symbol>{ }); - - std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> res = { - {{A, a}, {c, f, a}}, - {{b, S}, {b}}, - {{c, A, d}, {c}}, - {{B}, {f, string::Epsilon::EPSILON}}, - {{f, S}, {f}}, - {{}, {string::Epsilon::EPSILON}}}; - CPPUNIT_ASSERT(res == grammar::parsing::First::first(grammar)); + std::map < std::vector < alphabet::Symbol >, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > res = { { { d }, { d } }, { { A, c }, { d } } }; + CPPUNIT_ASSERT ( res == grammar::parsing::First::first ( grammar ) ); } +void FirstTest::testFirst3 ( ) { + alphabet::Symbol S = alphabet::symbolFrom ( 'S' ); + alphabet::Symbol A = alphabet::symbolFrom ( 'A' ); + alphabet::Symbol B = alphabet::symbolFrom ( 'B' ); + alphabet::Symbol a = alphabet::symbolFrom ( 'a' ); + alphabet::Symbol b = alphabet::symbolFrom ( 'b' ); + alphabet::Symbol c = alphabet::symbolFrom ( 'c' ); + alphabet::Symbol d = alphabet::symbolFrom ( 'd' ); + alphabet::Symbol f = alphabet::symbolFrom ( 'f' ); + + grammar::CFG grammar ( S ); + + grammar.setTerminalAlphabet ( { a, b, c, d, f } ); + grammar.setNonterminalAlphabet ( { { S, A, B } + } ); + grammar.setInitialSymbol ( S ); + + grammar.addRule ( S, std::vector < alphabet::Symbol > { A, a } ); + grammar.addRule ( S, std::vector < alphabet::Symbol > { b, S } ); + grammar.addRule ( A, std::vector < alphabet::Symbol > { c, A, d } ); + grammar.addRule ( A, std::vector < alphabet::Symbol > { B } ); + grammar.addRule ( B, std::vector < alphabet::Symbol > { f, S } ); + grammar.addRule ( B, std::vector < alphabet::Symbol > { } ); + + std::map < std::vector < alphabet::Symbol >, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > res = + { + { { A, a }, { c, f, a } }, { { b, S }, { b } }, { { c, A, d }, { c } }, { { B }, { f, string::Epsilon::EPSILON } }, { { f, S }, { f } }, { { }, { string::Epsilon::EPSILON } } + }; + CPPUNIT_ASSERT ( res == grammar::parsing::First::first ( grammar ) ); +} diff --git a/alib2algo/test-src/grammar/parsing/FirstTest.h b/alib2algo/test-src/grammar/parsing/FirstTest.h index 46c90bab68..f0bd2252da 100644 --- a/alib2algo/test-src/grammar/parsing/FirstTest.h +++ b/alib2algo/test-src/grammar/parsing/FirstTest.h @@ -3,21 +3,20 @@ #include <cppunit/extensions/HelperMacros.h> -class FirstTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( FirstTest ); - CPPUNIT_TEST( testFirst ); - CPPUNIT_TEST( testFirst2 ); - CPPUNIT_TEST( testFirst3 ); - CPPUNIT_TEST_SUITE_END(); +class FirstTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE ( FirstTest ); + CPPUNIT_TEST ( testFirst ); + CPPUNIT_TEST ( testFirst2 ); + CPPUNIT_TEST ( testFirst3 ); + CPPUNIT_TEST_SUITE_END ( ); public: - void setUp(); - void tearDown(); + void setUp ( ); + void tearDown ( ); - void testFirst(); - void testFirst2(); - void testFirst3(); + void testFirst ( ); + void testFirst2 ( ); + void testFirst3 ( ); }; #endif /* FIRST_TEST_H_ */ diff --git a/alib2algo/test-src/grammar/parsing/FollowTest.cpp b/alib2algo/test-src/grammar/parsing/FollowTest.cpp index 2a2d17f044..7b483e93ab 100644 --- a/alib2algo/test-src/grammar/parsing/FollowTest.cpp +++ b/alib2algo/test-src/grammar/parsing/FollowTest.cpp @@ -4,135 +4,153 @@ #include "string/Epsilon.h" #include "grammar/ContextFree/CFG.h" -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FollowTest, "grammar" ); -CPPUNIT_TEST_SUITE_REGISTRATION( FollowTest ); +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION ( FollowTest, "grammar" ); +CPPUNIT_TEST_SUITE_REGISTRATION ( FollowTest ); -void FollowTest::setUp() { +void FollowTest::setUp ( ) { } -void FollowTest::tearDown() { +void FollowTest::tearDown ( ) { } -void FollowTest::testFollow() { +void FollowTest::testFollow ( ) { { - alphabet::Symbol nE = alphabet::symbolFrom('E'); - alphabet::Symbol nT = alphabet::symbolFrom('T'); - alphabet::Symbol nF = alphabet::symbolFrom('F'); - - alphabet::Symbol tP = alphabet::symbolFrom('+'); - alphabet::Symbol tS = alphabet::symbolFrom('*'); - alphabet::Symbol tL = alphabet::symbolFrom('('); - alphabet::Symbol tR = alphabet::symbolFrom(')'); - alphabet::Symbol tA = alphabet::symbolFrom('a'); - - grammar::CFG grammar(nE); - grammar.setTerminalAlphabet(std::set<alphabet::Symbol>{tP, tS, tL, tR, tA}); - grammar.setNonterminalAlphabet(std::set<alphabet::Symbol>{nE, nT, nF}); - - std::vector<alphabet::Symbol> rhsE1({nE, tP, nT}); - std::vector<alphabet::Symbol> rhsE2({nT}); - std::vector<alphabet::Symbol> rhsT1({nT, tS, nF}); - std::vector<alphabet::Symbol> rhsT2({nF}); - std::vector<alphabet::Symbol> rhsF1({tA}); - std::vector<alphabet::Symbol> rhsF2({tL, nE, tR}); - - grammar.addRule(nE, rhsE1); - grammar.addRule(nE, rhsE2); - grammar.addRule(nT, rhsT1); - grammar.addRule(nT, rhsT2); - grammar.addRule(nF, rhsF1); - grammar.addRule(nF, rhsF2); + alphabet::Symbol nE = alphabet::symbolFrom ( 'E' ); + alphabet::Symbol nT = alphabet::symbolFrom ( 'T' ); + alphabet::Symbol nF = alphabet::symbolFrom ( 'F' ); + + alphabet::Symbol tP = alphabet::symbolFrom ( '+' ); + alphabet::Symbol tS = alphabet::symbolFrom ( '*' ); + alphabet::Symbol tL = alphabet::symbolFrom ( '(' ); + alphabet::Symbol tR = alphabet::symbolFrom ( ')' ); + alphabet::Symbol tA = alphabet::symbolFrom ( 'a' ); + + grammar::CFG grammar ( nE ); + grammar.setTerminalAlphabet ( std::set < alphabet::Symbol > { tP, tS, tL, tR, tA } ); + grammar.setNonterminalAlphabet ( std::set < alphabet::Symbol > { nE, nT, nF } ); + + std::vector < alphabet::Symbol > rhsE1 ( { nE, tP, nT } ); + std::vector < alphabet::Symbol > rhsE2 ( { nT } ); + std::vector < alphabet::Symbol > rhsT1 ( { nT, tS, nF } ); + std::vector < alphabet::Symbol > rhsT2 ( { nF } ); + std::vector < alphabet::Symbol > rhsF1 ( { tA } ); + std::vector < alphabet::Symbol > rhsF2 ( { tL, nE, tR } ); + + grammar.addRule ( nE, rhsE1 ); + grammar.addRule ( nE, rhsE2 ); + grammar.addRule ( nT, rhsT1 ); + grammar.addRule ( nT, rhsT2 ); + grammar.addRule ( nF, rhsF1 ); + grammar.addRule ( nF, rhsF2 ); + + // -------------------------------------------------- + std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > follow; + + follow[nE] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + string::Epsilon::EPSILON, tP, tR + } + follow[nT] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + string::Epsilon::EPSILON, tP, tR, tS + } + follow[nF] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + string::Epsilon::EPSILON, tP, tR, tS + } // -------------------------------------------------- - std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> follow; - follow[nE] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{string::Epsilon::EPSILON, tP, tR}; - follow[nT] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{string::Epsilon::EPSILON, tP, tR, tS}; - follow[nF] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{string::Epsilon::EPSILON, tP, tR, tS}; + std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > followAlgo; - // -------------------------------------------------- - - std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> followAlgo; + for ( const auto & nt : grammar.getNonterminalAlphabet ( ) ) + followAlgo[nt] = grammar::parsing::Follow::follow ( grammar, nt ); - for(const auto& nt : grammar.getNonterminalAlphabet()) - followAlgo[nt] = grammar::parsing::Follow::follow(grammar, nt); - - // std::cout << follow << std::endl; - // std::cout << followAlgo << std::endl; - CPPUNIT_ASSERT(follow == followAlgo); + // std::cout << follow << std::endl; + // std::cout << followAlgo << std::endl; + CPPUNIT_ASSERT ( follow == followAlgo ); } { - alphabet::Symbol nS = alphabet::symbolFrom('S'); - alphabet::Symbol nA = alphabet::symbolFrom('A'); - alphabet::Symbol nB = alphabet::symbolFrom('B'); - alphabet::Symbol nC = alphabet::symbolFrom('C'); - alphabet::Symbol nD = alphabet::symbolFrom('D'); - alphabet::Symbol nE = alphabet::symbolFrom('E'); - alphabet::Symbol nF = alphabet::symbolFrom('F'); - - alphabet::Symbol tA = alphabet::symbolFrom('a'); - alphabet::Symbol tB = alphabet::symbolFrom('b'); - alphabet::Symbol tC = alphabet::symbolFrom('c'); - alphabet::Symbol tD = alphabet::symbolFrom('d'); - alphabet::Symbol tE = alphabet::symbolFrom('e'); - - grammar::CFG grammar(nS); - grammar.setTerminalAlphabet(std::set<alphabet::Symbol>{tA, tB, tC, tD, tE}); - grammar.setNonterminalAlphabet(std::set<alphabet::Symbol>{nS, nA, nB, nC, nD, nE, nF}); - - std::vector<alphabet::Symbol> rhsS1({nB, tD, nS}); - std::vector<alphabet::Symbol> rhsS2({tD, tD, nC}); - std::vector<alphabet::Symbol> rhsS3({tC, nA}); - std::vector<alphabet::Symbol> rhsA1({tA, tE, nE}); - std::vector<alphabet::Symbol> rhsA2({tB, tB, nE}); - std::vector<alphabet::Symbol> rhsB1({tA, nF}); - std::vector<alphabet::Symbol> rhsB2({tB, tB, nD}); - std::vector<alphabet::Symbol> rhsC1({tA, nB, tD}); - std::vector<alphabet::Symbol> rhsC2({tE, nA}); - std::vector<alphabet::Symbol> rhsD1({tC, tA, nF}); - std::vector<alphabet::Symbol> rhsE1({tC, tA, tE, nE}); - std::vector<alphabet::Symbol> rhsE2({}); - std::vector<alphabet::Symbol> rhsF1({tE, nD}); - std::vector<alphabet::Symbol> rhsF2({}); - - grammar.addRule(nS, rhsS1); - grammar.addRule(nS, rhsS2); - grammar.addRule(nS, rhsS3); - grammar.addRule(nA, rhsA1); - grammar.addRule(nA, rhsA2); - grammar.addRule(nB, rhsB1); - grammar.addRule(nB, rhsB2); - grammar.addRule(nC, rhsC1); - grammar.addRule(nC, rhsC2); - grammar.addRule(nD, rhsD1); - grammar.addRule(nE, rhsE1); - grammar.addRule(nE, rhsE2); - grammar.addRule(nF, rhsF1); - grammar.addRule(nF, rhsF2); - - // -------------------------------------------------- - std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> follow; - - follow[nS] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{string::Epsilon::EPSILON}; - follow[nA] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{string::Epsilon::EPSILON}; - follow[nB] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tD}; - follow[nC] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{string::Epsilon::EPSILON}; - follow[nD] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tD}; - follow[nE] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{string::Epsilon::EPSILON}; - follow[nF] = std::set<std::variant<alphabet::Symbol, string::Epsilon>>{tD}; + alphabet::Symbol nS = alphabet::symbolFrom ( 'S' ); + alphabet::Symbol nA = alphabet::symbolFrom ( 'A' ); + alphabet::Symbol nB = alphabet::symbolFrom ( 'B' ); + alphabet::Symbol nC = alphabet::symbolFrom ( 'C' ); + alphabet::Symbol nD = alphabet::symbolFrom ( 'D' ); + alphabet::Symbol nE = alphabet::symbolFrom ( 'E' ); + alphabet::Symbol nF = alphabet::symbolFrom ( 'F' ); + + alphabet::Symbol tA = alphabet::symbolFrom ( 'a' ); + alphabet::Symbol tB = alphabet::symbolFrom ( 'b' ); + alphabet::Symbol tC = alphabet::symbolFrom ( 'c' ); + alphabet::Symbol tD = alphabet::symbolFrom ( 'd' ); + alphabet::Symbol tE = alphabet::symbolFrom ( 'e' ); + + grammar::CFG grammar ( nS ); + grammar.setTerminalAlphabet ( std::set < alphabet::Symbol > { tA, tB, tC, tD, tE } ); + grammar.setNonterminalAlphabet ( std::set < alphabet::Symbol > { nS, nA, nB, nC, nD, nE, nF } ); + + std::vector < alphabet::Symbol > rhsS1 ( { nB, tD, nS } ); + std::vector < alphabet::Symbol > rhsS2 ( { tD, tD, nC } ); + std::vector < alphabet::Symbol > rhsS3 ( { tC, nA } ); + std::vector < alphabet::Symbol > rhsA1 ( { tA, tE, nE } ); + std::vector < alphabet::Symbol > rhsA2 ( { tB, tB, nE } ); + std::vector < alphabet::Symbol > rhsB1 ( { tA, nF } ); + std::vector < alphabet::Symbol > rhsB2 ( { tB, tB, nD } ); + std::vector < alphabet::Symbol > rhsC1 ( { tA, nB, tD } ); + std::vector < alphabet::Symbol > rhsC2 ( { tE, nA } ); + std::vector < alphabet::Symbol > rhsD1 ( { tC, tA, nF } ); + std::vector < alphabet::Symbol > rhsE1 ( { tC, tA, tE, nE } ); + std::vector < alphabet::Symbol > rhsE2 ( { } ); + std::vector < alphabet::Symbol > rhsF1 ( { tE, nD } ); + std::vector < alphabet::Symbol > rhsF2 ( { } ); + + grammar.addRule ( nS, rhsS1 ); + grammar.addRule ( nS, rhsS2 ); + grammar.addRule ( nS, rhsS3 ); + grammar.addRule ( nA, rhsA1 ); + grammar.addRule ( nA, rhsA2 ); + grammar.addRule ( nB, rhsB1 ); + grammar.addRule ( nB, rhsB2 ); + grammar.addRule ( nC, rhsC1 ); + grammar.addRule ( nC, rhsC2 ); + grammar.addRule ( nD, rhsD1 ); + grammar.addRule ( nE, rhsE1 ); + grammar.addRule ( nE, rhsE2 ); + grammar.addRule ( nF, rhsF1 ); + grammar.addRule ( nF, rhsF2 ); + + // -------------------------------------------------- + std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > follow; + + follow[nS] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + string::Epsilon::EPSILON + } + follow[nA] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + string::Epsilon::EPSILON + } + follow[nB] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tD + } + follow[nC] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + string::Epsilon::EPSILON + } + follow[nD] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tD + } + follow[nE] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + string::Epsilon::EPSILON + } + follow[nF] = std::set < std::variant < alphabet::Symbol, string::Epsilon > > { + tD + } // -------------------------------------------------- - std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> followAlgo; + std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > followAlgo; - for(const auto& nt : grammar.getNonterminalAlphabet()) - followAlgo[nt] = grammar::parsing::Follow::follow(grammar, nt); - - // std::cout << follow << std::endl; - // std::cout << followAlgo << std::endl; - CPPUNIT_ASSERT(follow == followAlgo); + for ( const auto & nt : grammar.getNonterminalAlphabet ( ) ) + followAlgo[nt] = grammar::parsing::Follow::follow ( grammar, nt ); + // std::cout << follow << std::endl; + // std::cout << followAlgo << std::endl; + CPPUNIT_ASSERT ( follow == followAlgo ); } } - -- GitLab