diff --git a/alib2algo/src/grammar/parsing/SLR1ParseTable.cpp b/alib2algo/src/grammar/parsing/SLR1ParseTable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0b3025d18bab07596196d4098a204f6a6d92c4d8 --- /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 0000000000000000000000000000000000000000..3f4c6a4b5a8c5d5843939c7f434e588db16f0e05 --- /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_ */