From c284362f414b929f9a6c99be434b646ab0f41df2 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Mon, 17 Sep 2018 16:21:50 +0200 Subject: [PATCH] template LeftRG datatype and RRG <-> LRG algos --- .../src/grammar/convert/ToGrammarLeftRG.h | 41 ++-- .../src/grammar/convert/ToGrammarRightRG.h | 41 ++-- alib2data/src/grammar/Regular/LeftRG.h | 210 +++++++++--------- alib2data/src/grammar/Regular/RightRG.h | 12 +- 4 files changed, 161 insertions(+), 143 deletions(-) diff --git a/alib2algo/src/grammar/convert/ToGrammarLeftRG.h b/alib2algo/src/grammar/convert/ToGrammarLeftRG.h index fea91f6220..8fe5e86b7a 100644 --- a/alib2algo/src/grammar/convert/ToGrammarLeftRG.h +++ b/alib2algo/src/grammar/convert/ToGrammarLeftRG.h @@ -24,19 +24,24 @@ class ToGrammarLeftRG { public: /** * Performs conversion. - * @param grammar Right regular grammar to convert - * @return left regular grammar which is equivalent to source right regular grammar. + * + * \tparam TerminalSymbolType used for the terminal alphabet of the grammar. + * \tparam NonterminalSymbolType used for the nonterminal alphabet, and the initial symbol of the grammar. + * + * \param grammar Right regular grammar to convert + * + * \return left regular grammar which is equivalent to source right regular grammar. */ - template < class SymbolType > - static grammar::LeftRG < SymbolType > convert(const grammar::RightRG < SymbolType > & grammar); + template < class TerminalSymbolType, class NonterminalSymbolType > + static grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > convert(const grammar::RightRG < TerminalSymbolType, NonterminalSymbolType > & grammar); }; -template < class SymbolType > -grammar::LeftRG < SymbolType > ToGrammarLeftRG::convert(const grammar::RightRG < SymbolType > & grammar) { +template < class TerminalSymbolType, class NonterminalSymbolType > +grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > ToGrammarLeftRG::convert(const grammar::RightRG < TerminalSymbolType, NonterminalSymbolType > & grammar) { // 1. - SymbolType s = common::createUnique( grammar.getInitialSymbol( ), grammar.getNonterminalAlphabet(), grammar.getTerminalAlphabet() ); + NonterminalSymbolType s = common::createUnique( grammar.getInitialSymbol( ), grammar.getNonterminalAlphabet(), grammar.getTerminalAlphabet() ); - grammar::LeftRG < SymbolType > lrg(s); + grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > lrg(s); for(const auto & nonterminalSymbol : grammar.getNonterminalAlphabet()) { lrg.addNonterminalSymbol( nonterminalSymbol ); @@ -47,31 +52,31 @@ grammar::LeftRG < SymbolType > ToGrammarLeftRG::convert(const grammar::RightRG < // 2. for( const auto & rule : grammar.getRules( ) ) { - const SymbolType& lhs = rule.first; + const NonterminalSymbolType& lhs = rule.first; for(const auto & ruleRHS : rule.second ) { - if( ruleRHS.template is<ext::pair<SymbolType, SymbolType>>( ) ) { - const ext::pair<SymbolType, SymbolType>& rhs = ruleRHS.template get<ext::pair<SymbolType, SymbolType>>(); + if( ruleRHS.template is<ext::pair<TerminalSymbolType, NonterminalSymbolType>>( ) ) { + const ext::pair<TerminalSymbolType, NonterminalSymbolType>& rhs = ruleRHS.template get<ext::pair<TerminalSymbolType, NonterminalSymbolType>>(); - SymbolType leftSide = rhs.second; - ext::pair<SymbolType, SymbolType> rightSide = ext::make_pair( lhs, rhs.first ); + NonterminalSymbolType leftSide = rhs.second; + ext::pair<NonterminalSymbolType, TerminalSymbolType> rightSide = ext::make_pair( lhs, rhs.first ); lrg.addRule( leftSide, std::move ( rightSide ) ); if( lhs == grammar.getInitialSymbol( ) ) { leftSide = rhs.second; - SymbolType rightSide2 = rhs.first; + TerminalSymbolType rightSide2 = rhs.first; lrg.addRule( leftSide, std::move ( rightSide2 ) ); } } else { - const SymbolType& rhs = ruleRHS.template get<SymbolType>(); + const TerminalSymbolType& rhs = ruleRHS.template get<TerminalSymbolType>(); - SymbolType leftSide = lrg.getInitialSymbol( ); - ext::pair<SymbolType, SymbolType> rightSide = ext::make_pair ( lhs, rhs ); + NonterminalSymbolType leftSide = lrg.getInitialSymbol( ); + ext::pair<NonterminalSymbolType, TerminalSymbolType> rightSide = ext::make_pair ( lhs, rhs ); lrg.addRule( leftSide, std::move ( rightSide ) ); if( lhs == grammar.getInitialSymbol( ) ) { leftSide = lrg.getInitialSymbol( ); - SymbolType rightSide2 = rhs; + TerminalSymbolType rightSide2 = rhs; lrg.addRule( leftSide, std::move ( rightSide2 ) ); } } diff --git a/alib2algo/src/grammar/convert/ToGrammarRightRG.h b/alib2algo/src/grammar/convert/ToGrammarRightRG.h index a0af3bdc5f..7d559d1ce5 100644 --- a/alib2algo/src/grammar/convert/ToGrammarRightRG.h +++ b/alib2algo/src/grammar/convert/ToGrammarRightRG.h @@ -24,19 +24,24 @@ class ToGrammarRightRG { public: /** * Performs conversion. - * @param grammar Left regular grammar to convert - * @return right regular grammar which is equivalent to source left regular grammar. + * + * \tparam TerminalSymbolType used for the terminal alphabet of the grammar. + * \tparam NonterminalSymbolType used for the nonterminal alphabet, and the initial symbol of the grammar. + * + * \param grammar Left regular grammar to convert + * + * \return right regular grammar which is equivalent to source left regular grammar. */ - template < class SymbolType > - static grammar::RightRG < SymbolType > convert(const grammar::LeftRG < SymbolType > & grammar); + template < class TerminalSymbolType, class NonterminalSymbolType > + static grammar::RightRG < TerminalSymbolType > convert(const grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > & grammar); }; -template < class SymbolType > -grammar::RightRG < SymbolType > ToGrammarRightRG::convert(const grammar::LeftRG < SymbolType > & grammar) { +template < class TerminalSymbolType, class NonterminalSymbolType > +grammar::RightRG < TerminalSymbolType, NonterminalSymbolType > ToGrammarRightRG::convert(const grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > & grammar) { // 1. - SymbolType s = common::createUnique( grammar.getInitialSymbol( ), grammar.getNonterminalAlphabet(), grammar.getTerminalAlphabet() ); + NonterminalSymbolType s = common::createUnique( grammar.getInitialSymbol( ), grammar.getNonterminalAlphabet(), grammar.getTerminalAlphabet() ); - grammar::RightRG < SymbolType > rrg( s ); + grammar::RightRG < TerminalSymbolType, NonterminalSymbolType > rrg( s ); for(const auto & nonterminalSymbol : grammar.getNonterminalAlphabet() ) { rrg.addNonterminalSymbol( nonterminalSymbol ); @@ -47,31 +52,31 @@ grammar::RightRG < SymbolType > ToGrammarRightRG::convert(const grammar::LeftRG // 2 for( const auto & rule : grammar.getRules( ) ) { - const SymbolType& lhs = rule.first; + const NonterminalSymbolType& lhs = rule.first; for(const auto & ruleRHS : rule.second ) { - if( ruleRHS.template is<ext::pair<SymbolType, SymbolType>>( ) ) { - const ext::pair<SymbolType, SymbolType>& rhs = ruleRHS.template get<ext::pair<SymbolType, SymbolType>>(); + if( ruleRHS.template is<ext::pair<NonterminalSymbolType, TerminalSymbolType>>( ) ) { + const ext::pair<NonterminalSymbolType, TerminalSymbolType>& rhs = ruleRHS.template get<ext::pair<NonterminalSymbolType, TerminalSymbolType>>(); - SymbolType leftSide = ( rhs.first ); - ext::pair<SymbolType, SymbolType> rightSide = ext::make_pair( rhs.second, lhs ); + NonterminalSymbolType leftSide = ( rhs.first ); + ext::pair<TerminalSymbolType, NonterminalSymbolType> rightSide = ext::make_pair( rhs.second, lhs ); rrg.addRule( leftSide, std::move ( rightSide ) ); if( lhs == grammar.getInitialSymbol( ) ) { leftSide = rhs.first; - SymbolType rightSide2 = rhs.second; + TerminalSymbolType rightSide2 = rhs.second; rrg.addRule( leftSide, rightSide2 ); } } else { - const SymbolType& rhs = ruleRHS.template get<SymbolType>(); + const TerminalSymbolType& rhs = ruleRHS.template get<TerminalSymbolType>(); - SymbolType leftSide = rrg.getInitialSymbol( ); - ext::pair<SymbolType, SymbolType> rightSide = ext::make_pair( rhs, lhs ); + NonterminalSymbolType leftSide = rrg.getInitialSymbol( ); + ext::pair<TerminalSymbolType, NonterminalSymbolType> rightSide = ext::make_pair( rhs, lhs ); rrg.addRule( leftSide, std::move ( rightSide ) ); if( lhs == grammar.getInitialSymbol( ) ) { leftSide = rrg.getInitialSymbol( ); - SymbolType rightSide2 = rhs; + terminalSymbolType rightSide2 = rhs; rrg.addRule( leftSide, rightSide2 ); } } diff --git a/alib2data/src/grammar/Regular/LeftRG.h b/alib2data/src/grammar/Regular/LeftRG.h index 6f6c59372d..0641dfeec1 100644 --- a/alib2data/src/grammar/Regular/LeftRG.h +++ b/alib2data/src/grammar/Regular/LeftRG.h @@ -65,14 +65,15 @@ class InitialSymbol; * * This definition has simplier handling of empty string generation and it is compatible with common definitions where the transformation from this definition to the common definition and backwards is straightforward. * - * \tparam SymbolType used for the terminal alphabet, the nonterminal alphabet, and the initial symbol of the grammar. + * \tparam TerminalSymbolType used for the terminal alphabet of the grammar. + * \tparam NonterminalSymbolType used for the nonterminal alphabet, and the initial symbol of the grammar. */ -template < class SymbolType = DefaultSymbolType > -class LeftRG final : public GrammarBase, public core::Components < LeftRG < SymbolType >, ext::set < SymbolType >, component::Set, std::tuple < TerminalAlphabet, NonterminalAlphabet >, SymbolType, component::Value, InitialSymbol > { +template < class TerminalSymbolType = DefaultSymbolType, class NonterminalSymbolType = DefaultSymbolType > +class LeftRG final : public GrammarBase, public core::Components < LeftRG < TerminalSymbolType, NonterminalSymbolType >, ext::set < TerminalSymbolType >, component::Set, TerminalAlphabet, ext::set < NonterminalSymbolType >, component::Set, NonterminalAlphabet, NonterminalSymbolType, component::Value, InitialSymbol > { /** * Rules as mapping from nonterminal symbol on the left hand side to set of either terminal symbols or doublets of terminal symbol and nonterminal symbol. */ - ext::map < SymbolType, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > > rules; + ext::map < NonterminalSymbolType, ext::set < ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > > > rules; /** * Boolean signaling whether grammar generates empty string or don't. @@ -85,7 +86,7 @@ public: * * \param initialSymbol the initial symbol of the grammar */ - explicit LeftRG ( SymbolType initialSymbol ); + explicit LeftRG ( NonterminalSymbolType initialSymbol ); /** * \brief Creates a new instance of Left regular grammar with a concrete nonterminal, terminal alphabet and initial symbol. @@ -94,7 +95,7 @@ public: * \param terminalSymbols the initial terminal alphabet * \param initialSymbol the initial symbol of the grammar */ - explicit LeftRG ( ext::set < SymbolType > nonTerminalSymbols, ext::set < SymbolType > terminalSymbols, SymbolType initialSymbol ); + explicit LeftRG ( ext::set < NonterminalSymbolType > nonTerminalSymbols, ext::set < TerminalSymbolType > terminalSymbols, NonterminalSymbolType initialSymbol ); /** * @copydoc grammar::GrammarBase::clone() @@ -116,7 +117,7 @@ public: * * \returns true if the rule was indeed added, false othervise */ - bool addRule ( SymbolType leftHandSide, ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > rightHandSide ); + bool addRule ( NonterminalSymbolType leftHandSide, ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > rightHandSide ); /** * \brief Add a new rule of a grammar. @@ -128,7 +129,7 @@ public: * * \returns true if the rule was indeed added, false othervise */ - bool addRule ( SymbolType leftHandSide, SymbolType rightHandSide ); + bool addRule ( NonterminalSymbolType leftHandSide, TerminalSymbolType rightHandSide ); /** * \brief Add a new rule of a grammar. @@ -140,7 +141,7 @@ public: * * \returns true if the rule was indeed added, false othervise */ - bool addRule ( SymbolType leftHandSide, ext::pair < SymbolType, SymbolType > rightHandSide ); + bool addRule ( NonterminalSymbolType leftHandSide, ext::pair < NonterminalSymbolType, TerminalSymbolType > rightHandSide ); /** * \brief Add new rules of a grammar. @@ -150,21 +151,21 @@ public: * \param leftHandSide the left hand side of the rule * \param rightHandSide a set of right hand sides of the rule */ - void addRules ( SymbolType leftHandSide, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > rightHandSide ); + void addRules ( NonterminalSymbolType leftHandSide, ext::set < ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > > rightHandSide ); /** * Get rules of the grammar. * * \returns rules of the grammar */ - const ext::map < SymbolType, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > > & getRules ( ) const &; + const ext::map < NonterminalSymbolType, ext::set < ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > > > & getRules ( ) const &; /** * Get rules of the grammar. * * \returns rules of the grammar */ - ext::map < SymbolType, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > > && getRules ( ) &&; + ext::map < NonterminalSymbolType, ext::set < ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > > > && getRules ( ) &&; /** * Remove a rule of a grammar in form of A -> Ba or A -> a, where A, B \in N and a \in T. @@ -174,7 +175,7 @@ public: * * \returns true if the rule was indeed removed, false othervise */ - bool removeRule ( const SymbolType & leftHandSide, const ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > & rightHandSide ); + bool removeRule ( const NonterminalSymbolType & leftHandSide, const ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > & rightHandSide ); /** * Remove a rule of a grammar in form of A -> a, where A \in N and a \in T. @@ -184,7 +185,7 @@ public: * * \returns true if the rule was indeed removed, false othervise */ - bool removeRule ( const SymbolType & leftHandSide, const SymbolType & rightHandSide ); + bool removeRule ( const NonterminalSymbolType & leftHandSide, const TerminalSymbolType & rightHandSide ); /** * Remove a rule of a grammar in form of A -> Ba, where A, B \in N and a \in T. @@ -194,14 +195,14 @@ public: * * \returns true if the rule was indeed removed, false othervise */ - bool removeRule ( const SymbolType & leftHandSide, const ext::pair < SymbolType, SymbolType > & rightHandSide ); + bool removeRule ( const NonterminalSymbolType & leftHandSide, const ext::pair < NonterminalSymbolType, TerminalSymbolType > & rightHandSide ); /** * Getter of initial symbol. * * \returns the initial symbol of the grammar */ - const SymbolType & getInitialSymbol ( ) const & { + const NonterminalSymbolType & getInitialSymbol ( ) const & { return this->template accessComponent < InitialSymbol > ( ).get ( ); } @@ -210,7 +211,7 @@ public: * * \returns the initial symbol of the grammar */ - SymbolType && getInitialSymbol ( ) && { + NonterminalSymbolType && getInitialSymbol ( ) && { return std::move ( this->template accessComponent < InitialSymbol > ( ).get ( ) ); } @@ -221,7 +222,7 @@ public: * * \returns true if the initial symbol was indeed changed */ - bool setInitialSymbol ( SymbolType symbol ) { + bool setInitialSymbol ( NonterminalSymbolType symbol ) { return this->template accessComponent < InitialSymbol > ( ).set ( std::move ( symbol ) ); } @@ -230,7 +231,7 @@ public: * * \returns the nonterminal alphabet of the grammar */ - const ext::set < SymbolType > & getNonterminalAlphabet ( ) const & { + const ext::set < NonterminalSymbolType > & getNonterminalAlphabet ( ) const & { return this->template accessComponent < NonterminalAlphabet > ( ).get ( ); } @@ -239,7 +240,7 @@ public: * * \returns the nonterminal alphabet of the grammar */ - ext::set < SymbolType > && getNonterminalAlphabet ( ) && { + ext::set < NonterminalSymbolType > && getNonterminalAlphabet ( ) && { return std::move ( this->template accessComponent < NonterminalAlphabet > ( ).get ( ) ); } @@ -250,7 +251,7 @@ public: * * \returns true if the symbol was indeed added */ - bool addNonterminalSymbol ( SymbolType symbol ) { + bool addNonterminalSymbol ( NonterminalSymbolType symbol ) { return this->template accessComponent < NonterminalAlphabet > ( ).add ( std::move ( symbol ) ); } @@ -259,7 +260,7 @@ public: * * \param symbols completely new nonterminal alphabet */ - void setNonterminalAlphabet ( ext::set < SymbolType > symbols ) { + void setNonterminalAlphabet ( ext::set < NonterminalSymbolType > symbols ) { this->template accessComponent < NonterminalAlphabet > ( ).set ( std::move ( symbols ) ); } @@ -268,7 +269,7 @@ public: * * \returns the terminal alphabet of the grammar */ - const ext::set < SymbolType > & getTerminalAlphabet ( ) const & { + const ext::set < TerminalSymbolType > & getTerminalAlphabet ( ) const & { return this->template accessComponent < TerminalAlphabet > ( ).get ( ); } @@ -277,7 +278,7 @@ public: * * \returns the terminal alphabet of the grammar */ - ext::set < SymbolType > && getTerminalAlphabet ( ) && { + ext::set < TerminalSymbolType > && getTerminalAlphabet ( ) && { return std::move ( this->template accessComponent < TerminalAlphabet > ( ).get ( ) ); } @@ -288,7 +289,7 @@ public: * * \returns true if the symbol was indeed added */ - bool addTerminalSymbol ( SymbolType symbol ) { + bool addTerminalSymbol ( TerminalSymbolType symbol ) { return this->template accessComponent < TerminalAlphabet > ( ).add ( std::move ( symbol ) ); } @@ -297,7 +298,7 @@ public: * * \param symbol completely new nontemrinal alphabet */ - void setTerminalAlphabet ( ext::set < SymbolType > symbols ) { + void setTerminalAlphabet ( ext::set < TerminalSymbolType > symbols ) { this->template accessComponent < TerminalAlphabet > ( ).set ( std::move ( symbols ) ); } @@ -349,36 +350,36 @@ public: virtual object::ObjectBase * inc ( ) && override; }; -template < class SymbolType > -LeftRG < SymbolType >::LeftRG ( SymbolType initialSymbol ) : LeftRG ( ext::set < SymbolType > { initialSymbol }, ext::set < SymbolType > ( ), initialSymbol ) { +template < class TerminalSymbolType, class NonterminalSymbolType > +LeftRG < TerminalSymbolType, NonterminalSymbolType >::LeftRG ( NonterminalSymbolType initialSymbol ) : LeftRG ( ext::set < NonterminalSymbolType > { initialSymbol }, ext::set < TerminalSymbolType > ( ), initialSymbol ) { } -template < class SymbolType > -LeftRG < SymbolType >::LeftRG ( ext::set < SymbolType > nonterminalAlphabet, ext::set < SymbolType > terminalAlphabet, SymbolType initialSymbol ) : core::Components < LeftRG, ext::set < SymbolType >, component::Set, std::tuple < TerminalAlphabet, NonterminalAlphabet >, SymbolType, component::Value, InitialSymbol > ( std::move ( terminalAlphabet), std::move ( nonterminalAlphabet ), std::move ( initialSymbol ) ), generatesEpsilon ( false ) { +template < class TerminalSymbolType, class NonterminalSymbolType > +LeftRG < TerminalSymbolType, NonterminalSymbolType >::LeftRG ( ext::set < NonterminalSymbolType > nonterminalAlphabet, ext::set < TerminalSymbolType > terminalAlphabet, NonterminalSymbolType initialSymbol ) : core::Components < LeftRG, ext::set < TerminalSymbolType >, component::Set, TerminalAlphabet, ext::set < NonterminalSymbolType >, component::Set, NonterminalAlphabet, NonterminalSymbolType, component::Value, InitialSymbol > ( std::move ( terminalAlphabet), std::move ( nonterminalAlphabet ), std::move ( initialSymbol ) ), generatesEpsilon ( false ) { } -template < class SymbolType > -GrammarBase * LeftRG < SymbolType >::clone ( ) const & { +template < class TerminalSymbolType, class NonterminalSymbolType > +GrammarBase * LeftRG < TerminalSymbolType, NonterminalSymbolType >::clone ( ) const & { return new LeftRG ( * this ); } -template < class SymbolType > -GrammarBase * LeftRG < SymbolType >::clone ( ) && { +template < class TerminalSymbolType, class NonterminalSymbolType > +GrammarBase * LeftRG < TerminalSymbolType, NonterminalSymbolType >::clone ( ) && { return new LeftRG ( std::move ( * this ) ); } -template < class SymbolType > -bool LeftRG < SymbolType >::addRule ( SymbolType leftHandSide, ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > rightHandSide ) { +template < class TerminalSymbolType, class NonterminalSymbolType > +bool LeftRG < TerminalSymbolType, NonterminalSymbolType >::addRule ( NonterminalSymbolType leftHandSide, ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > rightHandSide ) { if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) ) throw GrammarException ( "Rule must rewrite nonterminal symbol" ); - if ( rightHandSide.template is < SymbolType > ( ) ) { - const SymbolType & rhs = rightHandSide.template get < SymbolType > ( ); + if ( rightHandSide.template is < TerminalSymbolType > ( ) ) { + const TerminalSymbolType & rhs = rightHandSide.template get < TerminalSymbolType > ( ); if ( !getTerminalAlphabet ( ).count ( rhs ) ) throw GrammarException ( "Rule must rewrite to terminal symbol" ); } else { - const ext::pair < SymbolType, SymbolType > & rhs = rightHandSide.template get < ext::pair < SymbolType, SymbolType > > ( ); + const ext::pair < NonterminalSymbolType, TerminalSymbolType > & rhs = rightHandSide.template get < ext::pair < NonterminalSymbolType, TerminalSymbolType > > ( ); if ( !getNonterminalAlphabet ( ).count ( rhs.first ) || !getTerminalAlphabet ( ).count ( rhs.second ) ) throw GrammarException ( "Rule must rewrite to terminal symbol followed by nonterminal symbol" ); @@ -387,20 +388,20 @@ bool LeftRG < SymbolType >::addRule ( SymbolType leftHandSide, ext::variant < Sy return rules [ std::move ( leftHandSide ) ].insert ( std::move ( rightHandSide ) ).second; } -template < class SymbolType > -void LeftRG < SymbolType >::addRules ( SymbolType leftHandSide, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > rightHandSide ) { +template < class TerminalSymbolType, class NonterminalSymbolType > +void LeftRG < TerminalSymbolType, NonterminalSymbolType >::addRules ( NonterminalSymbolType leftHandSide, ext::set < ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > > rightHandSide ) { if ( !getNonterminalAlphabet ( ).count ( leftHandSide ) ) throw GrammarException ( "Rule must rewrite nonterminal symbol" ); - for ( const ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > & element : rightHandSide ) { - if ( element.template is < SymbolType > ( ) ) { - const SymbolType & rhs = element.template get < SymbolType > ( ); + for ( const ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > & element : rightHandSide ) { + if ( element.template is < NonterminalSymbolType > ( ) ) { + const TerminalSymbolType & rhs = element.template get < TerminalSymbolType > ( ); if ( ! getTerminalAlphabet ( ).count ( rhs ) ) throw GrammarException ( "Rule must rewrite to terminal symbol" ); } else { - const ext::pair < SymbolType, SymbolType > & rhs = element.template get < ext::pair < SymbolType, SymbolType > > ( ); + const ext::pair < NonterminalSymbolType, TerminalSymbolType > & rhs = element.template get < ext::pair < NonterminalSymbolType, TerminalSymbolType > > ( ); if ( ! getNonterminalAlphabet ( ).count ( rhs.first ) || ! getTerminalAlphabet ( ).count ( rhs.second ) ) throw GrammarException ( "Rule must rewrite to terminal symbol followed by nonterminal symbol" ); @@ -410,61 +411,61 @@ void LeftRG < SymbolType >::addRules ( SymbolType leftHandSide, ext::set < ext:: rules [ std::move ( leftHandSide ) ].insert ( ext::make_mover ( rightHandSide ).begin ( ), ext::make_mover ( rightHandSide ).end ( ) ); } -template < class SymbolType > -bool LeftRG < SymbolType >::addRule ( SymbolType leftHandSide, SymbolType rightHandSide ) { - ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > rhs ( std::move ( rightHandSide ) ); +template < class TerminalSymbolType, class NonterminalSymbolType > +bool LeftRG < TerminalSymbolType, NonterminalSymbolType >::addRule ( NonterminalSymbolType leftHandSide, TerminalSymbolType rightHandSide ) { + ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > rhs ( std::move ( rightHandSide ) ); return addRule ( std::move ( leftHandSide ), std::move ( rhs ) ); } -template < class SymbolType > -bool LeftRG < SymbolType >::addRule ( SymbolType leftHandSide, ext::pair < SymbolType, SymbolType > rightHandSide ) { - ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > rhs ( std::move ( rightHandSide ) ); +template < class TerminalSymbolType, class NonterminalSymbolType > +bool LeftRG < TerminalSymbolType, NonterminalSymbolType >::addRule ( NonterminalSymbolType leftHandSide, ext::pair < NonterminalSymbolType, TerminalSymbolType > rightHandSide ) { + ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > rhs ( std::move ( rightHandSide ) ); return addRule ( std::move ( leftHandSide ), std::move ( rhs ) ); } -template < class SymbolType > -const ext::map < SymbolType, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > > & LeftRG < SymbolType >::getRules ( ) const & { +template < class TerminalSymbolType, class NonterminalSymbolType > +const ext::map < NonterminalSymbolType, ext::set < ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > > > & LeftRG < TerminalSymbolType, NonterminalSymbolType >::getRules ( ) const & { return rules; } -template < class SymbolType > -ext::map < SymbolType, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > > && LeftRG < SymbolType >::getRules ( ) && { +template < class TerminalSymbolType, class NonterminalSymbolType > +ext::map < NonterminalSymbolType, ext::set < ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > > > && LeftRG < TerminalSymbolType, NonterminalSymbolType >::getRules ( ) && { return std::move ( rules ); } -template < class SymbolType > -bool LeftRG < SymbolType >::removeRule ( const SymbolType & leftHandSide, const ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > & rightHandSide ) { +template < class TerminalSymbolType, class NonterminalSymbolType > +bool LeftRG < TerminalSymbolType, NonterminalSymbolType >::removeRule ( const NonterminalSymbolType & leftHandSide, const ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > & rightHandSide ) { return rules[leftHandSide].erase ( rightHandSide ); } -template < class SymbolType > -bool LeftRG < SymbolType >::removeRule ( const SymbolType & leftHandSide, const SymbolType & rightHandSide ) { - ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > rhs ( rightHandSide ); +template < class TerminalSymbolType, class NonterminalSymbolType > +bool LeftRG < TerminalSymbolType, NonterminalSymbolType >::removeRule ( const NonterminalSymbolType & leftHandSide, const TerminalSymbolType & rightHandSide ) { + ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > rhs ( rightHandSide ); return removeRule ( leftHandSide, rhs ); } -template < class SymbolType > -bool LeftRG < SymbolType >::removeRule ( const SymbolType & leftHandSide, const ext::pair < SymbolType, SymbolType > & rightHandSide ) { - ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > rhs ( rightHandSide ); +template < class TerminalSymbolType, class NonterminalSymbolType > +bool LeftRG < TerminalSymbolType, NonterminalSymbolType >::removeRule ( const NonterminalSymbolType & leftHandSide, const ext::pair < NonterminalSymbolType, TerminalSymbolType > & rightHandSide ) { + ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > rhs ( rightHandSide ); return removeRule ( leftHandSide, rhs ); } -template < class SymbolType > -void LeftRG < SymbolType >::setGeneratesEpsilon ( bool genEps ) { +template < class TerminalSymbolType, class NonterminalSymbolType > +void LeftRG < TerminalSymbolType, NonterminalSymbolType >::setGeneratesEpsilon ( bool genEps ) { generatesEpsilon = genEps; } -template < class SymbolType > -bool LeftRG < SymbolType >::getGeneratesEpsilon ( ) const { +template < class TerminalSymbolType, class NonterminalSymbolType > +bool LeftRG < TerminalSymbolType, NonterminalSymbolType >::getGeneratesEpsilon ( ) const { return generatesEpsilon; } -template < class SymbolType > -int LeftRG < SymbolType >::compare ( const LeftRG & other ) const { +template < class TerminalSymbolType, class NonterminalSymbolType > +int LeftRG < TerminalSymbolType, NonterminalSymbolType >::compare ( const LeftRG & other ) const { auto first = ext::tie ( getTerminalAlphabet ( ), getNonterminalAlphabet ( ), getInitialSymbol ( ), rules ); auto second = ext::tie ( other.getTerminalAlphabet ( ), other.getNonterminalAlphabet ( ), other.getInitialSymbol ( ), other.rules ); @@ -473,8 +474,8 @@ int LeftRG < SymbolType >::compare ( const LeftRG & other ) const { return comp ( first, second ); } -template < class SymbolType > -void LeftRG < SymbolType >::operator >>( std::ostream & out ) const { +template < class TerminalSymbolType, class NonterminalSymbolType > +void LeftRG < TerminalSymbolType, NonterminalSymbolType >::operator >>( std::ostream & out ) const { out << "(LeftRG " << "nonterminalAlphabet = " << getNonterminalAlphabet ( ) << "terminalAlphabet = " << getTerminalAlphabet ( ) @@ -483,15 +484,15 @@ void LeftRG < SymbolType >::operator >>( std::ostream & out ) const { << "generatesEpsilon = " << generatesEpsilon << ")"; } -template < class SymbolType > -LeftRG < SymbolType >::operator std::string ( ) const { +template < class TerminalSymbolType, class NonterminalSymbolType > +LeftRG < TerminalSymbolType, NonterminalSymbolType >::operator std::string ( ) const { std::stringstream ss; ss << * this; return ss.str ( ); } -template < class SymbolType > -object::ObjectBase* LeftRG < SymbolType >::inc() && { +template < class TerminalSymbolType, class NonterminalSymbolType > +object::ObjectBase* LeftRG < TerminalSymbolType, NonterminalSymbolType >::inc() && { return new object::UniqueObject ( object::Object ( std::move ( * this ) ), primitive::Integer ( 0 ) ); } @@ -502,10 +503,11 @@ namespace core { /** * Helper class specifying constraints for the grammar's internal terminal alphabet component. * - * \tparam SymbolType used for the terminal alphabet of the grammar. + * \tparam TerminalSymbolType used for the terminal alphabet of the grammar. + * \tparam NonterminalSymbolType used for the nonterminal alphabet, and the initial symbol of the grammar. */ -template < class SymbolType > -class SetConstraint< grammar::LeftRG < SymbolType >, SymbolType, grammar::TerminalAlphabet > { +template < class TerminalSymbolType, class NonterminalSymbolType > +class SetConstraint< grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType >, TerminalSymbolType, grammar::TerminalAlphabet > { public: /** * Returns true if the terminal symbol is still used in some rule of the grammar. @@ -515,10 +517,10 @@ public: * * \returns true if the symbol is used, false othervise */ - static bool used ( const grammar::LeftRG < SymbolType > & grammar, const SymbolType & symbol ) { - for ( const std::pair < const SymbolType, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > > & rule : grammar.getRules ( ) ) - for ( const ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > & rhs : rule.second ) - if ( ( rhs.template is < SymbolType > ( ) && ( rhs.template get < SymbolType > ( ) == symbol ) ) || ( rhs.template get < ext::pair < SymbolType, SymbolType > > ( ).second == symbol ) ) + static bool used ( const grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > & grammar, const TerminalSymbolType & symbol ) { + for ( const std::pair < const NonterminalSymbolType, ext::set < ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > > > & rule : grammar.getRules ( ) ) + for ( const ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > & rhs : rule.second ) + if ( ( rhs.template is < TerminalSymbolType > ( ) && ( rhs.template get < TerminalSymbolType > ( ) == symbol ) ) || ( rhs.template get < ext::pair < NonterminalSymbolType, TerminalSymbolType > > ( ).second == symbol ) ) return true; return false; @@ -532,7 +534,7 @@ public: * * \returns true */ - static bool available ( const grammar::LeftRG < SymbolType > &, const SymbolType & ) { + static bool available ( const grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > &, const TerminalSymbolType & ) { return true; } @@ -544,7 +546,7 @@ public: * * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ - static void valid ( const grammar::LeftRG < SymbolType > & grammar, const SymbolType & symbol ) { + static void valid ( const grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > & grammar, const TerminalSymbolType & symbol ) { if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); } @@ -553,10 +555,11 @@ public: /** * Helper class specifying constraints for the grammar's internal nonterminal alphabet component. * - * \tparam SymbolType used for the nonterminal alphabet of the grammar. + * \tparam TerminalSymbolType used for the terminal alphabet of the grammar. + * \tparam NonterminalSymbolType used for the nonterminal alphabet, and the initial symbol of the grammar. */ -template < class SymbolType > -class SetConstraint< grammar::LeftRG < SymbolType >, SymbolType, grammar::NonterminalAlphabet > { +template < class TerminalSymbolType, class NonterminalSymbolType > +class SetConstraint< grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType >, NonterminalSymbolType, grammar::NonterminalAlphabet > { public: /** * Returns true if the nonterminal symbol is still used in some rule of the grammar or if it is the initial symbol of the grammar. @@ -566,13 +569,13 @@ public: * * \returns true if the symbol is used, false othervise */ - static bool used ( const grammar::LeftRG < SymbolType > & grammar, const SymbolType & symbol ) { - for ( const std::pair < const SymbolType, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > > & rule : grammar.getRules ( ) ) { + static bool used ( const grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > & grammar, const NonterminalSymbolType & symbol ) { + for ( const std::pair < const NonterminalSymbolType, ext::set < ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > > > & rule : grammar.getRules ( ) ) { if ( rule.first == symbol ) return true; - for ( const ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > & rhs : rule.second ) - if ( rhs.template get < ext::pair < SymbolType, SymbolType > > ( ).first == symbol ) + for ( const ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > & rhs : rule.second ) + if ( rhs.template get < ext::pair < NonterminalSymbolType, TerminalSymbolType > > ( ).first == symbol ) return true; } @@ -591,7 +594,7 @@ public: * * \returns true */ - static bool available ( const grammar::LeftRG < SymbolType > &, const SymbolType & ) { + static bool available ( const grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > &, const NonterminalSymbolType & ) { return true; } @@ -603,7 +606,7 @@ public: * * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ - static void valid ( const grammar::LeftRG < SymbolType > & grammar, const SymbolType & symbol ) { + static void valid ( const grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > & grammar, const NonterminalSymbolType & symbol ) { if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); } @@ -612,10 +615,11 @@ public: /** * Helper class specifying constraints for the grammar's internal initial symbol element. * - * \tparam SymbolType used for the initial symbol of the grammar. + * \tparam TerminalSymbolType used for the terminal alphabet of the grammar. + * \tparam NonterminalSymbolType used for the nonterminal alphabet, and the initial symbol of the grammar. */ -template < class SymbolType > -class ElementConstraint< grammar::LeftRG < SymbolType >, SymbolType, grammar::InitialSymbol > { +template < class TerminalSymbolType, class NonterminalSymbolType > +class ElementConstraint< grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType >, NonterminalSymbolType, grammar::InitialSymbol > { public: /** * Returns true if the symbol requested to be initial is available in nonterminal alphabet. @@ -625,7 +629,7 @@ public: * * \returns true if the tested symbol is in nonterminal alphabet */ - static bool available ( const grammar::LeftRG < SymbolType > & grammar, const SymbolType & symbol ) { + static bool available ( const grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > & grammar, const NonterminalSymbolType & symbol ) { return grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); } @@ -635,7 +639,7 @@ public: * \param grammar the tested grammar * \param symbol the tested symbol */ - static void valid ( const grammar::LeftRG < SymbolType > &, const SymbolType & ) { + static void valid ( const grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > &, const NonterminalSymbolType & ) { } }; @@ -644,19 +648,19 @@ public: * * \returns new instance of the grammar with default template parameters or unmodified instance if the template parameters were already default ones */ -template < class SymbolType > -struct normalize < grammar::LeftRG < SymbolType > > { - static grammar::LeftRG < > eval ( grammar::LeftRG < SymbolType > && value ) { +template < class TerminalSymbolType, class NonterminalSymbolType > +struct normalize < grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > > { + static grammar::LeftRG < > eval ( grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > && value ) { ext::set < DefaultSymbolType > nonterminals = alphabet::SymbolNormalize::normalizeAlphabet ( std::move ( value ).getNonterminalAlphabet ( ) ); ext::set < DefaultSymbolType > terminals = alphabet::SymbolNormalize::normalizeAlphabet ( std::move ( value ).getTerminalAlphabet ( ) ); DefaultSymbolType initialSymbol = alphabet::SymbolNormalize::normalizeSymbol ( std::move ( value ).getInitialSymbol ( ) ); grammar::LeftRG < > res ( std::move ( nonterminals ), std::move ( terminals ), std::move ( initialSymbol ) ); - for ( std::pair < SymbolType, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > > && rule : ext::make_mover ( std::move ( value ).getRules ( ) ) ) { + for ( std::pair < NonterminalSymbolType, ext::set < ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > > > && rule : ext::make_mover ( std::move ( value ).getRules ( ) ) ) { ext::set < ext::variant < DefaultSymbolType, ext::pair < DefaultSymbolType, DefaultSymbolType > > > rhs; - for ( ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > && target : ext::make_mover ( rule.second ) ) + for ( ext::variant < TerminalSymbolType, ext::pair < NonterminalSymbolType, TerminalSymbolType > > && target : ext::make_mover ( rule.second ) ) rhs.insert ( grammar::GrammarNormalize::normalizeRHS ( std::move ( target ) ) ); DefaultSymbolType lhs = alphabet::SymbolNormalize::normalizeSymbol ( std::move ( rule.first ) ); diff --git a/alib2data/src/grammar/Regular/RightRG.h b/alib2data/src/grammar/Regular/RightRG.h index 15671dac6a..d61cc94d09 100644 --- a/alib2data/src/grammar/Regular/RightRG.h +++ b/alib2data/src/grammar/Regular/RightRG.h @@ -65,7 +65,8 @@ class InitialSymbol; * * This definition has simplier handling of empty string generation and it is compatible with common definitions where the transformation from this definition to the common definition and backwards is straightforward. * - * \tparam SymbolType used for the terminal alphabet, the nonterminal alphabet, and the initial symbol of the grammar. + * \tparam TerminalSymbolType used for the terminal alphabet of the grammar. + * \tparam NonterminalSymbolType used for the nonterminal alphabet, and the initial symbol of the grammar. */ template < class TerminalSymbolType = DefaultSymbolType, class NonterminalSymbolType = DefaultSymbolType > class RightRG final : public GrammarBase, public core::Components < RightRG < TerminalSymbolType, NonterminalSymbolType >, ext::set < TerminalSymbolType >, component::Set, TerminalAlphabet, ext::set < NonterminalSymbolType >, component::Set, NonterminalAlphabet, NonterminalSymbolType, component::Value, InitialSymbol > { @@ -501,7 +502,8 @@ namespace core { /** * Helper class specifying constraints for the grammar's internal terminal alphabet component. * - * \tparam SymbolType used for the terminal alphabet of the grammar. + * \tparam TerminalSymbolType used for the terminal alphabet of the grammar. + * \tparam NonterminalSymbolType used for the nonterminal alphabet, and the initial symbol of the grammar. */ template < class TerminalSymbolType, class NonterminalSymbolType > class SetConstraint< grammar::RightRG < TerminalSymbolType, NonterminalSymbolType >, TerminalSymbolType, grammar::TerminalAlphabet > { @@ -552,7 +554,8 @@ public: /** * Helper class specifying constraints for the grammar's internal nonterminal alphabet component. * - * \tparam SymbolType used for the nonterminal alphabet of the grammar. + * \tparam TerminalSymbolType used for the terminal alphabet of the grammar. + * \tparam NonterminalSymbolType used for the nonterminal alphabet, and the initial symbol of the grammar. */ template < class TerminalSymbolType, class NonterminalSymbolType > class SetConstraint< grammar::RightRG < TerminalSymbolType, NonterminalSymbolType >, NonterminalSymbolType, grammar::NonterminalAlphabet > { @@ -611,7 +614,8 @@ public: /** * Helper class specifying constraints for the grammar's internal initial symbol element. * - * \tparam SymbolType used for the initial symbol of the grammar. + * \tparam TerminalSymbolType used for the terminal alphabet of the grammar. + * \tparam NonterminalSymbolType used for the nonterminal alphabet, and the initial symbol of the grammar. */ template < class TerminalSymbolType, class NonterminalSymbolType > class ElementConstraint< grammar::RightRG < TerminalSymbolType, NonterminalSymbolType >, NonterminalSymbolType, grammar::InitialSymbol > { -- GitLab