diff --git a/alib2algo/src/grammar/parsing/CornerSubstitution.cpp b/alib2algo/src/grammar/parsing/CornerSubstitution.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ee0f90e2ccc61bfa419c482fbc86537226ecf8e8 --- /dev/null +++ b/alib2algo/src/grammar/parsing/CornerSubstitution.cpp @@ -0,0 +1,40 @@ +/* + * CornerSubstitution.cpp + * + * Created on: 9. 6. 2015 + * Author: Jan Travnicek + */ + +#include "First.h" +#include "common/Substitute.h" +#include "CornerSubstitution.h" + +#include <grammar/ContextFree/CFG.h> + +namespace grammar { + +namespace parsing { + +void CornerSubstitution::cornerSubstitution ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const alphabet::Symbol & nonterminal ) { + 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 ) { + if ( ( lhs == nonterminal ) && ( rhs.size ( ) > 0 ) && ( rhs[0] == nonterminal ) && First::first ( grammar, rhs ).count ( terminal ) ) + Substitute::substitute ( grammar, res, lhs, rhs, rhs.begin ( ) ); + else + res.addRule ( lhs, rhs ); + } + } + + grammar = res; +} + +} /* namespace parsing */ + +} /* namespace grammar */ diff --git a/alib2algo/src/grammar/parsing/CornerSubstitution.h b/alib2algo/src/grammar/parsing/CornerSubstitution.h new file mode 100644 index 0000000000000000000000000000000000000000..cf01564b7c901ea139640498d0924049b489123a --- /dev/null +++ b/alib2algo/src/grammar/parsing/CornerSubstitution.h @@ -0,0 +1,28 @@ +/* + * CornerSubstitution.h + * + * Created on: 9. 6. 2015 + * Author: Jan Travnicek + */ + +#ifndef CORNER_SUBSTITUTION_H_ +#define CORNER_SUBSTITUTION_H_ + +#include <grammar/GrammarFeatures.h> +#include <alphabet/Symbol.h> + +namespace grammar { + +namespace parsing { + +class CornerSubstitution { +public: + static void cornerSubstitution ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const alphabet::Symbol & nonterminal ); + +}; + +} /* namespace parsing */ + +} /* namespace grammar */ + +#endif /* CORNER_SUBSTITUTION_H_ */ diff --git a/alib2algo/src/grammar/parsing/DeterministicLL1Grammar.cpp b/alib2algo/src/grammar/parsing/DeterministicLL1Grammar.cpp index 39d411e5cd69df1e9f3b077f9211e61fb282d64c..1aece85b06bec80434e716fc153ebdea35be7348 100644 --- a/alib2algo/src/grammar/parsing/DeterministicLL1Grammar.cpp +++ b/alib2algo/src/grammar/parsing/DeterministicLL1Grammar.cpp @@ -2,7 +2,7 @@ * DeterministicLL1ParseTable.cpp * * Created on: 9. 6. 2015 - * Author: Tomas Pecka + * Author: Jan Travnicek */ #include "DeterministicLL1Grammar.h" @@ -10,7 +10,7 @@ #include "First.h" #include "../properties/NullableNonterminals.h" #include "common/Substitute.h" -#include "LeftFactorize.h" +#include "HandleFirstFirstConflict.h" #include <grammar/ContextFree/CFG.h> #include <exception/AlibException.h> @@ -21,37 +21,6 @@ namespace grammar { namespace parsing { -void cornerSubstitution ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const alphabet::Symbol & nonterminal ) { - 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 ) { - if ( ( lhs == nonterminal ) && ( rhs.size ( ) > 0 ) && ( rhs[0] == nonterminal ) && First::first ( grammar, rhs ).count ( terminal ) ) - Substitute::substitute ( grammar, res, lhs, rhs, rhs.begin ( ) ); - else - res.addRule ( lhs, rhs ); - } - } - - grammar = res; -} - -bool handleFirstFirstConflict ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const alphabet::Symbol & nonterminal, const std::set < std::vector < alphabet::Symbol > > & rhsds ) { - for ( const std::vector < alphabet::Symbol > & rhs : rhsds ) - if ( ( rhs.size ( ) > 0 ) && grammar.getNonterminalAlphabet ( ).count ( rhs[0] ) && First::first ( grammar, rhs ).count ( terminal ) ) { - cornerSubstitution ( grammar, terminal, nonterminal ); - return true; - } - - LeftFactorize::leftFactorize ( grammar, terminal, nonterminal ); - return true; -} - 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 ( ) ); @@ -175,7 +144,7 @@ bool transformToLL1 ( grammar::CFG & grammar, const alphabet::Symbol & terminal, } ) ) return handleFirstFollowConflict ( grammar, terminal, nonterminal, rhsds ); else - return handleFirstFirstConflict ( grammar, terminal, nonterminal, rhsds ); + return HandleFirstFirstConflict::handleFirstFirstConflict ( grammar, terminal, nonterminal, rhsds ); } grammar::CFG DeterministicLL1Grammar::convert ( const grammar::CFG & param ) { diff --git a/alib2algo/src/grammar/parsing/HandleFirstFirstConflict.cpp b/alib2algo/src/grammar/parsing/HandleFirstFirstConflict.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a5f5c7bd64f470571200fc12b738b236af16ceee --- /dev/null +++ b/alib2algo/src/grammar/parsing/HandleFirstFirstConflict.cpp @@ -0,0 +1,32 @@ +/* + * DeterministicLL1ParseTable.cpp + * + * Created on: 9. 6. 2015 + * Author: Jan Travnicek + */ + +#include "HandleFirstFirstConflict.h" +#include "First.h" +#include "LeftFactorize.h" +#include "CornerSubstitution.h" + +#include <grammar/ContextFree/CFG.h> + +namespace grammar { + +namespace parsing { + +bool HandleFirstFirstConflict::handleFirstFirstConflict ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const alphabet::Symbol & nonterminal, const std::set < std::vector < alphabet::Symbol > > & rhsds ) { + for ( const std::vector < alphabet::Symbol > & rhs : rhsds ) + if ( ( rhs.size ( ) > 0 ) && grammar.getNonterminalAlphabet ( ).count ( rhs[0] ) && First::first ( grammar, rhs ).count ( terminal ) ) { + CornerSubstitution::cornerSubstitution ( grammar, terminal, nonterminal ); + return true; + } + + LeftFactorize::leftFactorize ( grammar, terminal, nonterminal ); + return true; +} + +} /* namespace parsing */ + +} /* namespace grammar */ diff --git a/alib2algo/src/grammar/parsing/HandleFirstFirstConflict.h b/alib2algo/src/grammar/parsing/HandleFirstFirstConflict.h new file mode 100644 index 0000000000000000000000000000000000000000..b9bce9ccf042d6c07ee71b360fc21df8d0065831 --- /dev/null +++ b/alib2algo/src/grammar/parsing/HandleFirstFirstConflict.h @@ -0,0 +1,29 @@ +/* + * HandleFirstFirstConflict.h + * + * Created on: 9. 6. 2015 + * Author: Jan Travnicek + */ + +#ifndef HANDLE_FIRST_FIRST_CONFLICT_H_ +#define HANDLE_FIRST_FIRST_CONFLICT_H_ + +#include <grammar/GrammarFeatures.h> +#include <alphabet/Symbol.h> +#include <vector> + +namespace grammar { + +namespace parsing { + +class HandleFirstFirstConflict { +public: + static bool handleFirstFirstConflict ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const alphabet::Symbol & nonterminal, const std::set < std::vector < alphabet::Symbol > > & rhsds ); + +}; + +} /* namespace parsing */ + +} /* namespace grammar */ + +#endif /* HANDLE_FIRST_FIRST_CONFLICT_H_ */