diff --git a/alib2algo/src/grammar/convert/ToGrammarLeftRG.cpp b/alib2algo/src/grammar/convert/ToGrammarLeftRG.cpp index 3b7659b4a2afd0ecba38148d128d0221e331464a..ab7ae99d6883d0982a91821cefb449bcbbc957e5 100644 --- a/alib2algo/src/grammar/convert/ToGrammarLeftRG.cpp +++ b/alib2algo/src/grammar/convert/ToGrammarLeftRG.cpp @@ -6,64 +6,15 @@ */ #include "ToGrammarLeftRG.h" -#include <common/createUnique.hpp> namespace grammar { namespace convert { -grammar::LeftRG < > ToGrammarLeftRG::convert(const grammar::Grammar& grammar) { +grammar::Grammar ToGrammarLeftRG::convert(const grammar::Grammar& grammar) { return dispatch(grammar.getData()); } -grammar::LeftRG < > ToGrammarLeftRG::convert(const grammar::RightRG < > & grammar) { - // 1. - alphabet::Symbol s = common::createUnique( grammar.getInitialSymbol( ), grammar.getNonterminalAlphabet(), grammar.getTerminalAlphabet() ); - - grammar::LeftRG < > lrg(s); - - for(const auto & nonterminalSymbol : grammar.getNonterminalAlphabet()) { - lrg.addNonterminalSymbol( nonterminalSymbol ); - } - - lrg.setTerminalAlphabet( grammar.getTerminalAlphabet( ) ); - lrg.setGeneratesEpsilon( grammar.getGeneratesEpsilon( ) ); - - // 2. - for( const auto & rule : grammar.getRules( ) ) { - const alphabet::Symbol& lhs = rule.first; - - for(const auto & ruleRHS : rule.second ) { - if( ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>( ) ) { - const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>(); - - alphabet::Symbol leftSide = rhs.second; - std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair( lhs, rhs.first ); - lrg.addRule( leftSide, rightSide ); - - if( lhs == grammar.getInitialSymbol( ) ) { - leftSide = rhs.second; - alphabet::Symbol rightSide2 = rhs.first; - lrg.addRule( leftSide, rightSide2 ); - } - } else { - const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>(); - - alphabet::Symbol leftSide = lrg.getInitialSymbol( ); - std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair ( lhs, rhs ); - lrg.addRule( leftSide, rightSide ); - - if( lhs == grammar.getInitialSymbol( ) ) { - leftSide = lrg.getInitialSymbol( ); - alphabet::Symbol rightSide2 = rhs; - lrg.addRule( leftSide, rightSide2 ); - } - } - } - } - return lrg; -} - auto ToGrammarLeftRGRightRG = ToGrammarLeftRG::RegistratorWrapper<grammar::LeftRG < >, grammar::RightRG < > >(ToGrammarLeftRG::convert); } /* namespace convert */ diff --git a/alib2algo/src/grammar/convert/ToGrammarLeftRG.h b/alib2algo/src/grammar/convert/ToGrammarLeftRG.h index ffb07f9e62bf3c136bd2438a09897a07f80ed20c..8475e0ae4eaec1903967598030e5ad2eaf6cb8af 100644 --- a/alib2algo/src/grammar/convert/ToGrammarLeftRG.h +++ b/alib2algo/src/grammar/convert/ToGrammarLeftRG.h @@ -14,6 +14,8 @@ #include <grammar/Regular/LeftRG.h> #include <grammar/Regular/RightRG.h> +#include <common/createUnique.hpp> + namespace grammar { namespace convert { @@ -21,17 +23,69 @@ namespace convert { /** * Converts right regular grammar to left regular grammar. */ -class ToGrammarLeftRG : public std::SingleDispatch<ToGrammarLeftRG, grammar::LeftRG < >, const grammar::GrammarBase &> { +class ToGrammarLeftRG : public std::SingleDispatch<ToGrammarLeftRG, grammar::Grammar, const grammar::GrammarBase &> { public: /** * Performs conversion. * @param grammar Right regular grammar to convert * @return left regular grammar which is equivalent to source right regular grammar. */ - static grammar::LeftRG < > convert(const grammar::Grammar& grammar); - static grammar::LeftRG < > convert(const grammar::RightRG < > & grammar); + static grammar::Grammar convert(const grammar::Grammar& grammar); + + template < class SymbolType > + static grammar::LeftRG < SymbolType > convert(const grammar::RightRG < SymbolType > & grammar); }; +template < class SymbolType > +grammar::LeftRG < SymbolType > ToGrammarLeftRG::convert(const grammar::RightRG < SymbolType > & grammar) { + // 1. + SymbolType s = common::createUnique( grammar.getInitialSymbol( ), grammar.getNonterminalAlphabet(), grammar.getTerminalAlphabet() ); + + grammar::LeftRG < SymbolType > lrg(s); + + for(const auto & nonterminalSymbol : grammar.getNonterminalAlphabet()) { + lrg.addNonterminalSymbol( nonterminalSymbol ); + } + + lrg.setTerminalAlphabet( grammar.getTerminalAlphabet( ) ); + lrg.setGeneratesEpsilon( grammar.getGeneratesEpsilon( ) ); + + // 2. + for( const auto & rule : grammar.getRules( ) ) { + const SymbolType& lhs = rule.first; + + for(const auto & ruleRHS : rule.second ) { + if( ruleRHS.template is<std::pair<SymbolType, SymbolType>>( ) ) { + const std::pair<SymbolType, SymbolType>& rhs = ruleRHS.template get<std::pair<SymbolType, SymbolType>>(); + + SymbolType leftSide = rhs.second; + std::pair<SymbolType, SymbolType> rightSide = std::make_pair( lhs, rhs.first ); + lrg.addRule( leftSide, rightSide ); + + if( lhs == grammar.getInitialSymbol( ) ) { + leftSide = rhs.second; + SymbolType rightSide2 = rhs.first; + lrg.addRule( leftSide, rightSide2 ); + } + } else { + const SymbolType& rhs = ruleRHS.template get<SymbolType>(); + + SymbolType leftSide = lrg.getInitialSymbol( ); + std::pair<SymbolType, SymbolType> rightSide = std::make_pair ( lhs, rhs ); + lrg.addRule( leftSide, rightSide ); + + if( lhs == grammar.getInitialSymbol( ) ) { + leftSide = lrg.getInitialSymbol( ); + SymbolType rightSide2 = rhs; + lrg.addRule( leftSide, rightSide2 ); + } + } + } + } + + return lrg; +} + } /* namespace convert */ } /* namespace grammar */ diff --git a/alib2algo/src/grammar/convert/ToGrammarRightRG.cpp b/alib2algo/src/grammar/convert/ToGrammarRightRG.cpp index d7c9b0e10d04c2408c65f741406d26fceb70d53f..062ed8e822eb273bbd0d544bb792e553c2a3b94b 100644 --- a/alib2algo/src/grammar/convert/ToGrammarRightRG.cpp +++ b/alib2algo/src/grammar/convert/ToGrammarRightRG.cpp @@ -6,64 +6,15 @@ */ #include "ToGrammarRightRG.h" -#include <common/createUnique.hpp> namespace grammar { namespace convert { -grammar::RightRG < > ToGrammarRightRG::convert(const grammar::Grammar& grammar) { +grammar::Grammar ToGrammarRightRG::convert(const grammar::Grammar& grammar) { return dispatch(grammar.getData()); } -grammar::RightRG < > ToGrammarRightRG::convert(const grammar::LeftRG < > & grammar) { - // 1. - alphabet::Symbol s = common::createUnique( grammar.getInitialSymbol( ), grammar.getNonterminalAlphabet(), grammar.getTerminalAlphabet() ); - - grammar::RightRG < > rrg( s ); - - for(const auto & nonterminalSymbol : grammar.getNonterminalAlphabet() ) { - rrg.addNonterminalSymbol( nonterminalSymbol ); - } - - rrg.setTerminalAlphabet( grammar.getTerminalAlphabet( ) ); - rrg.setGeneratesEpsilon( grammar.getGeneratesEpsilon( ) ); - - // 2 - for( const auto & rule : grammar.getRules( ) ) { - const alphabet::Symbol& lhs = rule.first; - - for(const auto & ruleRHS : rule.second ) { - if( ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>( ) ) { - const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>(); - - alphabet::Symbol leftSide = ( rhs.first ); - std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair( rhs.second, lhs ); - rrg.addRule( leftSide, rightSide ); - - if( lhs == grammar.getInitialSymbol( ) ) { - leftSide = rhs.first; - alphabet::Symbol rightSide2 = rhs.second; - rrg.addRule( leftSide, rightSide2 ); - } - } else { - const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>(); - - alphabet::Symbol leftSide = rrg.getInitialSymbol( ); - std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair( rhs, lhs ); - rrg.addRule( leftSide, rightSide ); - - if( lhs == grammar.getInitialSymbol( ) ) { - leftSide = rrg.getInitialSymbol( ); - alphabet::Symbol rightSide2 = rhs; - rrg.addRule( leftSide, rightSide2 ); - } - } - } - } - return rrg; -} - auto ToGrammarRightRGLeftRG = ToGrammarRightRG::RegistratorWrapper<grammar::RightRG < >, grammar::LeftRG < > >(ToGrammarRightRG::convert); } /* namespace convert */ diff --git a/alib2algo/src/grammar/convert/ToGrammarRightRG.h b/alib2algo/src/grammar/convert/ToGrammarRightRG.h index 0559ab99d937318ffd0ffa1050f4e3bd300f035f..4e4b6e6ab1e54baeac043bb439df6e2a16ccbcc2 100644 --- a/alib2algo/src/grammar/convert/ToGrammarRightRG.h +++ b/alib2algo/src/grammar/convert/ToGrammarRightRG.h @@ -14,6 +14,8 @@ #include <grammar/Regular/LeftRG.h> #include <grammar/Regular/RightRG.h> +#include <common/createUnique.hpp> + namespace grammar { namespace convert { @@ -21,17 +23,68 @@ namespace convert { /** * Converts left regular grammar to right regular grammar. */ -class ToGrammarRightRG : public std::SingleDispatch<ToGrammarRightRG, grammar::RightRG < >, const grammar::GrammarBase &> { +class ToGrammarRightRG : public std::SingleDispatch<ToGrammarRightRG, grammar::Grammar, const grammar::GrammarBase &> { public: /** * Performs conversion. * @param grammar Left regular grammar to convert * @return right regular grammar which is equivalent to source left regular grammar. */ - static grammar::RightRG < > convert(const grammar::Grammar& grammar); - static grammar::RightRG < > convert(const grammar::LeftRG < > & grammar); + static grammar::Grammar convert(const grammar::Grammar& grammar); + + template < class SymbolType > + static grammar::RightRG < SymbolType > convert(const grammar::LeftRG < SymbolType > & grammar); }; +template < class SymbolType > +grammar::RightRG < SymbolType > ToGrammarRightRG::convert(const grammar::LeftRG < SymbolType > & grammar) { + // 1. + SymbolType s = common::createUnique( grammar.getInitialSymbol( ), grammar.getNonterminalAlphabet(), grammar.getTerminalAlphabet() ); + + grammar::RightRG < SymbolType > rrg( s ); + + for(const auto & nonterminalSymbol : grammar.getNonterminalAlphabet() ) { + rrg.addNonterminalSymbol( nonterminalSymbol ); + } + + rrg.setTerminalAlphabet( grammar.getTerminalAlphabet( ) ); + rrg.setGeneratesEpsilon( grammar.getGeneratesEpsilon( ) ); + + // 2 + for( const auto & rule : grammar.getRules( ) ) { + const SymbolType& lhs = rule.first; + + for(const auto & ruleRHS : rule.second ) { + if( ruleRHS.template is<std::pair<SymbolType, SymbolType>>( ) ) { + const std::pair<SymbolType, SymbolType>& rhs = ruleRHS.template get<std::pair<SymbolType, SymbolType>>(); + + SymbolType leftSide = ( rhs.first ); + std::pair<SymbolType, SymbolType> rightSide = std::make_pair( rhs.second, lhs ); + rrg.addRule( leftSide, rightSide ); + + if( lhs == grammar.getInitialSymbol( ) ) { + leftSide = rhs.first; + SymbolType rightSide2 = rhs.second; + rrg.addRule( leftSide, rightSide2 ); + } + } else { + const SymbolType& rhs = ruleRHS.template get<SymbolType>(); + + SymbolType leftSide = rrg.getInitialSymbol( ); + std::pair<SymbolType, SymbolType> rightSide = std::make_pair( rhs, lhs ); + rrg.addRule( leftSide, rightSide ); + + if( lhs == grammar.getInitialSymbol( ) ) { + leftSide = rrg.getInitialSymbol( ); + SymbolType rightSide2 = rhs; + rrg.addRule( leftSide, rightSide2 ); + } + } + } + } + return rrg; +} + } /* namespace convert */ } /* namespace grammar */ diff --git a/anormalize2/src/anormalize.cpp b/anormalize2/src/anormalize.cpp index c3edc07b31480c67c55c3f0fb95d2c515f9a2d40..ec55bffee9f3af3463075ba2827755d666eff423 100644 --- a/anormalize2/src/anormalize.cpp +++ b/anormalize2/src/anormalize.cpp @@ -116,7 +116,7 @@ int main ( int argc, char * * argv ) { measurements::end ( ); measurements::start ( "Algorithm", measurements::Type::MAIN ); - grammar::LeftRG < > res = grammar::convert::ToGrammarLeftRG::convert ( grammar ); + grammar::Grammar res = grammar::convert::ToGrammarLeftRG::convert ( grammar ); measurements::end ( ); measurements::start ( "Output write", measurements::Type::AUXILIARY ); @@ -128,7 +128,7 @@ int main ( int argc, char * * argv ) { measurements::end ( ); measurements::start ( "Algorithm", measurements::Type::MAIN ); - grammar::RightRG < > res = grammar::convert::ToGrammarRightRG::convert ( grammar ); + grammar::Grammar res = grammar::convert::ToGrammarRightRG::convert ( grammar ); measurements::end ( ); measurements::start ( "Output write", measurements::Type::AUXILIARY );