From 1f3c7245705ab9b0a2df7360a09c666227659f6f Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Mon, 1 Aug 2016 12:59:35 +0200 Subject: [PATCH] ugrade Reg. and CS grammars to use components2 --- .../src/grammar/ContextSensitive/CSG.cpp | 94 +------------------ alib2data/src/grammar/ContextSensitive/CSG.h | 90 +++++++++++++++++- .../NonContractingGrammar.cpp | 81 +--------------- .../ContextSensitive/NonContractingGrammar.h | 77 ++++++++++++++- alib2data/src/grammar/Regular/LeftLG.cpp | 91 +----------------- alib2data/src/grammar/Regular/LeftLG.h | 87 ++++++++++++++++- alib2data/src/grammar/Regular/LeftRG.cpp | 76 +-------------- alib2data/src/grammar/Regular/LeftRG.h | 72 +++++++++++++- alib2data/src/grammar/Regular/RightLG.cpp | 91 +----------------- alib2data/src/grammar/Regular/RightLG.h | 87 ++++++++++++++++- alib2data/src/grammar/Regular/RightRG.cpp | 76 +-------------- alib2data/src/grammar/Regular/RightRG.h | 72 +++++++++++++- 12 files changed, 479 insertions(+), 515 deletions(-) diff --git a/alib2data/src/grammar/ContextSensitive/CSG.cpp b/alib2data/src/grammar/ContextSensitive/CSG.cpp index 210b0633b7..6850e6633d 100644 --- a/alib2data/src/grammar/ContextSensitive/CSG.cpp +++ b/alib2data/src/grammar/ContextSensitive/CSG.cpp @@ -6,7 +6,6 @@ */ #include "CSG.h" -#include "../GrammarException.h" #include <algorithm> #include <sstream> @@ -24,7 +23,7 @@ namespace grammar { CSG::CSG ( alphabet::Symbol initialSymbol ) : CSG ( std::set < alphabet::Symbol > { initialSymbol }, std::set < alphabet::Symbol > ( ), initialSymbol ) { } -CSG::CSG ( std::set < alphabet::Symbol > nonterminalAlphabet, std::set < alphabet::Symbol > terminalAlphabet, alphabet::Symbol initialSymbol ) : std::Components < CSG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ), generatesEpsilon ( false ) { +CSG::CSG ( std::set < alphabet::Symbol > nonterminalAlphabet, std::set < alphabet::Symbol > terminalAlphabet, alphabet::Symbol initialSymbol ) : std::Components2 < CSG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ), generatesEpsilon ( false ) { } GrammarBase * CSG::clone ( ) const { @@ -163,97 +162,6 @@ void CSG::composeRules ( std::deque < sax::Token > & out ) const { } /* namespace grammar */ -namespace std { - -template < > -bool grammar::CSG::Component < grammar::CSG, alphabet::Symbol, grammar::TerminalAlphabet >::used ( const alphabet::Symbol & symbol ) const { - const grammar::CSG * grammar = static_cast < const grammar::CSG * > ( this ); - - for ( const std::pair < const std::tuple < std::vector < alphabet::Symbol >, alphabet::Symbol, std::vector < alphabet::Symbol > >, std::set < std::vector < alphabet::Symbol > > > & rule : grammar->getRules ( ) ) { - for ( const alphabet::Symbol & lCont : std::get < 0 > ( rule.first ) ) - if ( lCont == symbol ) - return false; - - for ( const alphabet::Symbol & rCont : std::get < 2 > ( rule.first ) ) - if ( rCont == symbol ) - return false; - - for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) - if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) - return false; - - } - - return false; -} - -template < > -bool grammar::CSG::Component < grammar::CSG, alphabet::Symbol, grammar::TerminalAlphabet >::available ( const alphabet::Symbol & ) const { - return true; -} - -template < > -void grammar::CSG::Component < grammar::CSG, alphabet::Symbol, grammar::TerminalAlphabet >::valid ( const alphabet::Symbol & symbol ) const { - const grammar::CSG * grammar = static_cast < const grammar::CSG * > ( this ); - - if ( grammar->accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) - throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); -} - -template < > -bool grammar::CSG::Component < grammar::CSG, alphabet::Symbol, grammar::NonterminalAlphabet >::used ( const alphabet::Symbol & symbol ) const { - const grammar::CSG * grammar = static_cast < const grammar::CSG * > ( this ); - - for ( const std::pair < const std::tuple < std::vector < alphabet::Symbol >, alphabet::Symbol, std::vector < alphabet::Symbol > >, std::set < std::vector < alphabet::Symbol > > > & rule : grammar->getRules ( ) ) { - for ( const alphabet::Symbol & lCont : std::get < 0 > ( rule.first ) ) - if ( lCont == symbol ) - return true; - - if ( std::get < 1 > ( rule.first ) == symbol ) - return true; - - for ( const alphabet::Symbol & rCont : std::get < 2 > ( rule.first ) ) - if ( rCont == symbol ) - return true; - - for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) - if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) - return true; - - } - - if ( grammar->accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) - return true; - - return false; -} - -template < > -bool grammar::CSG::Component < grammar::CSG, alphabet::Symbol, grammar::NonterminalAlphabet >::available ( const alphabet::Symbol & ) const { - return true; -} - -template < > -void grammar::CSG::Component < grammar::CSG, alphabet::Symbol, grammar::NonterminalAlphabet >::valid ( const alphabet::Symbol & symbol ) const { - const grammar::CSG * grammar = static_cast < const grammar::CSG * > ( this ); - - if ( grammar->accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) - throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); -} - -template < > -bool grammar::CSG::Element < grammar::CSG, alphabet::Symbol, grammar::InitialSymbol >::available ( const alphabet::Symbol & symbol ) const { - const grammar::CSG * grammar = static_cast < const grammar::CSG * > ( this ); - - return grammar->accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); -} - -template < > -void grammar::CSG::Element < grammar::CSG, alphabet::Symbol, grammar::InitialSymbol >::valid ( const alphabet::Symbol & ) const { -} - -} /* namespace std */ - namespace alib { auto CSGParserRegister = xmlApi < grammar::Grammar >::ParserRegister < grammar::CSG > ( ); diff --git a/alib2data/src/grammar/ContextSensitive/CSG.h b/alib2data/src/grammar/ContextSensitive/CSG.h index d2c69a3169..2d99fd2b29 100644 --- a/alib2data/src/grammar/ContextSensitive/CSG.h +++ b/alib2data/src/grammar/ContextSensitive/CSG.h @@ -8,10 +8,11 @@ #ifndef CSG_H_ #define CSG_H_ +#include "../GrammarException.h" #include "../GrammarBase.h" #include <map> #include <vector> -#include <core/components.hpp> +#include <core/components2.hpp> #include "../../alphabet/Symbol.h" namespace grammar { @@ -23,7 +24,7 @@ class TerminalAlphabet; class NonterminalAlphabet; class InitialSymbol; -class CSG : public GrammarBase, public std::Components < CSG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { +class CSG : public GrammarBase, public std::Components2 < CSG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { std::map < std::tuple < std::vector < alphabet::Symbol >, alphabet::Symbol, std::vector < alphabet::Symbol > >, std::set < std::vector < alphabet::Symbol > > > rules; bool generatesEpsilon; @@ -104,4 +105,89 @@ public: } /* namespace grammar */ +namespace std { + +template < > +class ComponentConstraint2< grammar::CSG, alphabet::Symbol, grammar::TerminalAlphabet > { +public: + static bool used ( const grammar::CSG & grammar, const alphabet::Symbol & symbol ) { + for ( const std::pair < const std::tuple < std::vector < alphabet::Symbol >, alphabet::Symbol, std::vector < alphabet::Symbol > >, std::set < std::vector < alphabet::Symbol > > > & rule : grammar.getRules ( ) ) { + for ( const alphabet::Symbol & lCont : std::get < 0 > ( rule.first ) ) + if ( lCont == symbol ) + return false; + + for ( const alphabet::Symbol & rCont : std::get < 2 > ( rule.first ) ) + if ( rCont == symbol ) + return false; + + for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) + if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) + return false; + + } + + return false; + } + + static bool available ( const grammar::CSG &, const alphabet::Symbol & ) { + return true; + } + + static void valid ( const grammar::CSG & grammar, const alphabet::Symbol & symbol ) { + if ( grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); + } +}; + +template < > +class ComponentConstraint2< grammar::CSG, alphabet::Symbol, grammar::NonterminalAlphabet > { +public: + static bool used ( const grammar::CSG & grammar, const alphabet::Symbol & symbol ) { + for ( const std::pair < const std::tuple < std::vector < alphabet::Symbol >, alphabet::Symbol, std::vector < alphabet::Symbol > >, std::set < std::vector < alphabet::Symbol > > > & rule : grammar.getRules ( ) ) { + for ( const alphabet::Symbol & lCont : std::get < 0 > ( rule.first ) ) + if ( lCont == symbol ) + return true; + + if ( std::get < 1 > ( rule.first ) == symbol ) + return true; + + for ( const alphabet::Symbol & rCont : std::get < 2 > ( rule.first ) ) + if ( rCont == symbol ) + return true; + + for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) + if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) + return true; + + } + + if ( grammar.accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) + return true; + + return false; + } + + static bool available ( const grammar::CSG &, const alphabet::Symbol & ) { + return true; + } + + static void valid ( const grammar::CSG & grammar, const alphabet::Symbol & symbol ) { + if ( grammar.accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); + } +}; + +template < > +class ElementConstraint2< grammar::CSG, alphabet::Symbol, grammar::InitialSymbol > { +public: + static bool available ( const grammar::CSG & grammar, const alphabet::Symbol & symbol ) { + return grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); + } + + static void valid ( const grammar::CSG &, const alphabet::Symbol & ) { + } +}; + +} /* namespace std */ + #endif /* CSG_H_ */ diff --git a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp index 1634953fdd..657814efeb 100644 --- a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp +++ b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp @@ -6,7 +6,6 @@ */ #include "NonContractingGrammar.h" -#include "../GrammarException.h" #include <algorithm> #include <sstream> @@ -24,7 +23,7 @@ namespace grammar { NonContractingGrammar::NonContractingGrammar ( alphabet::Symbol initialSymbol ) : NonContractingGrammar ( std::set < alphabet::Symbol > { initialSymbol }, std::set < alphabet::Symbol > ( ), initialSymbol ) { } -NonContractingGrammar::NonContractingGrammar ( std::set < alphabet::Symbol > nonterminalAlphabet, std::set < alphabet::Symbol > terminalAlphabet, alphabet::Symbol initialSymbol ) : std::Components < NonContractingGrammar, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ), generatesEpsilon ( false ) { +NonContractingGrammar::NonContractingGrammar ( std::set < alphabet::Symbol > nonterminalAlphabet, std::set < alphabet::Symbol > terminalAlphabet, alphabet::Symbol initialSymbol ) : std::Components2 < NonContractingGrammar, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ), generatesEpsilon ( false ) { } GrammarBase * NonContractingGrammar::clone ( ) const { @@ -157,84 +156,6 @@ void NonContractingGrammar::composeRules ( std::deque < sax::Token > & out ) con } /* namespace grammar */ -namespace std { - -template < > -bool grammar::NonContractingGrammar::Component < grammar::NonContractingGrammar, alphabet::Symbol, grammar::TerminalAlphabet >::used ( const alphabet::Symbol & symbol ) const { - const grammar::NonContractingGrammar * grammar = static_cast < const grammar::NonContractingGrammar * > ( this ); - - for ( const std::pair < const std::vector < alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > > & rule : grammar->getRules ( ) ) { - if ( std::find ( rule.first.begin ( ), rule.first.end ( ), symbol ) != rule.first.end ( ) ) - return true; - - for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) - if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) - return true; - - } - - return false; -} - -template < > -bool grammar::NonContractingGrammar::Component < grammar::NonContractingGrammar, alphabet::Symbol, grammar::TerminalAlphabet >::available ( const alphabet::Symbol & ) const { - return true; -} - -template < > -void grammar::NonContractingGrammar::Component < grammar::NonContractingGrammar, alphabet::Symbol, grammar::TerminalAlphabet >::valid ( const alphabet::Symbol & symbol ) const { - const grammar::NonContractingGrammar * grammar = static_cast < const grammar::NonContractingGrammar * > ( this ); - - if ( grammar->accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) - throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); -} - -template < > -bool grammar::NonContractingGrammar::Component < grammar::NonContractingGrammar, alphabet::Symbol, grammar::NonterminalAlphabet >::used ( const alphabet::Symbol & symbol ) const { - const grammar::NonContractingGrammar * grammar = static_cast < const grammar::NonContractingGrammar * > ( this ); - - for ( const std::pair < const std::vector < alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > > & rule : grammar->getRules ( ) ) { - if ( std::find ( rule.first.begin ( ), rule.first.end ( ), symbol ) != rule.first.end ( ) ) - return true; - - for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) - if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) - return true; - - } - - if ( grammar->accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) - return true; - - return false; -} - -template < > -bool grammar::NonContractingGrammar::Component < grammar::NonContractingGrammar, alphabet::Symbol, grammar::NonterminalAlphabet >::available ( const alphabet::Symbol & ) const { - return true; -} - -template < > -void grammar::NonContractingGrammar::Component < grammar::NonContractingGrammar, alphabet::Symbol, grammar::NonterminalAlphabet >::valid ( const alphabet::Symbol & symbol ) const { - const grammar::NonContractingGrammar * grammar = static_cast < const grammar::NonContractingGrammar * > ( this ); - - if ( grammar->accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) - throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); -} - -template < > -bool grammar::NonContractingGrammar::Element < grammar::NonContractingGrammar, alphabet::Symbol, grammar::InitialSymbol >::available ( const alphabet::Symbol & symbol ) const { - const grammar::NonContractingGrammar * grammar = static_cast < const grammar::NonContractingGrammar * > ( this ); - - return grammar->accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); -} - -template < > -void grammar::NonContractingGrammar::Element < grammar::NonContractingGrammar, alphabet::Symbol, grammar::InitialSymbol >::valid ( const alphabet::Symbol & ) const { -} - -} /* namespace std */ - namespace alib { auto nonContractingGrammarParserRegister = xmlApi < grammar::Grammar >::ParserRegister < grammar::NonContractingGrammar > ( ); diff --git a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h index c02115c423..b7ad2dcab3 100644 --- a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h +++ b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h @@ -8,10 +8,11 @@ #ifndef NON_CONTRACTING_GRAMMAR_H_ #define NON_CONTRACTING_GRAMMAR_H_ +#include "../GrammarException.h" #include "../GrammarBase.h" #include <map> #include <vector> -#include <core/components.hpp> +#include <core/components2.hpp> #include "../../alphabet/Symbol.h" namespace grammar { @@ -23,7 +24,7 @@ class TerminalAlphabet; class NonterminalAlphabet; class InitialSymbol; -class NonContractingGrammar : public GrammarBase, public std::Components < NonContractingGrammar, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { +class NonContractingGrammar : public GrammarBase, public std::Components2 < NonContractingGrammar, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { std::map < std::vector < alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > > rules; bool generatesEpsilon; @@ -104,4 +105,76 @@ public: } /* namespace grammar */ +namespace std { + +template < > +class ComponentConstraint2< grammar::NonContractingGrammar, alphabet::Symbol, grammar::TerminalAlphabet > { +public: + static bool used ( const grammar::NonContractingGrammar & grammar, const alphabet::Symbol & symbol ) { + for ( const std::pair < const std::vector < alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > > & rule : grammar.getRules ( ) ) { + if ( std::find ( rule.first.begin ( ), rule.first.end ( ), symbol ) != rule.first.end ( ) ) + return true; + + for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) + if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) + return true; + + } + + return false; + } + + static bool available ( const grammar::NonContractingGrammar &, const alphabet::Symbol & ) { + return true; + } + + static void valid ( const grammar::NonContractingGrammar & grammar, const alphabet::Symbol & symbol ) { + if ( grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); + } +}; + +template < > +class ComponentConstraint2< grammar::NonContractingGrammar, alphabet::Symbol, grammar::NonterminalAlphabet > { +public: + static bool used ( const grammar::NonContractingGrammar & grammar, const alphabet::Symbol & symbol ) { + for ( const std::pair < const std::vector < alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > > & rule : grammar.getRules ( ) ) { + if ( std::find ( rule.first.begin ( ), rule.first.end ( ), symbol ) != rule.first.end ( ) ) + return true; + + for ( const std::vector < alphabet::Symbol > & rhs : rule.second ) + if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) + return true; + + } + + if ( grammar.accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) + return true; + + return false; + } + + static bool available ( const grammar::NonContractingGrammar &, const alphabet::Symbol & ) { + return true; + } + + static void valid ( const grammar::NonContractingGrammar & grammar, const alphabet::Symbol & symbol ) { + if ( grammar.accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); + } +}; + +template < > +class ElementConstraint2< grammar::NonContractingGrammar, alphabet::Symbol, grammar::InitialSymbol > { +public: + static bool available ( const grammar::NonContractingGrammar & grammar, const alphabet::Symbol & symbol ) { + return grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); + } + + static void valid ( const grammar::NonContractingGrammar &, const alphabet::Symbol & ) { + } +}; + +} /* namespace std */ + #endif /* NON_CONTRACTING_GRAMMAR_H_ */ diff --git a/alib2data/src/grammar/Regular/LeftLG.cpp b/alib2data/src/grammar/Regular/LeftLG.cpp index 7f0c24f42f..0df14e1823 100644 --- a/alib2data/src/grammar/Regular/LeftLG.cpp +++ b/alib2data/src/grammar/Regular/LeftLG.cpp @@ -6,7 +6,6 @@ */ #include "LeftLG.h" -#include "../GrammarException.h" #include <algorithm> #include <sstream> @@ -24,7 +23,7 @@ namespace grammar { LeftLG::LeftLG ( alphabet::Symbol initialSymbol ) : LeftLG ( std::set < alphabet::Symbol > { initialSymbol }, std::set < alphabet::Symbol > ( ), initialSymbol ) { } -LeftLG::LeftLG ( std::set < alphabet::Symbol > nonterminalAlphabet, std::set < alphabet::Symbol > terminalAlphabet, alphabet::Symbol initialSymbol ) : std::Components < LeftLG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ) { +LeftLG::LeftLG ( std::set < alphabet::Symbol > nonterminalAlphabet, std::set < alphabet::Symbol > terminalAlphabet, alphabet::Symbol initialSymbol ) : std::Components2 < LeftLG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ) { } GrammarBase * LeftLG::clone ( ) const { @@ -205,94 +204,6 @@ void LeftLG::composeRules ( std::deque < sax::Token > & out ) const { } /* namespace grammar */ -namespace std { - -template < > -bool grammar::LeftLG::Component < grammar::LeftLG, alphabet::Symbol, grammar::TerminalAlphabet >::used ( const alphabet::Symbol & symbol ) const { - const grammar::LeftLG * grammar = static_cast < const grammar::LeftLG * > ( this ); - - for ( const std::pair < const alphabet::Symbol, std::set < std::variant < std::vector < alphabet::Symbol >, std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > > > & rule : grammar->getRules ( ) ) { - for ( const std::variant < std::vector < alphabet::Symbol >, std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > & rhsTmp : rule.second ) - if ( rhsTmp.is < std::vector < alphabet::Symbol > > ( ) ) { - const std::vector < alphabet::Symbol > & rhs = rhsTmp.get < std::vector < alphabet::Symbol > > ( ); - - if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) - return true; - } else { - const std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > & rhs = rhsTmp.get < std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > ( ); - - if ( std::find ( rhs.second.begin ( ), rhs.second.end ( ), symbol ) != rhs.second.end ( ) ) - return true; - } - - } - - return false; -} - -template < > -bool grammar::LeftLG::Component < grammar::LeftLG, alphabet::Symbol, grammar::TerminalAlphabet >::available ( const alphabet::Symbol & ) const { - return true; -} - -template < > -void grammar::LeftLG::Component < grammar::LeftLG, alphabet::Symbol, grammar::TerminalAlphabet >::valid ( const alphabet::Symbol & symbol ) const { - const grammar::LeftLG * grammar = static_cast < const grammar::LeftLG * > ( this ); - - if ( grammar->accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) - throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); -} - -template < > -bool grammar::LeftLG::Component < grammar::LeftLG, alphabet::Symbol, grammar::NonterminalAlphabet >::used ( const alphabet::Symbol & symbol ) const { - const grammar::LeftLG * grammar = static_cast < const grammar::LeftLG * > ( this ); - - for ( const std::pair < const alphabet::Symbol, std::set < std::variant < std::vector < alphabet::Symbol >, std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > > > & rule : grammar->getRules ( ) ) { - if ( rule.first == symbol ) - return true; - - for ( const std::variant < std::vector < alphabet::Symbol >, std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > & rhsTmp : rule.second ) - if ( rhsTmp.is < std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > ( ) ) { - const std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > & rhs = rhsTmp.get < std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > ( ); - - if ( rhs.first == symbol ) - return true; - } - - } - - if ( grammar->accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) - return true; - - return false; -} - -template < > -bool grammar::LeftLG::Component < grammar::LeftLG, alphabet::Symbol, grammar::NonterminalAlphabet >::available ( const alphabet::Symbol & ) const { - return true; -} - -template < > -void grammar::LeftLG::Component < grammar::LeftLG, alphabet::Symbol, grammar::NonterminalAlphabet >::valid ( const alphabet::Symbol & symbol ) const { - const grammar::LeftLG * grammar = static_cast < const grammar::LeftLG * > ( this ); - - if ( grammar->accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) - throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); -} - -template < > -bool grammar::LeftLG::Element < grammar::LeftLG, alphabet::Symbol, grammar::InitialSymbol >::available ( const alphabet::Symbol & symbol ) const { - const grammar::LeftLG * grammar = static_cast < const grammar::LeftLG * > ( this ); - - return grammar->accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); -} - -template < > -void grammar::LeftLG::Element < grammar::LeftLG, alphabet::Symbol, grammar::InitialSymbol >::valid ( const alphabet::Symbol & ) const { -} - -} /* namespace std */ - namespace alib { auto LeftLGParserRegister = xmlApi < grammar::Grammar >::ParserRegister < grammar::LeftLG > ( ); diff --git a/alib2data/src/grammar/Regular/LeftLG.h b/alib2data/src/grammar/Regular/LeftLG.h index 5b11f3599c..381194ed8e 100644 --- a/alib2data/src/grammar/Regular/LeftLG.h +++ b/alib2data/src/grammar/Regular/LeftLG.h @@ -8,11 +8,12 @@ #ifndef LEFT_LG_H_ #define LEFT_LG_H_ +#include "../GrammarException.h" #include "../GrammarBase.h" #include <map> #include <vector> #include <variant> -#include <core/components.hpp> +#include <core/components2.hpp> #include "../../alphabet/Symbol.h" namespace grammar { @@ -24,7 +25,7 @@ class TerminalAlphabet; class NonterminalAlphabet; class InitialSymbol; -class LeftLG : public GrammarBase, public std::Components < LeftLG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { +class LeftLG : public GrammarBase, public std::Components2 < LeftLG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { std::map < alphabet::Symbol, std::set < std::variant < std::vector < alphabet::Symbol >, std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > > > rules; public: @@ -111,4 +112,86 @@ public: } /* namespace grammar */ +namespace std { + +template < > +class ComponentConstraint2< grammar::LeftLG, alphabet::Symbol, grammar::TerminalAlphabet > { +public: + static bool used ( const grammar::LeftLG & grammar, const alphabet::Symbol & symbol ) { + for ( const std::pair < const alphabet::Symbol, std::set < std::variant < std::vector < alphabet::Symbol >, std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > > > & rule : grammar.getRules ( ) ) { + for ( const std::variant < std::vector < alphabet::Symbol >, std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > & rhsTmp : rule.second ) + if ( rhsTmp.is < std::vector < alphabet::Symbol > > ( ) ) { + const std::vector < alphabet::Symbol > & rhs = rhsTmp.get < std::vector < alphabet::Symbol > > ( ); + + if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) + return true; + } else { + const std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > & rhs = rhsTmp.get < std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > ( ); + + if ( std::find ( rhs.second.begin ( ), rhs.second.end ( ), symbol ) != rhs.second.end ( ) ) + return true; + } + + } + + return false; + } + + static bool available ( const grammar::LeftLG &, const alphabet::Symbol & ) { + return true; + } + + static void valid ( const grammar::LeftLG & grammar, const alphabet::Symbol & symbol ) { + if ( grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); + } +}; + +template < > +class ComponentConstraint2< grammar::LeftLG, alphabet::Symbol, grammar::NonterminalAlphabet > { +public: + static bool used ( const grammar::LeftLG & grammar, const alphabet::Symbol & symbol ) { + for ( const std::pair < const alphabet::Symbol, std::set < std::variant < std::vector < alphabet::Symbol >, std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > > > & rule : grammar.getRules ( ) ) { + if ( rule.first == symbol ) + return true; + + for ( const std::variant < std::vector < alphabet::Symbol >, std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > & rhsTmp : rule.second ) + if ( rhsTmp.is < std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > ( ) ) { + const std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > & rhs = rhsTmp.get < std::pair < alphabet::Symbol, std::vector < alphabet::Symbol > > > ( ); + + if ( rhs.first == symbol ) + return true; + } + + } + + if ( grammar.accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) + return true; + + return false; + } + + static bool available ( const grammar::LeftLG &, const alphabet::Symbol & ) { + return true; + } + + static void valid ( const grammar::LeftLG & grammar, const alphabet::Symbol & symbol ) { + if ( grammar.accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); + } +}; + +template < > +class ElementConstraint2< grammar::LeftLG, alphabet::Symbol, grammar::InitialSymbol > { +public: + static bool available ( const grammar::LeftLG & grammar, const alphabet::Symbol & symbol ) { + return grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); + } + + static void valid ( const grammar::LeftLG &, const alphabet::Symbol & ) { + } +}; + +} /* namespace std */ + #endif /* LEFT_LG_H_ */ diff --git a/alib2data/src/grammar/Regular/LeftRG.cpp b/alib2data/src/grammar/Regular/LeftRG.cpp index db59311825..d375774e96 100644 --- a/alib2data/src/grammar/Regular/LeftRG.cpp +++ b/alib2data/src/grammar/Regular/LeftRG.cpp @@ -6,7 +6,6 @@ */ #include "LeftRG.h" -#include "../GrammarException.h" #include <algorithm> #include <sstream> @@ -24,7 +23,7 @@ namespace grammar { LeftRG::LeftRG ( alphabet::Symbol initialSymbol ) : LeftRG ( std::set < alphabet::Symbol > { initialSymbol }, std::set < alphabet::Symbol > ( ), initialSymbol ) { } -LeftRG::LeftRG ( std::set < alphabet::Symbol > nonterminalAlphabet, std::set < alphabet::Symbol > terminalAlphabet, alphabet::Symbol initialSymbol ) : std::Components < LeftRG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ), generatesEpsilon ( false ) { +LeftRG::LeftRG ( std::set < alphabet::Symbol > nonterminalAlphabet, std::set < alphabet::Symbol > terminalAlphabet, alphabet::Symbol initialSymbol ) : std::Components2 < LeftRG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ), generatesEpsilon ( false ) { } GrammarBase * LeftRG::clone ( ) const { @@ -232,79 +231,6 @@ void LeftRG::composeRules ( std::deque < sax::Token > & out ) const { } /* namespace grammar */ -namespace std { - -template < > -bool grammar::LeftRG::Component < grammar::LeftRG, alphabet::Symbol, grammar::TerminalAlphabet >::used ( const alphabet::Symbol & symbol ) const { - const grammar::LeftRG * grammar = static_cast < const grammar::LeftRG * > ( this ); - - for ( const std::pair < const alphabet::Symbol, std::set < std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > > > & rule : grammar->getRules ( ) ) - for ( const std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > & rhs : rule.second ) - if ( ( rhs.is < alphabet::Symbol > ( ) && ( rhs.get < alphabet::Symbol > ( ) == symbol ) ) || ( rhs.get < std::pair < alphabet::Symbol, alphabet::Symbol > > ( ).first == symbol ) ) - return true; - - return false; -} - -template < > -bool grammar::LeftRG::Component < grammar::LeftRG, alphabet::Symbol, grammar::TerminalAlphabet >::available ( const alphabet::Symbol & ) const { - return true; -} - -template < > -void grammar::LeftRG::Component < grammar::LeftRG, alphabet::Symbol, grammar::TerminalAlphabet >::valid ( const alphabet::Symbol & symbol ) const { - const grammar::LeftRG * grammar = static_cast < const grammar::LeftRG * > ( this ); - - if ( grammar->accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) - throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); -} - -template < > -bool grammar::LeftRG::Component < grammar::LeftRG, alphabet::Symbol, grammar::NonterminalAlphabet >::used ( const alphabet::Symbol & symbol ) const { - const grammar::LeftRG * grammar = static_cast < const grammar::LeftRG * > ( this ); - - for ( const std::pair < const alphabet::Symbol, std::set < std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > > > & rule : grammar->getRules ( ) ) { - if ( rule.first == symbol ) - return true; - - for ( const std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > & rhs : rule.second ) - if ( rhs.get < std::pair < alphabet::Symbol, alphabet::Symbol > > ( ).second == symbol ) - return true; - - } - - if ( grammar->accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) - return true; - - return false; -} - -template < > -bool grammar::LeftRG::Component < grammar::LeftRG, alphabet::Symbol, grammar::NonterminalAlphabet >::available ( const alphabet::Symbol & ) const { - return true; -} - -template < > -void grammar::LeftRG::Component < grammar::LeftRG, alphabet::Symbol, grammar::NonterminalAlphabet >::valid ( const alphabet::Symbol & symbol ) const { - const grammar::LeftRG * grammar = static_cast < const grammar::LeftRG * > ( this ); - - if ( grammar->accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) - throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); -} - -template < > -bool grammar::LeftRG::Element < grammar::LeftRG, alphabet::Symbol, grammar::InitialSymbol >::available ( const alphabet::Symbol & symbol ) const { - const grammar::LeftRG * grammar = static_cast < const grammar::LeftRG * > ( this ); - - return grammar->accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); -} - -template < > -void grammar::LeftRG::Element < grammar::LeftRG, alphabet::Symbol, grammar::InitialSymbol >::valid ( const alphabet::Symbol & ) const { -} - -} /* namespace std */ - namespace alib { auto LeftRGParserRegister = xmlApi < grammar::Grammar >::ParserRegister < grammar::LeftRG > ( ); diff --git a/alib2data/src/grammar/Regular/LeftRG.h b/alib2data/src/grammar/Regular/LeftRG.h index a8307dfe7b..95f77b0466 100644 --- a/alib2data/src/grammar/Regular/LeftRG.h +++ b/alib2data/src/grammar/Regular/LeftRG.h @@ -8,11 +8,12 @@ #ifndef LEFT_RG_H_ #define LEFT_RG_H_ +#include "../GrammarException.h" #include "../GrammarBase.h" #include <map> #include <vector> #include <variant> -#include <core/components.hpp> +#include <core/components2.hpp> #include "../../alphabet/Symbol.h" namespace grammar { @@ -33,7 +34,7 @@ class TerminalAlphabet; class NonterminalAlphabet; class InitialSymbol; -class LeftRG : public GrammarBase, public std::Components < LeftRG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { +class LeftRG : public GrammarBase, public std::Components2 < LeftRG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { /** * Transition function as mapping from nonterminal symbol on the left hand side to set of either terminal symbols or doublets of terminal symbol and nonterminal symbol */ @@ -189,4 +190,71 @@ public: } /* namespace grammar */ +namespace std { + +template < > +class ComponentConstraint2< grammar::LeftRG, alphabet::Symbol, grammar::TerminalAlphabet > { +public: + static bool used ( const grammar::LeftRG & grammar, const alphabet::Symbol & symbol ) { + for ( const std::pair < const alphabet::Symbol, std::set < std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > > > & rule : grammar.getRules ( ) ) + for ( const std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > & rhs : rule.second ) + if ( ( rhs.is < alphabet::Symbol > ( ) && ( rhs.get < alphabet::Symbol > ( ) == symbol ) ) || ( rhs.get < std::pair < alphabet::Symbol, alphabet::Symbol > > ( ).first == symbol ) ) + return true; + + return false; + } + + static bool available ( const grammar::LeftRG &, const alphabet::Symbol & ) { + return true; + } + + static void valid ( const grammar::LeftRG & grammar, const alphabet::Symbol & symbol ) { + if ( grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); + } +}; + +template < > +class ComponentConstraint2< grammar::LeftRG, alphabet::Symbol, grammar::NonterminalAlphabet > { +public: + static bool used ( const grammar::LeftRG & grammar, const alphabet::Symbol & symbol ) { + for ( const std::pair < const alphabet::Symbol, std::set < std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > > > & rule : grammar.getRules ( ) ) { + if ( rule.first == symbol ) + return true; + + for ( const std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > & rhs : rule.second ) + if ( rhs.get < std::pair < alphabet::Symbol, alphabet::Symbol > > ( ).second == symbol ) + return true; + + } + + if ( grammar.accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) + return true; + + return false; + } + + static bool available ( const grammar::LeftRG &, const alphabet::Symbol & ) { + return true; + } + + static void valid ( const grammar::LeftRG & grammar, const alphabet::Symbol & symbol ) { + if ( grammar.accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); + } +}; + +template < > +class ElementConstraint2< grammar::LeftRG, alphabet::Symbol, grammar::InitialSymbol > { +public: + static bool available ( const grammar::LeftRG & grammar, const alphabet::Symbol & symbol ) { + return grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); + } + + static void valid ( const grammar::LeftRG &, const alphabet::Symbol & ) { + } +}; + +} /* namespace std */ + #endif /* LEFT_RG_H_ */ diff --git a/alib2data/src/grammar/Regular/RightLG.cpp b/alib2data/src/grammar/Regular/RightLG.cpp index 3ce8a30432..4ea483bcad 100644 --- a/alib2data/src/grammar/Regular/RightLG.cpp +++ b/alib2data/src/grammar/Regular/RightLG.cpp @@ -6,7 +6,6 @@ */ #include "RightLG.h" -#include "../GrammarException.h" #include <algorithm> #include <sstream> @@ -24,7 +23,7 @@ namespace grammar { RightLG::RightLG ( alphabet::Symbol initialSymbol ) : RightLG ( std::set < alphabet::Symbol > { initialSymbol }, std::set < alphabet::Symbol > ( ), initialSymbol ) { } -RightLG::RightLG ( std::set < alphabet::Symbol > nonterminalAlphabet, std::set < alphabet::Symbol > terminalAlphabet, alphabet::Symbol initialSymbol ) : std::Components < RightLG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ) { +RightLG::RightLG ( std::set < alphabet::Symbol > nonterminalAlphabet, std::set < alphabet::Symbol > terminalAlphabet, alphabet::Symbol initialSymbol ) : std::Components2 < RightLG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ) { } GrammarBase * RightLG::clone ( ) const { @@ -205,94 +204,6 @@ void RightLG::composeRules ( std::deque < sax::Token > & out ) const { } /* namespace grammar */ -namespace std { - -template < > -bool grammar::RightLG::Component < grammar::RightLG, alphabet::Symbol, grammar::TerminalAlphabet >::used ( const alphabet::Symbol & symbol ) const { - const grammar::RightLG * grammar = static_cast < const grammar::RightLG * > ( this ); - - for ( const std::pair < const alphabet::Symbol, std::set < std::variant < std::vector < alphabet::Symbol >, std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > > > & rule : grammar->getRules ( ) ) { - for ( const std::variant < std::vector < alphabet::Symbol >, std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > & rhsTmp : rule.second ) - if ( rhsTmp.is < std::vector < alphabet::Symbol > > ( ) ) { - const std::vector < alphabet::Symbol > & rhs = rhsTmp.get < std::vector < alphabet::Symbol > > ( ); - - if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) - return true; - } else { - const std::vector < alphabet::Symbol > & rhs = rhsTmp.get < std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > ( ).first; - - if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) - return true; - } - - } - - return false; -} - -template < > -bool grammar::RightLG::Component < grammar::RightLG, alphabet::Symbol, grammar::TerminalAlphabet >::available ( const alphabet::Symbol & ) const { - return true; -} - -template < > -void grammar::RightLG::Component < grammar::RightLG, alphabet::Symbol, grammar::TerminalAlphabet >::valid ( const alphabet::Symbol & symbol ) const { - const grammar::RightLG * grammar = static_cast < const grammar::RightLG * > ( this ); - - if ( grammar->accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) - throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); -} - -template < > -bool grammar::RightLG::Component < grammar::RightLG, alphabet::Symbol, grammar::NonterminalAlphabet >::used ( const alphabet::Symbol & symbol ) const { - const grammar::RightLG * grammar = static_cast < const grammar::RightLG * > ( this ); - - for ( const std::pair < const alphabet::Symbol, std::set < std::variant < std::vector < alphabet::Symbol >, std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > > > & rule : grammar->getRules ( ) ) { - if ( rule.first == symbol ) - return true; - - for ( const std::variant < std::vector < alphabet::Symbol >, std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > & rhsTmp : rule.second ) - if ( rhsTmp.is < std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > ( ) ) { - const std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > & rhs = rhsTmp.get < std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > ( ); - - if ( rhs.second == symbol ) - return true; - } - - } - - if ( grammar->accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) - return true; - - return false; -} - -template < > -bool grammar::RightLG::Component < grammar::RightLG, alphabet::Symbol, grammar::NonterminalAlphabet >::available ( const alphabet::Symbol & ) const { - return true; -} - -template < > -void grammar::RightLG::Component < grammar::RightLG, alphabet::Symbol, grammar::NonterminalAlphabet >::valid ( const alphabet::Symbol & symbol ) const { - const grammar::RightLG * grammar = static_cast < const grammar::RightLG * > ( this ); - - if ( grammar->accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) - throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); -} - -template < > -bool grammar::RightLG::Element < grammar::RightLG, alphabet::Symbol, grammar::InitialSymbol >::available ( const alphabet::Symbol & symbol ) const { - const grammar::RightLG * grammar = static_cast < const grammar::RightLG * > ( this ); - - return grammar->accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); -} - -template < > -void grammar::RightLG::Element < grammar::RightLG, alphabet::Symbol, grammar::InitialSymbol >::valid ( const alphabet::Symbol & ) const { -} - -} /* namespace std */ - namespace alib { auto RightLGParserRegister = xmlApi < grammar::Grammar >::ParserRegister < grammar::RightLG > ( ); diff --git a/alib2data/src/grammar/Regular/RightLG.h b/alib2data/src/grammar/Regular/RightLG.h index e758a27d44..506ef62762 100644 --- a/alib2data/src/grammar/Regular/RightLG.h +++ b/alib2data/src/grammar/Regular/RightLG.h @@ -8,11 +8,12 @@ #ifndef RIGHT_LG_H_ #define RIGHT_LG_H_ +#include "../GrammarException.h" #include "../GrammarBase.h" #include <map> #include <vector> #include <variant> -#include <core/components.hpp> +#include <core/components2.hpp> #include "../../alphabet/Symbol.h" namespace grammar { @@ -24,7 +25,7 @@ class TerminalAlphabet; class NonterminalAlphabet; class InitialSymbol; -class RightLG : public GrammarBase, public std::Components < RightLG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { +class RightLG : public GrammarBase, public std::Components2 < RightLG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { std::map < alphabet::Symbol, std::set < std::variant < std::vector < alphabet::Symbol >, std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > > > rules; public: @@ -111,4 +112,86 @@ public: } /* namespace grammar */ +namespace std { + +template < > +class ComponentConstraint2< grammar::RightLG, alphabet::Symbol, grammar::TerminalAlphabet > { +public: + static bool used ( const grammar::RightLG & grammar, const alphabet::Symbol & symbol ) { + for ( const std::pair < const alphabet::Symbol, std::set < std::variant < std::vector < alphabet::Symbol >, std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > > > & rule : grammar.getRules ( ) ) { + for ( const std::variant < std::vector < alphabet::Symbol >, std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > & rhsTmp : rule.second ) + if ( rhsTmp.is < std::vector < alphabet::Symbol > > ( ) ) { + const std::vector < alphabet::Symbol > & rhs = rhsTmp.get < std::vector < alphabet::Symbol > > ( ); + + if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) + return true; + } else { + const std::vector < alphabet::Symbol > & rhs = rhsTmp.get < std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > ( ).first; + + if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) + return true; + } + + } + + return false; + } + + static bool available ( const grammar::RightLG &, const alphabet::Symbol & ) { + return true; + } + + static void valid ( const grammar::RightLG & grammar, const alphabet::Symbol & symbol ) { + if ( grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); + } +}; + +template < > +class ComponentConstraint2< grammar::RightLG, alphabet::Symbol, grammar::NonterminalAlphabet > { +public: + static bool used ( const grammar::RightLG & grammar, const alphabet::Symbol & symbol ) { + for ( const std::pair < const alphabet::Symbol, std::set < std::variant < std::vector < alphabet::Symbol >, std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > > > & rule : grammar.getRules ( ) ) { + if ( rule.first == symbol ) + return true; + + for ( const std::variant < std::vector < alphabet::Symbol >, std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > & rhsTmp : rule.second ) + if ( rhsTmp.is < std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > ( ) ) { + const std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > & rhs = rhsTmp.get < std::pair < std::vector < alphabet::Symbol >, alphabet::Symbol > > ( ); + + if ( rhs.second == symbol ) + return true; + } + + } + + if ( grammar.accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) + return true; + + return false; + } + + static bool available ( const grammar::RightLG &, const alphabet::Symbol & ) { + return true; + } + + static void valid ( const grammar::RightLG & grammar, const alphabet::Symbol & symbol ) { + if ( grammar.accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); + } +}; + +template < > +class ElementConstraint2< grammar::RightLG, alphabet::Symbol, grammar::InitialSymbol > { +public: + static bool available ( const grammar::RightLG & grammar, const alphabet::Symbol & symbol ) { + return grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); + } + + static void valid ( const grammar::RightLG &, const alphabet::Symbol & ) { + } +}; + +} /* namespace std */ + #endif /* RIGHT_LG_H_ */ diff --git a/alib2data/src/grammar/Regular/RightRG.cpp b/alib2data/src/grammar/Regular/RightRG.cpp index 5c34244a69..74aae42385 100644 --- a/alib2data/src/grammar/Regular/RightRG.cpp +++ b/alib2data/src/grammar/Regular/RightRG.cpp @@ -6,7 +6,6 @@ */ #include "RightRG.h" -#include "../GrammarException.h" #include <algorithm> #include <sstream> @@ -24,7 +23,7 @@ namespace grammar { RightRG::RightRG ( alphabet::Symbol initialSymbol ) : RightRG ( std::set < alphabet::Symbol > { initialSymbol }, std::set < alphabet::Symbol > ( ), initialSymbol ) { } -RightRG::RightRG ( std::set < alphabet::Symbol > nonterminalAlphabet, std::set < alphabet::Symbol > terminalAlphabet, alphabet::Symbol initialSymbol ) : std::Components < RightRG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ), generatesEpsilon ( false ) { +RightRG::RightRG ( std::set < alphabet::Symbol > nonterminalAlphabet, std::set < alphabet::Symbol > terminalAlphabet, alphabet::Symbol initialSymbol ) : std::Components2 < RightRG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ), generatesEpsilon ( false ) { } GrammarBase * RightRG::clone ( ) const { @@ -230,79 +229,6 @@ void RightRG::composeRules ( std::deque < sax::Token > & out ) const { } /* namespace grammar */ -namespace std { - -template < > -bool grammar::RightRG::Component < grammar::RightRG, alphabet::Symbol, grammar::TerminalAlphabet >::used ( const alphabet::Symbol & symbol ) const { - const grammar::RightRG * grammar = static_cast < const grammar::RightRG * > ( this ); - - for ( const std::pair < const alphabet::Symbol, std::set < std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > > > & rule : grammar->getRules ( ) ) - for ( const std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > & rhs : rule.second ) - if ( ( rhs.is < alphabet::Symbol > ( ) && ( rhs.get < alphabet::Symbol > ( ) == symbol ) ) || ( rhs.get < std::pair < alphabet::Symbol, alphabet::Symbol > > ( ).first == symbol ) ) - return true; - - return false; -} - -template < > -bool grammar::RightRG::Component < grammar::RightRG, alphabet::Symbol, grammar::TerminalAlphabet >::available ( const alphabet::Symbol & ) const { - return true; -} - -template < > -void grammar::RightRG::Component < grammar::RightRG, alphabet::Symbol, grammar::TerminalAlphabet >::valid ( const alphabet::Symbol & symbol ) const { - const grammar::RightRG * grammar = static_cast < const grammar::RightRG * > ( this ); - - if ( grammar->accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) - throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); -} - -template < > -bool grammar::RightRG::Component < grammar::RightRG, alphabet::Symbol, grammar::NonterminalAlphabet >::used ( const alphabet::Symbol & symbol ) const { - const grammar::RightRG * grammar = static_cast < const grammar::RightRG * > ( this ); - - for ( const std::pair < const alphabet::Symbol, std::set < std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > > > & rule : grammar->getRules ( ) ) { - if ( rule.first == symbol ) - return true; - - for ( const std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > & rhs : rule.second ) - if ( rhs.get < std::pair < alphabet::Symbol, alphabet::Symbol > > ( ).second == symbol ) - return true; - - } - - if ( grammar->accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) - return true; - - return false; -} - -template < > -bool grammar::RightRG::Component < grammar::RightRG, alphabet::Symbol, grammar::NonterminalAlphabet >::available ( const alphabet::Symbol & ) const { - return true; -} - -template < > -void grammar::RightRG::Component < grammar::RightRG, alphabet::Symbol, grammar::NonterminalAlphabet >::valid ( const alphabet::Symbol & symbol ) const { - const grammar::RightRG * grammar = static_cast < const grammar::RightRG * > ( this ); - - if ( grammar->accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) - throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); -} - -template < > -bool grammar::RightRG::Element < grammar::RightRG, alphabet::Symbol, grammar::InitialSymbol >::available ( const alphabet::Symbol & symbol ) const { - const grammar::RightRG * grammar = static_cast < const grammar::RightRG * > ( this ); - - return grammar->accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); -} - -template < > -void grammar::RightRG::Element < grammar::RightRG, alphabet::Symbol, grammar::InitialSymbol >::valid ( const alphabet::Symbol & ) const { -} - -} /* namespace std */ - namespace alib { auto RightRGParserRegister = xmlApi < grammar::Grammar >::ParserRegister < grammar::RightRG > ( ); diff --git a/alib2data/src/grammar/Regular/RightRG.h b/alib2data/src/grammar/Regular/RightRG.h index 1b8d85ba74..2b1d3fd0d6 100644 --- a/alib2data/src/grammar/Regular/RightRG.h +++ b/alib2data/src/grammar/Regular/RightRG.h @@ -8,11 +8,12 @@ #ifndef RIGHT_RG_H_ #define RIGHT_RG_H_ +#include "../GrammarException.h" #include "../GrammarBase.h" #include <map> #include <vector> #include <variant> -#include <core/components.hpp> +#include <core/components2.hpp> #include "../../alphabet/Symbol.h" namespace grammar { @@ -34,7 +35,7 @@ class TerminalAlphabet; class NonterminalAlphabet; class InitialSymbol; -class RightRG : public GrammarBase, public std::Components < RightRG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { +class RightRG : public GrammarBase, public std::Components2 < RightRG, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { /** * Transition function as mapping from nonterminal symbol on the left hand side to set of either terminal symbols or doublets of terminal symbol and nonterminal symbol */ @@ -132,4 +133,71 @@ public: } /* namespace grammar */ +namespace std { + +template < > +class ComponentConstraint2< grammar::RightRG, alphabet::Symbol, grammar::TerminalAlphabet > { +public: + static bool used ( const grammar::RightRG & grammar, const alphabet::Symbol & symbol ) { + for ( const std::pair < const alphabet::Symbol, std::set < std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > > > & rule : grammar.getRules ( ) ) + for ( const std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > & rhs : rule.second ) + if ( ( rhs.is < alphabet::Symbol > ( ) && ( rhs.get < alphabet::Symbol > ( ) == symbol ) ) || ( rhs.get < std::pair < alphabet::Symbol, alphabet::Symbol > > ( ).first == symbol ) ) + return true; + + return false; + } + + static bool available ( const grammar::RightRG &, const alphabet::Symbol & ) { + return true; + } + + static void valid ( const grammar::RightRG & grammar, const alphabet::Symbol & symbol ) { + if ( grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); + } +}; + +template < > +class ComponentConstraint2< grammar::RightRG, alphabet::Symbol, grammar::NonterminalAlphabet > { +public: + static bool used ( const grammar::RightRG & grammar, const alphabet::Symbol & symbol ) { + for ( const std::pair < const alphabet::Symbol, std::set < std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > > > & rule : grammar.getRules ( ) ) { + if ( rule.first == symbol ) + return true; + + for ( const std::variant < alphabet::Symbol, std::pair < alphabet::Symbol, alphabet::Symbol > > & rhs : rule.second ) + if ( rhs.get < std::pair < alphabet::Symbol, alphabet::Symbol > > ( ).second == symbol ) + return true; + + } + + if ( grammar.accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) + return true; + + return false; + } + + static bool available ( const grammar::RightRG &, const alphabet::Symbol & ) { + return true; + } + + static void valid ( const grammar::RightRG & grammar, const alphabet::Symbol & symbol ) { + if ( grammar.accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + throw grammar::GrammarException ( "Symbol " + ( std::string ) symbol + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); + } +}; + +template < > +class ElementConstraint2< grammar::RightRG, alphabet::Symbol, grammar::InitialSymbol > { +public: + static bool available ( const grammar::RightRG & grammar, const alphabet::Symbol & symbol ) { + return grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); + } + + static void valid ( const grammar::RightRG &, const alphabet::Symbol & ) { + } +}; + +} /* namespace std */ + #endif /* RIGHT_RG_H_ */ -- GitLab