From b45f05d46ea89de606bd868d8a3956f09bc71a9a Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Fri, 6 Nov 2015 21:37:52 +0100 Subject: [PATCH] continue refactoring 2 --- .../grammar/parsing/AbsorbTerminalSymbol.cpp | 67 +++++++++++++++ .../grammar/parsing/AbsorbTerminalSymbol.h | 31 +++++++ .../parsing/DeterministicLL1Grammar.cpp | 83 ++----------------- .../grammar/parsing/ExtractRightContext.cpp | 46 ++++++++++ .../src/grammar/parsing/ExtractRightContext.h | 29 +++++++ 5 files changed, 178 insertions(+), 78 deletions(-) create mode 100644 alib2algo/src/grammar/parsing/AbsorbTerminalSymbol.cpp create mode 100644 alib2algo/src/grammar/parsing/AbsorbTerminalSymbol.h create mode 100644 alib2algo/src/grammar/parsing/ExtractRightContext.cpp create mode 100644 alib2algo/src/grammar/parsing/ExtractRightContext.h diff --git a/alib2algo/src/grammar/parsing/AbsorbTerminalSymbol.cpp b/alib2algo/src/grammar/parsing/AbsorbTerminalSymbol.cpp new file mode 100644 index 0000000000..61f6a8103b --- /dev/null +++ b/alib2algo/src/grammar/parsing/AbsorbTerminalSymbol.cpp @@ -0,0 +1,67 @@ +/* + * AbsorbTerminalSymbol.cpp + * + * Created on: 9. 6. 2015 + * Author: Jan Travnicek + */ + +#include "AbsorbTerminalSymbol.h" + +#include <grammar/ContextFree/CFG.h> +#include <alphabet/SymbolPairSymbol.h> + +namespace grammar { + +namespace parsing { + +alphabet::Symbol AbsorbTerminalSymbol::handleAbsobtion ( const grammar::CFG & orig, grammar::CFG & res, const alphabet::Symbol & nonterminal, const alphabet::Symbol & terminal ) { + alphabet::Symbol newSymbol = alphabet::createUniqueSymbol ( alphabet::Symbol ( alphabet::SymbolPairSymbol ( std::make_pair ( nonterminal, terminal ) ) ), res.getTerminalAlphabet ( ), res.getNonterminalAlphabet ( ) ); + + for ( const std::vector < alphabet::Symbol > & rhs : orig.getRules ( ).find ( nonterminal )->second ) { + std::vector < alphabet::Symbol > newRHS ( rhs.begin ( ), rhs.end ( ) ); + newRHS.push_back ( terminal ); + res.addRule ( newSymbol, newRHS ); + } + + return newSymbol; +} + +void AbsorbTerminalSymbol::absorbTerminalSymbol ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const std::set < alphabet::Symbol > & nonterminals ) { + grammar::CFG res ( grammar.getInitialSymbol ( ) ); + + res.setNonterminalAlphabet ( grammar.getNonterminalAlphabet ( ) ); + res.setTerminalAlphabet ( grammar.getTerminalAlphabet ( ) ); + + std::map < alphabet::Symbol, alphabet::Symbol > nonterminalsPrimed; // terminal is fixed in particular calls + + for ( const alphabet::Symbol & nonterminal : nonterminals ) { + alphabet::Symbol newSymbol = handleAbsobtion ( grammar, res, nonterminal, terminal ); + res.addNonterminalSymbol ( newSymbol ); + nonterminalsPrimed.insert ( std::make_pair ( nonterminal, newSymbol ) ); + } + + for ( const std::pair < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > > & rule : grammar.getRules ( ) ) { + const alphabet::Symbol & lhs = rule.first; + + for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) { + std::vector < alphabet::Symbol > newRHS; + + for ( std::vector < alphabet::Symbol >::const_iterator iter = rhs.begin ( ); iter + 1 != rhs.end ( ); ++iter ) { + if ( nonterminals.count ( * iter ) && ( terminal == * ( iter + 1 ) ) ) { + newRHS.push_back ( nonterminalsPrimed.find ( * iter )->second ); + ++iter; + } else { + newRHS.push_back ( * iter ); + } + } + + res.addRule ( lhs, newRHS ); + } + } + + grammar = res; +} + +} /* namespace parsing */ + +} /* namespace grammar */ diff --git a/alib2algo/src/grammar/parsing/AbsorbTerminalSymbol.h b/alib2algo/src/grammar/parsing/AbsorbTerminalSymbol.h new file mode 100644 index 0000000000..a04ea6acb2 --- /dev/null +++ b/alib2algo/src/grammar/parsing/AbsorbTerminalSymbol.h @@ -0,0 +1,31 @@ +/* + * AbsorbTerminalSymbol.h + * + * Created on: 9. 6. 2015 + * Author: Jan Travnicek + */ + +#ifndef ABSORB_TERMINAL_SYMBOL_H_ +#define ABSORB_TERMINAL_SYMBOL_H_ + +#include <grammar/GrammarFeatures.h> +#include <alphabet/Symbol.h> +#include <set> + +namespace grammar { + +namespace parsing { + +class AbsorbTerminalSymbol { +public: + static alphabet::Symbol handleAbsobtion ( const grammar::CFG & orig, grammar::CFG & res, const alphabet::Symbol & nonterminal, const alphabet::Symbol & terminal ); + + static void absorbTerminalSymbol ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const std::set < alphabet::Symbol > & nonterminals ); + +}; + +} /* namespace parsing */ + +} /* namespace grammar */ + +#endif /* ABSORB_TERMINAL_SYMBOL_H_ */ diff --git a/alib2algo/src/grammar/parsing/DeterministicLL1Grammar.cpp b/alib2algo/src/grammar/parsing/DeterministicLL1Grammar.cpp index 1aece85b06..5a35f8598e 100644 --- a/alib2algo/src/grammar/parsing/DeterministicLL1Grammar.cpp +++ b/alib2algo/src/grammar/parsing/DeterministicLL1Grammar.cpp @@ -1,5 +1,5 @@ /* - * DeterministicLL1ParseTable.cpp + * DeterministicLL1Grammar.cpp * * Created on: 9. 6. 2015 * Author: Jan Travnicek @@ -11,6 +11,8 @@ #include "../properties/NullableNonterminals.h" #include "common/Substitute.h" #include "HandleFirstFirstConflict.h" +#include "AbsorbTerminalSymbol.h" +#include "ExtractRightContext.h" #include <grammar/ContextFree/CFG.h> #include <exception/AlibException.h> @@ -21,81 +23,6 @@ namespace grammar { namespace parsing { -alphabet::Symbol handleAbsobtion ( const grammar::CFG & orig, grammar::CFG & res, const alphabet::Symbol & nonterminal, const alphabet::Symbol & terminal ) { - alphabet::Symbol newSymbol = alphabet::createUniqueSymbol ( alphabet::Symbol ( alphabet::SymbolPairSymbol ( std::make_pair ( nonterminal, terminal ) ) ), res.getTerminalAlphabet ( ), res.getNonterminalAlphabet ( ) ); - - for ( const std::vector < alphabet::Symbol > & rhs : orig.getRules ( ).find ( nonterminal )->second ) { - std::vector < alphabet::Symbol > newRHS ( rhs.begin ( ), rhs.end ( ) ); - newRHS.push_back ( terminal ); - res.addRule ( newSymbol, newRHS ); - } - - return newSymbol; -} - -void absorbTerminalSymbol ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const std::set < alphabet::Symbol > & nonterminals ) { - grammar::CFG res ( grammar.getInitialSymbol ( ) ); - - res.setNonterminalAlphabet ( grammar.getNonterminalAlphabet ( ) ); - res.setTerminalAlphabet ( grammar.getTerminalAlphabet ( ) ); - - std::map < alphabet::Symbol, alphabet::Symbol > nonterminalsPrimed; // terminal is fixed in particular calls - - for ( const alphabet::Symbol & nonterminal : nonterminals ) { - alphabet::Symbol newSymbol = handleAbsobtion ( grammar, res, nonterminal, terminal ); - res.addNonterminalSymbol ( newSymbol ); - nonterminalsPrimed.insert ( std::make_pair ( nonterminal, newSymbol ) ); - } - - for ( const std::pair < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > > & rule : grammar.getRules ( ) ) { - const alphabet::Symbol & lhs = rule.first; - - for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) { - std::vector < alphabet::Symbol > newRHS; - - for ( std::vector < alphabet::Symbol >::const_iterator iter = rhs.begin ( ); iter + 1 != rhs.end ( ); ++iter ) { - if ( nonterminals.count ( * iter ) && ( terminal == * ( iter + 1 ) ) ) { - newRHS.push_back ( nonterminalsPrimed.find ( * iter )->second ); - ++iter; - } else { - newRHS.push_back ( * iter ); - } - } - - res.addRule ( lhs, newRHS ); - } - } - - grammar = res; -} - -void extractRightContext ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const std::set < alphabet::Symbol > & nonterminals ) { - grammar::CFG res ( grammar.getInitialSymbol ( ) ); - - res.setNonterminalAlphabet ( grammar.getNonterminalAlphabet ( ) ); - res.setTerminalAlphabet ( grammar.getTerminalAlphabet ( ) ); - - for ( const std::pair < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > > & rule : grammar.getRules ( ) ) { - const alphabet::Symbol & lhs = rule.first; - - for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) - for ( std::vector < alphabet::Symbol >::const_iterator iter = rhs.begin ( ); iter + 1 != rhs.end ( ); ++iter ) { - bool substitued = false; - - if ( nonterminals.count ( * iter ) && First::first ( grammar, std::vector < alphabet::Symbol > ( iter + 1, rhs.end ( ) ) ).count ( terminal ) && !grammar.getTerminalAlphabet ( ).count ( * iter ) ) { - substitued = true; - Substitute::substitute ( grammar, res, lhs, rhs, iter ); - } - - if ( !substitued ) - res.addRule ( lhs, rhs ); - } - - } - - grammar = res; -} - bool handleFirstFollowConflict ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const alphabet::Symbol & nonterminal, const std::set < std::vector < alphabet::Symbol > > & /* rhsds */ ) { std::set < alphabet::Symbol > nullableNonterminals = properties::NullableNonterminals::getNullableNonterminals ( grammar ); @@ -128,13 +55,13 @@ bool handleFirstFollowConflict ( grammar::CFG & grammar, const alphabet::Symbol for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) { for ( std::vector < alphabet::Symbol >::const_iterator iter = rhs.begin ( ); iter + 1 != rhs.end ( ); ++iter ) if ( symbolsEndingWithNonterminal.count ( * iter ) && First::first ( grammar, std::vector < alphabet::Symbol > ( iter + 1, rhs.end ( ) ) ).count ( terminal ) && !grammar.getTerminalAlphabet ( ).count ( * iter ) ) { - extractRightContext ( grammar, terminal, symbolsEndingWithNonterminal ); + ExtractRightContext::extractRightContext ( grammar, terminal, symbolsEndingWithNonterminal ); return true; } } - absorbTerminalSymbol ( grammar, terminal, symbolsEndingWithNonterminal ); + AbsorbTerminalSymbol::absorbTerminalSymbol ( grammar, terminal, symbolsEndingWithNonterminal ); return true; } diff --git a/alib2algo/src/grammar/parsing/ExtractRightContext.cpp b/alib2algo/src/grammar/parsing/ExtractRightContext.cpp new file mode 100644 index 0000000000..5a18645b25 --- /dev/null +++ b/alib2algo/src/grammar/parsing/ExtractRightContext.cpp @@ -0,0 +1,46 @@ +/* + * ExtractRightContext.cpp + * + * Created on: 9. 6. 2015 + * Author: Jan Travnicek + */ + +#include "ExtractRightContext.h" +#include "First.h" +#include "common/Substitute.h" +#include <grammar/ContextFree/CFG.h> + +namespace grammar { + +namespace parsing { + +void ExtractRightContext::extractRightContext ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const std::set < alphabet::Symbol > & nonterminals ) { + grammar::CFG res ( grammar.getInitialSymbol ( ) ); + + res.setNonterminalAlphabet ( grammar.getNonterminalAlphabet ( ) ); + res.setTerminalAlphabet ( grammar.getTerminalAlphabet ( ) ); + + for ( const std::pair < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > > & rule : grammar.getRules ( ) ) { + const alphabet::Symbol & lhs = rule.first; + + for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) + for ( std::vector < alphabet::Symbol >::const_iterator iter = rhs.begin ( ); iter + 1 != rhs.end ( ); ++iter ) { + bool substitued = false; + + if ( nonterminals.count ( * iter ) && First::first ( grammar, std::vector < alphabet::Symbol > ( iter + 1, rhs.end ( ) ) ).count ( terminal ) && !grammar.getTerminalAlphabet ( ).count ( * iter ) ) { + substitued = true; + Substitute::substitute ( grammar, res, lhs, rhs, iter ); + } + + if ( !substitued ) + res.addRule ( lhs, rhs ); + } + + } + + grammar = res; +} + +} /* namespace parsing */ + +} /* namespace grammar */ diff --git a/alib2algo/src/grammar/parsing/ExtractRightContext.h b/alib2algo/src/grammar/parsing/ExtractRightContext.h new file mode 100644 index 0000000000..978729ef71 --- /dev/null +++ b/alib2algo/src/grammar/parsing/ExtractRightContext.h @@ -0,0 +1,29 @@ +/* + * ExtractRightContext.h + * + * Created on: 9. 6. 2015 + * Author: Jan Travnicek + */ + +#ifndef EXTRACT_RIGHT_CONTEXT_H_ +#define EXTRACT_RIGHT_CONTEXT_H_ + +#include <grammar/GrammarFeatures.h> +#include <alphabet/Symbol.h> +#include <set> + +namespace grammar { + +namespace parsing { + +class ExtractRightContext { +public: + static void extractRightContext ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const std::set < alphabet::Symbol > & nonterminals ); + +}; + +} /* namespace parsing */ + +} /* namespace grammar */ + +#endif /* EXTRACT_RIGHT_CONTEXT_H_ */ -- GitLab