From ccfa95a79f90548a3a8ed8090bdebff5cab93e65 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 10:52:12 +0200 Subject: [PATCH] added universal LR parsing algorithm --- alib2algo/src/grammar/parsing/LRParser.cpp | 43 ++++++++++++++++++++++ alib2algo/src/grammar/parsing/LRParser.h | 4 ++ 2 files changed, 47 insertions(+) diff --git a/alib2algo/src/grammar/parsing/LRParser.cpp b/alib2algo/src/grammar/parsing/LRParser.cpp index 11428be758..86a8246ffb 100644 --- a/alib2algo/src/grammar/parsing/LRParser.cpp +++ b/alib2algo/src/grammar/parsing/LRParser.cpp @@ -85,6 +85,49 @@ LR0Items LRParser::getNextStateItems ( LR0Items items, alphabet::Symbol symbol, return getClosure ( transitionItems, originalGrammar ); } +bool LRParser::parse ( LRActionTable actionTable, LRGotoTable gotoTable, automaton::State initialState, std::vector < alphabet::Symbol > input ) { + std::stack < automaton::State > states; + states.push ( initialState ); + + unsigned currentPosition = 0; + while ( true ) { + LRActionTable::iterator actionIterator = actionTable.find ( { states.top ( ), input[currentPosition] } ); + if ( actionIterator == actionTable.end ( ) ) { + return false; + } + + switch ( actionIterator->second.first ) { + case LRAction::Shift: + states.push ( actionIterator->second.second.get < automaton::State > ( ) ); + + ++currentPosition; + break; + + case LRAction::Reduce: { + std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > reduceBy = actionIterator->second.second.get < std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > ( ); + for ( unsigned i = 0; i < reduceBy.second.size ( ); ++i ) { + states.pop ( ); + } + + LRGotoTable::iterator nextStateIterator = gotoTable.find ( { states.top ( ), reduceBy.first } ); + if (nextStateIterator == gotoTable.end()) { + return false; + } + + states.push ( nextStateIterator->second ); + + break; + } + + case LRAction::Accept: + return true; + break; + } + } + + return false; +} + } /* namespace parsing */ } /* namespace grammar */ diff --git a/alib2algo/src/grammar/parsing/LRParser.h b/alib2algo/src/grammar/parsing/LRParser.h index 561f69bf8d..2f1ad997f0 100644 --- a/alib2algo/src/grammar/parsing/LRParser.h +++ b/alib2algo/src/grammar/parsing/LRParser.h @@ -12,6 +12,8 @@ #include <grammar/ContextFree/CFG.h> #include <grammar/parsing/LRParserTypes.h> +#include <vector> + namespace grammar { namespace parsing { @@ -25,6 +27,8 @@ public: 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 ); }; } /* namespace parsing */ -- GitLab