diff --git a/alib2algo/src/grammar/parsing/DeterministicLL1Grammar.cpp b/alib2algo/src/grammar/parsing/DeterministicLL1Grammar.cpp index 33043ccec5ee7dfd853823b2bc7b7fe21f129214..8246ae13a21c025c088dcb87ea1ac02781f02f0d 100644 --- a/alib2algo/src/grammar/parsing/DeterministicLL1Grammar.cpp +++ b/alib2algo/src/grammar/parsing/DeterministicLL1Grammar.cpp @@ -20,15 +20,6 @@ namespace grammar { namespace parsing { -void transformToLL1 ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const alphabet::Symbol & nonterminal, const std::set < std::vector < alphabet::Symbol > > & rhsds ) { - if ( std::any_of ( rhsds.begin ( ), rhsds.end ( ), [] ( const std::vector < alphabet::Symbol > & rhs ) { - return rhs.size ( ) == 0; - } ) ) - HandleFirstFollowConflict::handleFirstFollowConflict ( grammar, terminal, nonterminal, rhsds ); - else - HandleFirstFirstConflict::handleFirstFirstConflict ( grammar, terminal, nonterminal, rhsds ); -} - grammar::CFG DeterministicLL1Grammar::convert ( const grammar::CFG & param ) { if ( std::any_of ( param.getNonterminalAlphabet ( ).begin ( ), param.getNonterminalAlphabet ( ).end ( ), [&] ( const alphabet::Symbol & nonterminal ) { @@ -41,28 +32,50 @@ grammar::CFG DeterministicLL1Grammar::convert ( const grammar::CFG & param ) { while ( true ) { std::map < std::pair < std::variant < alphabet::Symbol, string::Epsilon >, alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > > parseTable = LL1ParseTable::parseTable ( grammar ); - bool deterministic = true; - bool errorInEpsilon = false; + bool deterministic = true; for ( const std::pair < std::pair < std::variant < alphabet::Symbol, string::Epsilon >, alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > > & elem : parseTable ) - if ( elem.second.size ( ) > 1 ) { - if ( elem.first.first.is < string::Epsilon > ( ) ) { - errorInEpsilon = true; - continue; - } + if ( elem.second.size ( ) > 1 ) + if ( elem.first.first.is < string::Epsilon > ( ) ) + throw exception::AlibException ( "Cant handle conflict in epsilon" ); + + for ( const std::pair < std::pair < std::variant < alphabet::Symbol, string::Epsilon >, alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > > & elem : parseTable ) { + if ( elem.first.first.is < string::Epsilon > ( ) ) continue; + + const alphabet::Symbol & terminal = elem.first.first.get < alphabet::Symbol > ( ); + const alphabet::Symbol & nonterminal = elem.first.second; + const std::set < std::vector < alphabet::Symbol > > & rhsds = elem.second; - transformToLL1 ( grammar, elem.first.first.get < alphabet::Symbol > ( ), elem.first.second, elem.second ); + if ( ( elem.second.size ( ) > 1 ) && std::all_of ( rhsds.begin ( ), rhsds.end ( ), [] ( const std::vector < alphabet::Symbol > & rhs ) { + return rhs.size ( ) > 0; + } ) ) { + HandleFirstFirstConflict::handleFirstFirstConflict ( grammar, terminal, nonterminal, rhsds ); deterministic = false; break; } + } + if ( !deterministic ) continue; + for ( const std::pair < std::pair < std::variant < alphabet::Symbol, string::Epsilon >, alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > > & elem : parseTable ) { + if ( elem.first.first.is < string::Epsilon > ( ) ) continue; + + const alphabet::Symbol & terminal = elem.first.first.get < alphabet::Symbol > ( ); + const alphabet::Symbol & nonterminal = elem.first.second; + const std::set < std::vector < alphabet::Symbol > > & rhsds = elem.second; + + if ( ( elem.second.size ( ) > 1 ) && std::any_of ( rhsds.begin ( ), rhsds.end ( ), [] ( const std::vector < alphabet::Symbol > & rhs ) { + return rhs.size ( ) == 0; + } ) ) { + HandleFirstFollowConflict::handleFirstFollowConflict ( grammar, terminal, nonterminal, rhsds ); + deterministic = false; + break; + } + } - if ( deterministic ) - return grammar; + if ( !deterministic ) continue; - if ( errorInEpsilon ) - throw exception::AlibException ( "Cant handle conflict in epsilon" ); + return grammar; } } diff --git a/examples2/grammar/contextFree1-3.txt b/examples2/grammar/contextFree1-3.txt new file mode 100644 index 0000000000000000000000000000000000000000..a70e69adb8f2c5be1b61f7e2b42d41d2cc4c67fe --- /dev/null +++ b/examples2/grammar/contextFree1-3.txt @@ -0,0 +1,10 @@ +CFG ( +{'S', 'A', 'B', 'C', 'X'}, +{'a', 'b', 'c', 'd', 'e'}, +{'S' -> 'C' 'd' 'e' 'S' 'e' | 'd' 'd' 'B' | 'c' 'A', +'A' -> 'C' 'd' | 'b' 'b', +'B' -> 'b' 'a' 'C' 'd' |, +'C' -> 'b' 'b' 'c' 'a' 'X' | 'a' 'X', +'X' -> 'd' 'c' 'a' 'X' | +}, +'S')