From cced0790f1f5a8bb7ac39bd14d83ceb4c4b9b64d 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:59:15 +0200 Subject: [PATCH] added SLR(1) action table generator --- .../src/grammar/parsing/SLR1ParseTable.cpp | 72 +++++++++++++++++++ .../src/grammar/parsing/SLR1ParseTable.h | 31 ++++++++ 2 files changed, 103 insertions(+) create mode 100644 alib2algo/src/grammar/parsing/SLR1ParseTable.cpp create mode 100644 alib2algo/src/grammar/parsing/SLR1ParseTable.h diff --git a/alib2algo/src/grammar/parsing/SLR1ParseTable.cpp b/alib2algo/src/grammar/parsing/SLR1ParseTable.cpp new file mode 100644 index 0000000000..0b3025d18b --- /dev/null +++ b/alib2algo/src/grammar/parsing/SLR1ParseTable.cpp @@ -0,0 +1,72 @@ +/* + * SLR1ParseTable.cpp + * + * Created on: 4. 5. 2016 + * Author: Martin Kocicka + */ + +#include "SLR1ParseTable.h" + +#include "LRParser.h" +#include "LR0Parser.h" +#include "Follow.h" + +#include <exception/CommonException.h> +#include <label/LR0ItemsLabel.h> + +namespace grammar { + +namespace parsing { + +void SLR1ParseTable::insertToActionTable ( LRActionTable & actionTable, LRActionTable::key_type key, LRActionTable::mapped_type value ) { + std::pair<LRActionTable::iterator, bool> result = actionTable.insert ( { key, value } ); + if ( ! result.second ) { + throw exception::CommonException ( "Grammar is not SLR(1)!" ); + } +} + +LRActionTable SLR1ParseTable::getActionTable ( grammar::CFG originalGrammar ) { + LRActionTable actionTable; + grammar::CFG augmentedGrammar = LRParser::getAugmentedGrammar ( originalGrammar ); + automaton::DFA parsingAutomaton = LR0Parser::getAutomaton ( originalGrammar ); + for ( const automaton::State & state : parsingAutomaton.getStates ( ) ) { + LR0Items items = static_cast < const label::LR0ItemsLabel & > ( state.getName ( ) . getData ( ) ) . getItems ( ); + std::map < std::pair < automaton::State, alphabet::Symbol >, automaton::State > transitionsFromCurrentState = parsingAutomaton.getTransitionsFromState ( state ); + for ( const LR0Items::value_type & nonterminalItems : items ) { + alphabet::Symbol leftHandSide = nonterminalItems.first; + for ( const std::pair < unsigned, std::vector < alphabet::Symbol > > & item : nonterminalItems.second ) { + unsigned position = item.first; + std::vector < alphabet::Symbol > rightHandSide = item.second; + + if ( position == rightHandSide.size ( ) ) { + if ( leftHandSide == augmentedGrammar.getInitialSymbol ( ) ) { + insertToActionTable(actionTable, { state, LRParser::getEndOfInputSymbol(augmentedGrammar) }, { LRAction::Accept, state } ); + continue; + } + + grammar::parsing::FollowResult2 followSet = grammar::parsing::Follow::follow ( augmentedGrammar, leftHandSide ); + std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > currentRule = { leftHandSide, rightHandSide }; + for ( const std::variant < alphabet::Symbol, string::Epsilon > & followSymbol : followSet ) { + if ( followSymbol.is < alphabet::Symbol > ( ) ) { + insertToActionTable(actionTable, { state, followSymbol.get < alphabet::Symbol > ( ) }, { LRAction::Reduce, currentRule } ); + } else { + insertToActionTable(actionTable, { state, LRParser::getEndOfInputSymbol(augmentedGrammar) }, { LRAction::Reduce, currentRule } ); + } + } + continue; + } + + alphabet::Symbol currentSymbol = rightHandSide[position]; + if ( originalGrammar.getTerminalAlphabet ( ) . find ( currentSymbol ) != originalGrammar.getTerminalAlphabet ( ) . end ( ) ) { + insertToActionTable(actionTable, { state, currentSymbol }, { LRAction::Shift, transitionsFromCurrentState.find ( { state, currentSymbol } )->second } ); + } + } + } + } + + return actionTable; +} + +} /* namespace parsing */ + +} /* namespace grammar */ diff --git a/alib2algo/src/grammar/parsing/SLR1ParseTable.h b/alib2algo/src/grammar/parsing/SLR1ParseTable.h new file mode 100644 index 0000000000..3f4c6a4b5a --- /dev/null +++ b/alib2algo/src/grammar/parsing/SLR1ParseTable.h @@ -0,0 +1,31 @@ +/* + * SLR1ParseTable.h + * + * Created on: 4. 5. 2016 + * Author: Martin Kocicka + */ + +#ifndef SLR_1_PARSE_TABLE_H_ +#define SLR_1_PARSE_TABLE_H_ + +#include "LRParser.h" + +#include <grammar/ContextFree/CFG.h> +#include <grammar/parsing/LRParserTypes.h> + +namespace grammar { + +namespace parsing { + +class SLR1ParseTable { + static void insertToActionTable ( LRActionTable & actionTable, LRActionTable::key_type key, LRActionTable::mapped_type value ); + +public: + static LRActionTable getActionTable ( grammar::CFG originalGrammar ); +}; + +} /* namespace parsing */ + +} /* namespace grammar */ + +#endif /* SLR_1_PARSE_TABLE_H_ */ -- GitLab