From 505418dad62f10bff10c4348ab67d0df3a4eed0c Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Fri, 16 Oct 2015 11:43:41 +0200 Subject: [PATCH] add follow of all symbols --- alib2algo/src/grammar/parsing/Follow.cpp | 49 ++++++++++++++++-------- alib2algo/src/grammar/parsing/Follow.h | 31 ++++++++++++--- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/alib2algo/src/grammar/parsing/Follow.cpp b/alib2algo/src/grammar/parsing/Follow.cpp index cd4a99e343..c85a0a3f0d 100644 --- a/alib2algo/src/grammar/parsing/Follow.cpp +++ b/alib2algo/src/grammar/parsing/Follow.cpp @@ -52,10 +52,7 @@ void Follow::follow ( const T & grammar, std::map < alphabet::Symbol, std::set < } 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." ); - +std::map< alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > Follow::follow ( const T & grammar ) { /* * 1. Follow(S) = { \varepsilon } * Follow(A) = {} forall A \in N, A \neq S @@ -84,21 +81,43 @@ std::set < std::variant < alphabet::Symbol, string::Epsilon > > Follow::follow ( followSet1 = followSet2; } while ( true ); - return followSet1[nt]; + return followSet1; +} + +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." ); + + return follow(grammar)[nt]; +} + +auto FollowCFG = FollowBase1::RegistratorWrapper < FollowResult1, grammar::CFG > ( Follow::getInstance1 ( ), Follow::follow ); +auto FollowEpsilonFreeCFG = FollowBase1::RegistratorWrapper < FollowResult1, grammar::EpsilonFreeCFG > ( Follow::getInstance1 ( ), Follow::follow ); +auto FollowGNF = FollowBase1::RegistratorWrapper < FollowResult1, grammar::GNF > ( Follow::getInstance1 ( ), Follow::follow ); +auto FollowCNF = FollowBase1::RegistratorWrapper < FollowResult1, grammar::CNF > ( Follow::getInstance1 ( ), Follow::follow ); +auto FollowLG = FollowBase1::RegistratorWrapper < FollowResult1, grammar::LG > ( Follow::getInstance1 ( ), Follow::follow ); +auto FollowLeftLG = FollowBase1::RegistratorWrapper < FollowResult1, grammar::LeftLG > ( Follow::getInstance1 ( ), Follow::follow ); +auto FollowLeftRG = FollowBase1::RegistratorWrapper < FollowResult1, grammar::LeftRG > ( Follow::getInstance1 ( ), Follow::follow ); +auto FollowRightLG = FollowBase1::RegistratorWrapper < FollowResult1, grammar::RightLG > ( Follow::getInstance1 ( ), Follow::follow ); +auto FollowRightRG = FollowBase1::RegistratorWrapper < FollowResult1, grammar::RightRG > ( Follow::getInstance1 ( ), Follow::follow ); + +std::map< alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > Follow::follow ( const grammar::Grammar & grammar ) { + return getInstance1 ( ).dispatch ( grammar.getData ( ) ); } -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 ); +auto FollowCFG2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::CFG > ( Follow::getInstance2 ( ), Follow::follow ); +auto FollowEpsilonFreeCFG2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::EpsilonFreeCFG > ( Follow::getInstance2 ( ), Follow::follow ); +auto FollowGNF2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::GNF > ( Follow::getInstance2 ( ), Follow::follow ); +auto FollowCNF2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::CNF > ( Follow::getInstance2 ( ), Follow::follow ); +auto FollowLG2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::LG > ( Follow::getInstance2 ( ), Follow::follow ); +auto FollowLeftLG2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::LeftLG > ( Follow::getInstance2 ( ), Follow::follow ); +auto FollowLeftRG2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::LeftRG > ( Follow::getInstance2 ( ), Follow::follow ); +auto FollowRightLG2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::RightLG > ( Follow::getInstance2 ( ), Follow::follow ); +auto FollowRightRG2 = FollowBase2::RegistratorWrapper < FollowResult2, grammar::RightRG > ( Follow::getInstance2 ( ), 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 ); + return getInstance2 ( ).dispatch ( grammar.getData ( ), nt ); } } /* namespace parsing */ diff --git a/alib2algo/src/grammar/parsing/Follow.h b/alib2algo/src/grammar/parsing/Follow.h index 9e965dabb6..9f4d57505c 100644 --- a/alib2algo/src/grammar/parsing/Follow.h +++ b/alib2algo/src/grammar/parsing/Follow.h @@ -20,15 +20,15 @@ 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 ); +typedef std::map< alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > FollowResult1; +typedef std::SingleDispatch < FollowResult1, grammar::GrammarBase > FollowBase1; -public: - static std::set < std::variant < alphabet::Symbol, string::Epsilon > > follow ( const grammar::Grammar & grammar, const alphabet::Symbol & nt ); +typedef std::set < std::variant < alphabet::Symbol, string::Epsilon > > FollowResult2; +typedef std::SingleDispatchLastStaticParam < FollowResult2, grammar::GrammarBase, const alphabet::Symbol & > FollowBase2; +class Follow : public FollowBase1, public FollowBase2 { template < class T > - static std::set < std::variant < alphabet::Symbol, string::Epsilon > > follow ( const T & grammar, const alphabet::Symbol & nt ); + static void follow ( const T & grammar, std::map < alphabet::Symbol, std::set < std::variant < alphabet::Symbol, string::Epsilon > > > & followSet ); static Follow & getInstance ( ) { static Follow res; @@ -36,6 +36,25 @@ public: return res; } +public: + static FollowResult1 follow ( const grammar::Grammar & grammar ); + + static FollowResult2 follow ( const grammar::Grammar & grammar, const alphabet::Symbol & nt ); + + template < class T > + static FollowResult1 follow ( const T & grammar ); + + template < class T > + static FollowResult2 follow ( const T & grammar, const alphabet::Symbol & nt ); + + static FollowBase1 & getInstance1 ( ) { + return getInstance ( ); + } + + static FollowBase2 & getInstance2 ( ) { + return getInstance ( ); + } + }; } /* namespace parsing */ -- GitLab