From 6caa272a3e48a4433fef8e16c3c9c96422c69f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ko=C4=8Di=C4=8Dka?= <martin.kocicka@gmail.com> Date: Wed, 11 May 2016 18:42:02 +0200 Subject: [PATCH] moved getClosure() to LR0Parser since it's not universal --- alib2algo/src/grammar/parsing/LR0Parser.cpp | 34 +++++++++++++++++++-- alib2algo/src/grammar/parsing/LR0Parser.h | 3 ++ alib2algo/src/grammar/parsing/LRParser.cpp | 34 ++------------------- alib2algo/src/grammar/parsing/LRParser.h | 2 -- 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/alib2algo/src/grammar/parsing/LR0Parser.cpp b/alib2algo/src/grammar/parsing/LR0Parser.cpp index 6571b73c2e..c5c12b116a 100644 --- a/alib2algo/src/grammar/parsing/LR0Parser.cpp +++ b/alib2algo/src/grammar/parsing/LR0Parser.cpp @@ -9,9 +9,7 @@ #include "LRParser.h" -#include <automaton/FSM/DFA.h> #include <automaton/common/State.h> -#include <grammar/ContextFree/CFG.h> #include <label/LR0ItemsLabel.h> #include <queue> @@ -19,6 +17,36 @@ namespace grammar { namespace parsing { + +LR0Items LR0Parser::getClosure ( LR0Items items, grammar::CFG originalGrammar ) { + bool changed; + do { + changed = false; + + for ( const LR0Items::value_type & symbolItems : items ) { + for ( const std::pair < unsigned, std::vector < alphabet::Symbol > > & item : symbolItems.second ) { + unsigned position = item.first; + std::vector < alphabet::Symbol > rightHandSide = item.second; + + if ( position == rightHandSide.size ( ) ) { + continue; + } + + std::map < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > >::const_iterator rulesIterator = originalGrammar.getRules ( ) . find(rightHandSide[position]); + if ( rulesIterator != originalGrammar.getRules ( ) . end ( ) ) { + for ( const std::vector < alphabet::Symbol > & rule : rulesIterator->second ) { + if (items[rightHandSide[position]].find ( { 0, rule } ) == items[rightHandSide[position]].end ( ) ) { + changed = true; + items[rightHandSide[position]].insert ( { 0, rule } ); + } + } + } + } + } + } while ( changed ); + + return items; +} automaton::DFA LR0Parser::getAutomaton ( grammar::CFG originalGrammar ) { grammar::CFG augmentedGrammar = LRParser::getAugmentedGrammar ( originalGrammar ); @@ -28,7 +56,7 @@ automaton::DFA LR0Parser::getAutomaton ( grammar::CFG originalGrammar ) { LR0Items initialItems; initialItems[initialSymbol].insert ( { 0, *rules.find ( initialSymbol ) -> second.begin ( ) } ); - automaton::State initialState ( label::Label ( label::LR0ItemsLabel ( LRParser::getClosure ( initialItems, augmentedGrammar ) ) ) ); + automaton::State initialState ( label::Label ( label::LR0ItemsLabel ( getClosure ( initialItems, augmentedGrammar ) ) ) ); automaton::DFA lr0Automaton ( initialState ); lr0Automaton.addInputSymbols ( augmentedGrammar.getNonterminalAlphabet ( ) ); diff --git a/alib2algo/src/grammar/parsing/LR0Parser.h b/alib2algo/src/grammar/parsing/LR0Parser.h index 08b8010d9a..cf06cf4b96 100644 --- a/alib2algo/src/grammar/parsing/LR0Parser.h +++ b/alib2algo/src/grammar/parsing/LR0Parser.h @@ -10,6 +10,7 @@ #include <automaton/FSM/DFA.h> #include <grammar/ContextFree/CFG.h> +#include <grammar/parsing/LRParserTypes.h> namespace grammar { @@ -17,6 +18,8 @@ namespace parsing { class LR0Parser { public: + static LR0Items getClosure ( LR0Items items, grammar::CFG originalGrammar ); + static automaton::DFA getAutomaton ( grammar::CFG originalGrammar ); }; diff --git a/alib2algo/src/grammar/parsing/LRParser.cpp b/alib2algo/src/grammar/parsing/LRParser.cpp index 86a8246ffb..2c3d42b07e 100644 --- a/alib2algo/src/grammar/parsing/LRParser.cpp +++ b/alib2algo/src/grammar/parsing/LRParser.cpp @@ -7,6 +7,8 @@ #include "LRParser.h" +#include "LR0Parser.h" + #include <stack> namespace grammar { @@ -34,36 +36,6 @@ grammar::CFG LRParser::getAugmentedGrammar ( grammar::CFG originalGrammar ) { return originalGrammar; } -LR0Items LRParser::getClosure ( LR0Items items, grammar::CFG originalGrammar ) { - bool changed; - do { - changed = false; - - for ( const LR0Items::value_type & symbolItems : items ) { - for ( const std::pair < unsigned, std::vector < alphabet::Symbol > > & item : symbolItems.second ) { - unsigned position = item.first; - std::vector < alphabet::Symbol > rightHandSide = item.second; - - if ( position == rightHandSide.size ( ) ) { - continue; - } - - std::map < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > >::const_iterator rulesIterator = originalGrammar.getRules ( ) . find(rightHandSide[position]); - if ( rulesIterator != originalGrammar.getRules ( ) . end ( ) ) { - for ( const std::vector < alphabet::Symbol > & rule : rulesIterator->second ) { - if (items[rightHandSide[position]].find ( { 0, rule } ) == items[rightHandSide[position]].end ( ) ) { - changed = true; - items[rightHandSide[position]].insert ( { 0, rule } ); - } - } - } - } - } - } while ( changed ); - - return items; -} - LR0Items LRParser::getNextStateItems ( LR0Items items, alphabet::Symbol symbol, grammar::CFG originalGrammar ) { LR0Items transitionItems; for ( const LR0Items::value_type & symbolItems : items ) { @@ -82,7 +54,7 @@ LR0Items LRParser::getNextStateItems ( LR0Items items, alphabet::Symbol symbol, } } - return getClosure ( transitionItems, originalGrammar ); + return LR0Parser::getClosure ( transitionItems, originalGrammar ); } bool LRParser::parse ( LRActionTable actionTable, LRGotoTable gotoTable, automaton::State initialState, std::vector < alphabet::Symbol > input ) { diff --git a/alib2algo/src/grammar/parsing/LRParser.h b/alib2algo/src/grammar/parsing/LRParser.h index 2f1ad997f0..63349d60f2 100644 --- a/alib2algo/src/grammar/parsing/LRParser.h +++ b/alib2algo/src/grammar/parsing/LRParser.h @@ -24,8 +24,6 @@ public: static grammar::CFG getAugmentedGrammar ( grammar::CFG originalGrammar ); - static LR0Items getClosure ( LR0Items items, grammar::CFG originalGrammar ); - static LR0Items getNextStateItems ( LR0Items items, alphabet::Symbol symbol, grammar::CFG originalGrammar ); static bool parse ( LRActionTable actionTable, LRGotoTable gotoTable, automaton::State initialState, std::vector < alphabet::Symbol > input ); -- GitLab