diff --git a/acompare2/src/GrammarCompare.cpp b/acompare2/src/GrammarCompare.cpp index 6e3dd9ef5fd50eceb135e6494655d40b5b1cb609..101d325d147be690c8e3dee19f53d98faf2a1b43 100644 --- a/acompare2/src/GrammarCompare.cpp +++ b/acompare2/src/GrammarCompare.cpp @@ -100,7 +100,7 @@ bool GrammarCompare::testCompare(const grammar::CSG < > & a, const grammar::CSG a.getTerminalAlphabet() == b.getTerminalAlphabet() ; } -bool GrammarCompare::testCompare(const grammar::NonContractingGrammar& a, const grammar::NonContractingGrammar& b) { +bool GrammarCompare::testCompare(const grammar::NonContractingGrammar < > & a, const grammar::NonContractingGrammar < > & b) { return a.getNonterminalAlphabet() == b.getNonterminalAlphabet() && a.getRules() == b.getRules() && a.getInitialSymbol() == b.getInitialSymbol() && @@ -469,7 +469,7 @@ void GrammarCompare::printCompare(const grammar::CSG < > & a, const grammar::CSG } } -void GrammarCompare::printCompare(const grammar::NonContractingGrammar& a, const grammar::NonContractingGrammar& b) { +void GrammarCompare::printCompare(const grammar::NonContractingGrammar < > & a, const grammar::NonContractingGrammar < > & b) { std::cout << "GrammarCompareer" << std::endl; if(a.getNonterminalAlphabet() != b.getNonterminalAlphabet()) { @@ -669,7 +669,7 @@ int GrammarCompare::compare(const grammar::CSG < > & a, const grammar::CSG < > & auto GrammarCompareCSG = GrammarCompare::RegistratorWrapper<int, grammar::CSG < >, grammar::CSG < > >(GrammarCompare::compare); -int GrammarCompare::compare(const grammar::NonContractingGrammar& a, const grammar::NonContractingGrammar& b) { +int GrammarCompare::compare(const grammar::NonContractingGrammar < > & a, const grammar::NonContractingGrammar < > & b) { if(!GrammarCompare::testCompare(a, b)) { GrammarCompare::printCompare(a, b); return 1; @@ -678,7 +678,7 @@ int GrammarCompare::compare(const grammar::NonContractingGrammar& a, const gramm } } -auto GrammarCompareNonContractingGrammar = GrammarCompare::RegistratorWrapper<int, grammar::NonContractingGrammar, grammar::NonContractingGrammar>(GrammarCompare::compare); +auto GrammarCompareNonContractingGrammar = GrammarCompare::RegistratorWrapper<int, grammar::NonContractingGrammar < >, grammar::NonContractingGrammar < > >(GrammarCompare::compare); int GrammarCompare::compare(const grammar::ContextPreservingUnrestrictedGrammar& a, const grammar::ContextPreservingUnrestrictedGrammar& b) { if(!GrammarCompare::testCompare(a, b)) { diff --git a/acompare2/src/GrammarCompare.h b/acompare2/src/GrammarCompare.h index 391e973860b1d530dc7879133b0605c32c9d3d60..8aa7a471ba48516382d33bc27a35e0abf9543944 100644 --- a/acompare2/src/GrammarCompare.h +++ b/acompare2/src/GrammarCompare.h @@ -50,8 +50,8 @@ private: static bool testCompare(const grammar::CSG < > & a, const grammar::CSG < > & b); static void printCompare(const grammar::CSG < > & a, const grammar::CSG < > & b); - static bool testCompare(const grammar::NonContractingGrammar& a, const grammar::NonContractingGrammar& b); - static void printCompare(const grammar::NonContractingGrammar& a, const grammar::NonContractingGrammar& b); + static bool testCompare(const grammar::NonContractingGrammar < > & a, const grammar::NonContractingGrammar < > & b); + static void printCompare(const grammar::NonContractingGrammar < > & a, const grammar::NonContractingGrammar < > & b); static bool testCompare(const grammar::ContextPreservingUnrestrictedGrammar& a, const grammar::ContextPreservingUnrestrictedGrammar& b); static void printCompare(const grammar::ContextPreservingUnrestrictedGrammar& a, const grammar::ContextPreservingUnrestrictedGrammar& b); @@ -73,7 +73,7 @@ public: static int compare(const grammar::CNF < > & a, const grammar::CNF < > & b); static int compare(const grammar::GNF < > & a, const grammar::GNF < > & b); static int compare(const grammar::CSG < > & a, const grammar::CSG < > & b); - static int compare(const grammar::NonContractingGrammar& a, const grammar::NonContractingGrammar& b); + static int compare(const grammar::NonContractingGrammar < > & a, const grammar::NonContractingGrammar < > & b); static int compare(const grammar::ContextPreservingUnrestrictedGrammar& a, const grammar::ContextPreservingUnrestrictedGrammar& b); static int compare(const grammar::UnrestrictedGrammar& a, const grammar::UnrestrictedGrammar& b); diff --git a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp index 0e9e6c45cb741dca12e85f98fa54380857e5988d..da1e477e6c9f4908c7d37f9bd9e34b7c457daed5 100644 --- a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp +++ b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp @@ -6,159 +6,13 @@ */ #include "NonContractingGrammar.h" -#include <algorithm> -#include <sstream> - -#include "../../alphabet/Symbol.h" - -#include <sax/FromXMLParserHelper.h> -#include "../common/GrammarFromXMLParser.h" -#include "../common/GrammarToXMLComposer.h" #include "../Grammar.h" #include <object/Object.h> #include <XmlApi.hpp> -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 ) { -} - -GrammarBase * NonContractingGrammar::clone ( ) const { - return new NonContractingGrammar ( * this ); -} - -GrammarBase * NonContractingGrammar::plunder ( ) && { - return new NonContractingGrammar ( std::move ( * this ) ); -} - -bool NonContractingGrammar::addRule ( std::vector < alphabet::Symbol > leftHandSide, std::vector < alphabet::Symbol > rightHandSide ) { - int lSize = leftHandSide.size ( ); - int rSize = rightHandSide.size ( ); - - if ( lSize > rSize ) - throw GrammarException ( "Invalid size of right hand side of a rule" ); - - if ( std::all_of ( leftHandSide.begin ( ), leftHandSide.end ( ), [this] ( const alphabet::Symbol symbol ) { - return !getNonterminalAlphabet ( ).count ( symbol ); - } ) ) - throw GrammarException ( "Rule must rewrite nonterminal symbol" ); - - for ( const alphabet::Symbol & symbol : leftHandSide ) - if ( !getTerminalAlphabet ( ).count ( symbol ) && !getNonterminalAlphabet ( ).count ( symbol ) ) - throw GrammarException ( "Symbol \"" + std::to_string ( symbol ) + "\" is not neither terminal nor nonterminal symbol" ); - - for ( const alphabet::Symbol & symbol : rightHandSide ) - if ( !getTerminalAlphabet ( ).count ( symbol ) && !getNonterminalAlphabet ( ).count ( symbol ) ) - throw GrammarException ( "Symbol \"" + std::to_string ( symbol ) + "\" is not neither terminal nor nonterminal symbol" ); - - return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second; -} - -const std::map < std::vector < alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > > & NonContractingGrammar::getRules ( ) const { - return rules; -} - -bool NonContractingGrammar::removeRule ( const std::vector < alphabet::Symbol > & leftHandSide, const std::vector < alphabet::Symbol > & rightHandSide ) { - return rules[leftHandSide].erase ( rightHandSide ); -} - -void NonContractingGrammar::setGeneratesEpsilon ( bool genEps ) { - generatesEpsilon = genEps; -} - -bool NonContractingGrammar::getGeneratesEpsilon ( ) const { - return generatesEpsilon; -} - -int NonContractingGrammar::compare ( const NonContractingGrammar & other ) const { - auto first = std::tie ( getTerminalAlphabet ( ), getNonterminalAlphabet ( ), getInitialSymbol ( ), rules ); - auto second = std::tie ( other.getTerminalAlphabet ( ), other.getNonterminalAlphabet ( ), other.getInitialSymbol ( ), other.rules ); - - std::compare < decltype ( first ) > comp; - - return comp ( first, second ); -} - -void NonContractingGrammar::operator >>( std::ostream & out ) const { - out << "(NonContractingGrammar " - << "nonterminalAlphabet = " << getNonterminalAlphabet ( ) - << "terminalAlphabet = " << getTerminalAlphabet ( ) - << "initialSymbol = " << getInitialSymbol ( ) - << "rules = " << rules - << "generatesEpsilon = " << generatesEpsilon << ")"; -} - -NonContractingGrammar::operator std::string ( ) const { - std::stringstream ss; - ss << * this; - return ss.str ( ); -} - -NonContractingGrammar NonContractingGrammar::parse ( std::deque < sax::Token >::iterator & input ) { - sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, NonContractingGrammar::getXmlTagName() ); - - std::set < alphabet::Symbol > nonterminalAlphabet = GrammarFromXMLParser::parseNonterminalAlphabet ( input ); - std::set < alphabet::Symbol > terminalAlphabet = GrammarFromXMLParser::parseTerminalAlphabet ( input ); - alphabet::Symbol initialSymbol = GrammarFromXMLParser::parseInitialSymbol ( input ); - - NonContractingGrammar grammar ( std::move ( initialSymbol ) ); - - grammar.setNonterminalAlphabet ( std::move ( nonterminalAlphabet ) ); - grammar.setTerminalAlphabet ( std::move ( terminalAlphabet ) ); - - GrammarFromXMLParser::parseRules ( input, grammar ); - - bool generatesEpsilon = GrammarFromXMLParser::parseGeneratesEpsilon ( input ); - grammar.setGeneratesEpsilon ( generatesEpsilon ); - - sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, NonContractingGrammar::getXmlTagName() ); - return grammar; -} - -void NonContractingGrammar::parseRule ( std::deque < sax::Token >::iterator & input, NonContractingGrammar & grammar ) { - std::vector < alphabet::Symbol > lhs = GrammarFromXMLParser::parseRuleLHS ( input ); - std::vector < alphabet::Symbol > rhs = GrammarFromXMLParser::parseRuleRHS ( input ); - - grammar.addRule ( std::move ( lhs ), std::move ( rhs ) ); -} - -void NonContractingGrammar::compose ( std::deque < sax::Token > & out ) const { - out.emplace_back ( NonContractingGrammar::getXmlTagName(), sax::Token::TokenType::START_ELEMENT ); - - GrammarToXMLComposer::composeNonterminalAlphabet ( out, this->getNonterminalAlphabet ( ) ); - GrammarToXMLComposer::composeTerminalAlphabet ( out, this->getTerminalAlphabet ( ) ); - GrammarToXMLComposer::composeInitialSymbol ( out, this->getInitialSymbol ( ) ); - composeRules ( out ); - GrammarToXMLComposer::composeGeneratesEpsilon ( out, this->getGeneratesEpsilon ( ) ); - - out.emplace_back ( NonContractingGrammar::getXmlTagName(), sax::Token::TokenType::END_ELEMENT ); -} - -void NonContractingGrammar::composeRules ( std::deque < sax::Token > & out ) const { - out.emplace_back ( "rules", sax::Token::TokenType::START_ELEMENT ); - - for ( const auto & rule : this->getRules ( ) ) - - for ( const auto & rhs : rule.second ) { - out.emplace_back ( "rule", sax::Token::TokenType::START_ELEMENT ); - - GrammarToXMLComposer::composeRuleLHS ( out, rule.first ); - GrammarToXMLComposer::composeRuleRHS ( out, rhs ); - - out.emplace_back ( "rule", sax::Token::TokenType::END_ELEMENT ); - } - - out.emplace_back ( "rules", sax::Token::TokenType::END_ELEMENT ); -} - -} /* namespace grammar */ - namespace alib { -auto nonContractingGrammarParserRegister = xmlApi < grammar::Grammar >::ParserRegister < grammar::NonContractingGrammar > ( ); -auto nonContractingGrammarParserRegister2 = xmlApi < alib::Object >::ParserRegister < grammar::NonContractingGrammar > ( ); +auto nonContractingGrammarParserRegister = xmlApi < grammar::Grammar >::ParserRegister < grammar::NonContractingGrammar < > > ( ); +auto nonContractingGrammarParserRegister2 = xmlApi < alib::Object >::ParserRegister < grammar::NonContractingGrammar < > > ( ); } /* namespace alib */ diff --git a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h index b30706d6daf278d2a42af0d6363c308644721d3d..5fda40f728fe67cd47ea3a53e9d9d7fe93761055 100644 --- a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h +++ b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h @@ -8,12 +8,19 @@ #ifndef NON_CONTRACTING_GRAMMAR_H_ #define NON_CONTRACTING_GRAMMAR_H_ -#include "../GrammarException.h" -#include "../GrammarBase.h" #include <map> #include <vector> +#include <algorithm> +#include <sstream> + #include <core/components.hpp> -#include "../../alphabet/Symbol.h" +#include <sax/FromXMLParserHelper.h> + +#include "../GrammarBase.h" +#include "../GrammarFeatures.h" +#include "../GrammarException.h" +#include "../common/GrammarFromXMLParser.h" +#include "../common/GrammarToXMLComposer.h" namespace grammar { @@ -24,55 +31,56 @@ class TerminalAlphabet; class NonterminalAlphabet; class InitialSymbol; -class NonContractingGrammar : public GrammarBase, public std::Components < NonContractingGrammar, alphabet::Symbol, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { - std::map < std::vector < alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > > rules; +template < class SymbolType > +class NonContractingGrammar : public GrammarBase, public std::Components < NonContractingGrammar < SymbolType >, SymbolType, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > { + std::map < std::vector < SymbolType >, std::set < std::vector < SymbolType > > > rules; bool generatesEpsilon; public: - explicit NonContractingGrammar ( alphabet::Symbol initialSymbol ); + explicit NonContractingGrammar ( SymbolType initialSymbol ); - explicit NonContractingGrammar ( std::set < alphabet::Symbol > nonTerminalSymbols, std::set < alphabet::Symbol > terminalSymbols, alphabet::Symbol initialSymbol ); + explicit NonContractingGrammar ( std::set < SymbolType > nonTerminalSymbols, std::set < SymbolType > terminalSymbols, SymbolType initialSymbol ); virtual GrammarBase * clone ( ) const; virtual GrammarBase * plunder ( ) &&; - bool addRule ( std::vector < alphabet::Symbol > leftHandSide, std::vector < alphabet::Symbol > rightHandSide ); + bool addRule ( std::vector < SymbolType > leftHandSide, std::vector < SymbolType > rightHandSide ); - const std::map < std::vector < alphabet::Symbol >, std::set < std::vector < alphabet::Symbol > > > & getRules ( ) const; + const std::map < std::vector < SymbolType >, std::set < std::vector < SymbolType > > > & getRules ( ) const; - bool removeRule ( const std::vector < alphabet::Symbol > & leftHandSide, const std::vector < alphabet::Symbol > & rightHandSide ); + bool removeRule ( const std::vector < SymbolType > & leftHandSide, const std::vector < SymbolType > & rightHandSide ); - const alphabet::Symbol & getInitialSymbol ( ) const { - return accessElement < InitialSymbol > ( ).get ( ); + const SymbolType & getInitialSymbol ( ) const { + return this->template accessElement < InitialSymbol > ( ).get ( ); } - bool setInitialSymbol ( alphabet::Symbol symbol ) { - return accessElement < InitialSymbol > ( ).set ( std::move ( symbol ) ); + bool setInitialSymbol ( SymbolType symbol ) { + return this->template accessElement < InitialSymbol > ( ).set ( std::move ( symbol ) ); } - const std::set < alphabet::Symbol > & getNonterminalAlphabet ( ) const { - return accessComponent < NonterminalAlphabet > ( ).get ( ); + const std::set < SymbolType > & getNonterminalAlphabet ( ) const { + return this->template accessComponent < NonterminalAlphabet > ( ).get ( ); } - bool addNonterminalSymbol ( alphabet::Symbol symbol ) { - return accessComponent < NonterminalAlphabet > ( ).add ( std::move ( symbol ) ); + bool addNonterminalSymbol ( SymbolType symbol ) { + return this->template accessComponent < NonterminalAlphabet > ( ).add ( std::move ( symbol ) ); } - void setNonterminalAlphabet ( std::set < alphabet::Symbol > symbols ) { - accessComponent < NonterminalAlphabet > ( ).set ( std::move ( symbols ) ); + void setNonterminalAlphabet ( std::set < SymbolType > symbols ) { + this->template accessComponent < NonterminalAlphabet > ( ).set ( std::move ( symbols ) ); } - const std::set < alphabet::Symbol > & getTerminalAlphabet ( ) const { - return accessComponent < TerminalAlphabet > ( ).get ( ); + const std::set < SymbolType > & getTerminalAlphabet ( ) const { + return this->template accessComponent < TerminalAlphabet > ( ).get ( ); } - bool addTerminalSymbol ( alphabet::Symbol symbol ) { - return accessComponent < TerminalAlphabet > ( ).add ( std::move ( symbol ) ); + bool addTerminalSymbol ( SymbolType symbol ) { + return this->template accessComponent < TerminalAlphabet > ( ).add ( std::move ( symbol ) ); } - void setTerminalAlphabet ( std::set < alphabet::Symbol > symbols ) { - accessComponent < TerminalAlphabet > ( ).set ( std::move ( symbols ) ); + void setTerminalAlphabet ( std::set < SymbolType > symbols ) { + this->template accessComponent < TerminalAlphabet > ( ).set ( std::move ( symbols ) ); } void setGeneratesEpsilon ( bool genEps ); @@ -103,19 +111,169 @@ public: void composeRules ( std::deque < sax::Token > & out ) const; }; +template < class SymbolType > +NonContractingGrammar < SymbolType >::NonContractingGrammar ( SymbolType initialSymbol ) : NonContractingGrammar ( std::set < SymbolType > { initialSymbol }, std::set < SymbolType > ( ), initialSymbol ) { +} + +template < class SymbolType > +NonContractingGrammar < SymbolType >::NonContractingGrammar ( std::set < SymbolType > nonterminalAlphabet, std::set < SymbolType > terminalAlphabet, SymbolType initialSymbol ) : std::Components < NonContractingGrammar, SymbolType, std::tuple < TerminalAlphabet, NonterminalAlphabet >, std::tuple < InitialSymbol > > ( std::make_tuple ( std::move ( terminalAlphabet ), std::move ( nonterminalAlphabet ) ), std::make_tuple ( std::move ( initialSymbol ) ) ), generatesEpsilon ( false ) { +} + +template < class SymbolType > +GrammarBase * NonContractingGrammar < SymbolType >::clone ( ) const { + return new NonContractingGrammar ( * this ); +} + +template < class SymbolType > +GrammarBase * NonContractingGrammar < SymbolType >::plunder ( ) && { + return new NonContractingGrammar ( std::move ( * this ) ); +} + +template < class SymbolType > +bool NonContractingGrammar < SymbolType >::addRule ( std::vector < SymbolType > leftHandSide, std::vector < SymbolType > rightHandSide ) { + int lSize = leftHandSide.size ( ); + int rSize = rightHandSide.size ( ); + + if ( lSize > rSize ) + throw GrammarException ( "Invalid size of right hand side of a rule" ); + + if ( std::all_of ( leftHandSide.begin ( ), leftHandSide.end ( ), [this] ( const SymbolType symbol ) { + return !getNonterminalAlphabet ( ).count ( symbol ); + } ) ) + throw GrammarException ( "Rule must rewrite nonterminal symbol" ); + + for ( const SymbolType & symbol : leftHandSide ) + if ( !getTerminalAlphabet ( ).count ( symbol ) && !getNonterminalAlphabet ( ).count ( symbol ) ) + throw GrammarException ( "Symbol \"" + std::to_string ( symbol ) + "\" is not neither terminal nor nonterminal symbol" ); + + for ( const SymbolType & symbol : rightHandSide ) + if ( !getTerminalAlphabet ( ).count ( symbol ) && !getNonterminalAlphabet ( ).count ( symbol ) ) + throw GrammarException ( "Symbol \"" + std::to_string ( symbol ) + "\" is not neither terminal nor nonterminal symbol" ); + + return rules[std::move ( leftHandSide )].insert ( std::move ( rightHandSide ) ).second; +} + +template < class SymbolType > +const std::map < std::vector < SymbolType >, std::set < std::vector < SymbolType > > > & NonContractingGrammar < SymbolType >::getRules ( ) const { + return rules; +} + +template < class SymbolType > +bool NonContractingGrammar < SymbolType >::removeRule ( const std::vector < SymbolType > & leftHandSide, const std::vector < SymbolType > & rightHandSide ) { + return rules[leftHandSide].erase ( rightHandSide ); +} + +template < class SymbolType > +void NonContractingGrammar < SymbolType >::setGeneratesEpsilon ( bool genEps ) { + generatesEpsilon = genEps; +} + +template < class SymbolType > +bool NonContractingGrammar < SymbolType >::getGeneratesEpsilon ( ) const { + return generatesEpsilon; +} + +template < class SymbolType > +int NonContractingGrammar < SymbolType >::compare ( const NonContractingGrammar & other ) const { + auto first = std::tie ( getTerminalAlphabet ( ), getNonterminalAlphabet ( ), getInitialSymbol ( ), rules ); + auto second = std::tie ( other.getTerminalAlphabet ( ), other.getNonterminalAlphabet ( ), other.getInitialSymbol ( ), other.rules ); + + std::compare < decltype ( first ) > comp; + + return comp ( first, second ); +} + +template < class SymbolType > +void NonContractingGrammar < SymbolType >::operator >>( std::ostream & out ) const { + out << "(NonContractingGrammar " + << "nonterminalAlphabet = " << getNonterminalAlphabet ( ) + << "terminalAlphabet = " << getTerminalAlphabet ( ) + << "initialSymbol = " << getInitialSymbol ( ) + << "rules = " << rules + << "generatesEpsilon = " << generatesEpsilon << ")"; +} + +template < class SymbolType > +NonContractingGrammar < SymbolType >::operator std::string ( ) const { + std::stringstream ss; + ss << * this; + return ss.str ( ); +} + +template < class SymbolType > +NonContractingGrammar < SymbolType > NonContractingGrammar < SymbolType >::parse ( std::deque < sax::Token >::iterator & input ) { + sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, NonContractingGrammar::getXmlTagName() ); + + std::set < SymbolType > nonterminalAlphabet = GrammarFromXMLParser::parseNonterminalAlphabet ( input ); + std::set < SymbolType > terminalAlphabet = GrammarFromXMLParser::parseTerminalAlphabet ( input ); + SymbolType initialSymbol = GrammarFromXMLParser::parseInitialSymbol ( input ); + + NonContractingGrammar < SymbolType > grammar ( std::move ( initialSymbol ) ); + + grammar.setNonterminalAlphabet ( std::move ( nonterminalAlphabet ) ); + grammar.setTerminalAlphabet ( std::move ( terminalAlphabet ) ); + + GrammarFromXMLParser::parseRules ( input, grammar ); + + bool generatesEpsilon = GrammarFromXMLParser::parseGeneratesEpsilon ( input ); + grammar.setGeneratesEpsilon ( generatesEpsilon ); + + sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, NonContractingGrammar::getXmlTagName() ); + return grammar; +} + +template < class SymbolType > +void NonContractingGrammar < SymbolType >::parseRule ( std::deque < sax::Token >::iterator & input, NonContractingGrammar & grammar ) { + std::vector < SymbolType > lhs = GrammarFromXMLParser::parseRuleLHS ( input ); + std::vector < SymbolType > rhs = GrammarFromXMLParser::parseRuleRHS ( input ); + + grammar.addRule ( std::move ( lhs ), std::move ( rhs ) ); +} + +template < class SymbolType > +void NonContractingGrammar < SymbolType >::compose ( std::deque < sax::Token > & out ) const { + out.emplace_back ( NonContractingGrammar::getXmlTagName(), sax::Token::TokenType::START_ELEMENT ); + + GrammarToXMLComposer::composeNonterminalAlphabet ( out, this->getNonterminalAlphabet ( ) ); + GrammarToXMLComposer::composeTerminalAlphabet ( out, this->getTerminalAlphabet ( ) ); + GrammarToXMLComposer::composeInitialSymbol ( out, this->getInitialSymbol ( ) ); + composeRules ( out ); + GrammarToXMLComposer::composeGeneratesEpsilon ( out, this->getGeneratesEpsilon ( ) ); + + out.emplace_back ( NonContractingGrammar::getXmlTagName(), sax::Token::TokenType::END_ELEMENT ); +} + +template < class SymbolType > +void NonContractingGrammar < SymbolType >::composeRules ( std::deque < sax::Token > & out ) const { + out.emplace_back ( "rules", sax::Token::TokenType::START_ELEMENT ); + + for ( const auto & rule : this->getRules ( ) ) + + for ( const auto & rhs : rule.second ) { + out.emplace_back ( "rule", sax::Token::TokenType::START_ELEMENT ); + + GrammarToXMLComposer::composeRuleLHS ( out, rule.first ); + GrammarToXMLComposer::composeRuleRHS ( out, rhs ); + + out.emplace_back ( "rule", sax::Token::TokenType::END_ELEMENT ); + } + + out.emplace_back ( "rules", sax::Token::TokenType::END_ELEMENT ); +} + } /* namespace grammar */ namespace std { -template < > -class ComponentConstraint< grammar::NonContractingGrammar, alphabet::Symbol, grammar::TerminalAlphabet > { +template < class SymbolType > +class ComponentConstraint< grammar::NonContractingGrammar < SymbolType >, SymbolType, 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 ( ) ) { + static bool used ( const grammar::NonContractingGrammar < SymbolType > & grammar, const SymbolType & symbol ) { + for ( const std::pair < const std::vector < SymbolType >, std::set < std::vector < SymbolType > > > & 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 ) + for ( const std::vector < SymbolType > & rhs : rule.second ) if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) return true; @@ -124,54 +282,54 @@ public: return false; } - static bool available ( const grammar::NonContractingGrammar &, const alphabet::Symbol & ) { + static bool available ( const grammar::NonContractingGrammar < SymbolType > &, const SymbolType & ) { return true; } - static void valid ( const grammar::NonContractingGrammar & grammar, const alphabet::Symbol & symbol ) { - if ( grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + static void valid ( const grammar::NonContractingGrammar < SymbolType > & grammar, const SymbolType & symbol ) { + if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) throw grammar::GrammarException ( "Symbol " + std::to_string ( symbol ) + "cannot be in terminal alphabet since it is already nonterminal alphabet" ); } }; -template < > -class ComponentConstraint< grammar::NonContractingGrammar, alphabet::Symbol, grammar::NonterminalAlphabet > { +template < class SymbolType > +class ComponentConstraint< grammar::NonContractingGrammar < SymbolType >, SymbolType, 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 ( ) ) { + static bool used ( const grammar::NonContractingGrammar < SymbolType > & grammar, const SymbolType & symbol ) { + for ( const std::pair < const std::vector < SymbolType >, std::set < std::vector < SymbolType > > > & 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 ) + for ( const std::vector < SymbolType > & rhs : rule.second ) if ( std::find ( rhs.begin ( ), rhs.end ( ), symbol ) != rhs.end ( ) ) return true; } - if ( grammar.accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) + if ( grammar.template accessElement < grammar::InitialSymbol > ( ).get ( ) == symbol ) return true; return false; } - static bool available ( const grammar::NonContractingGrammar &, const alphabet::Symbol & ) { + static bool available ( const grammar::NonContractingGrammar < SymbolType > &, const SymbolType & ) { return true; } - static void valid ( const grammar::NonContractingGrammar & grammar, const alphabet::Symbol & symbol ) { - if ( grammar.accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + static void valid ( const grammar::NonContractingGrammar < SymbolType > & grammar, const SymbolType & symbol ) { + if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) throw grammar::GrammarException ( "Symbol " + std::to_string ( symbol ) + "cannot be in nonterminal alphabet since it is already in terminal alphabet" ); } }; -template < > -class ElementConstraint< grammar::NonContractingGrammar, alphabet::Symbol, grammar::InitialSymbol > { +template < class SymbolType > +class ElementConstraint< grammar::NonContractingGrammar < SymbolType >, SymbolType, grammar::InitialSymbol > { public: - static bool available ( const grammar::NonContractingGrammar & grammar, const alphabet::Symbol & symbol ) { - return grammar.accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); + static bool available ( const grammar::NonContractingGrammar < SymbolType > & grammar, const SymbolType & symbol ) { + return grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ); } - static void valid ( const grammar::NonContractingGrammar &, const alphabet::Symbol & ) { + static void valid ( const grammar::NonContractingGrammar < SymbolType > &, const SymbolType & ) { } }; diff --git a/alib2data/src/grammar/GrammarFeatures.h b/alib2data/src/grammar/GrammarFeatures.h index 419bad2d0e7a51962a40dd0d9fc3e6502fbbe70f..1766b7af7ba7bec966b8c3d806db95bf7e109366 100644 --- a/alib2data/src/grammar/GrammarFeatures.h +++ b/alib2data/src/grammar/GrammarFeatures.h @@ -47,6 +47,7 @@ template<class SymbolType = typename alphabet::Symbol > class GNF; template<class SymbolType = typename alphabet::Symbol > class CSG; +template<class SymbolType = typename alphabet::Symbol > class NonContractingGrammar; class ContextPreservingUnrestrictedGrammar; class UnrestrictedGrammar; diff --git a/alib2data/test-src/grammar/GrammarTest.cpp b/alib2data/test-src/grammar/GrammarTest.cpp index 4b7be9783631aa27a72eaecec7071211fb2413ca..dc95098a0d2b10caba9f993528479f67211631b5 100644 --- a/alib2data/test-src/grammar/GrammarTest.cpp +++ b/alib2data/test-src/grammar/GrammarTest.cpp @@ -321,7 +321,7 @@ void GrammarTest::testContextSensitiveParser() { } } { - grammar::NonContractingGrammar grammar(alphabet::symbolFrom(1)); + grammar::NonContractingGrammar < > grammar(alphabet::symbolFrom(1)); grammar.addNonterminalSymbol(alphabet::symbolFrom(1)); grammar.addNonterminalSymbol(alphabet::symbolFrom(2)); @@ -342,7 +342,7 @@ void GrammarTest::testContextSensitiveParser() { std::deque<sax::Token> tokens2; sax::SaxParseInterface::parseMemory(tmp, tokens2); - grammar::NonContractingGrammar grammar2 = alib::XmlDataFactory::fromTokens<grammar::NonContractingGrammar>(std::move(tokens2)); + grammar::NonContractingGrammar < > grammar2 = alib::XmlDataFactory::fromTokens<grammar::NonContractingGrammar < > >(std::move(tokens2)); CPPUNIT_ASSERT( grammar == grammar2 ); } diff --git a/alib2str/src/grammar/GrammarFromStringParser.cpp b/alib2str/src/grammar/GrammarFromStringParser.cpp index 1edd8523a08c70b324050e04dceb338f2095bd1c..267ab49c81c80154600e2d8495349bca0529d305 100644 --- a/alib2str/src/grammar/GrammarFromStringParser.cpp +++ b/alib2str/src/grammar/GrammarFromStringParser.cpp @@ -530,13 +530,13 @@ CNF < > GrammarFromStringParser::parseCNF(std::istream& input) const { return parseCFLikeGrammar<CNF < > >(input); } -NonContractingGrammar GrammarFromStringParser::parseNonContractingGrammar(std::istream& input) const { +NonContractingGrammar < > GrammarFromStringParser::parseNonContractingGrammar(std::istream& input) const { GrammarFromStringLexer::Token token = m_GrammarLexer.next(input); if(token.type != GrammarFromStringLexer::TokenType::NON_CONTRACTING_GRAMMAR) { throw exception::CommonException("Unrecognised NonContractingGrammar token."); } - return parseCSLikeGrammar<NonContractingGrammar>(input); + return parseCSLikeGrammar<NonContractingGrammar < > >(input); } CSG < > GrammarFromStringParser::parseCSG(std::istream& input) const { diff --git a/alib2str/src/grammar/GrammarFromStringParser.h b/alib2str/src/grammar/GrammarFromStringParser.h index 0a5d954a0e7940eafd2b7c9c531f3bb33d48845d..86256c3c066ed75d868a48ab3ef809bbbc3f42d3 100644 --- a/alib2str/src/grammar/GrammarFromStringParser.h +++ b/alib2str/src/grammar/GrammarFromStringParser.h @@ -56,7 +56,7 @@ private: GNF < > parseGNF(std::istream& input) const; CNF < > parseCNF(std::istream& input) const; - NonContractingGrammar parseNonContractingGrammar(std::istream& input) const; + NonContractingGrammar < > parseNonContractingGrammar(std::istream& input) const; CSG < > parseCSG(std::istream& input) const; ContextPreservingUnrestrictedGrammar parseContextPreservingUnrestrictedGrammar(std::istream& input) const; UnrestrictedGrammar parseUnrestrictedGrammar(std::istream& input) const; diff --git a/alib2str/src/grammar/GrammarToStringComposer.cpp b/alib2str/src/grammar/GrammarToStringComposer.cpp index b8b8880c05fc023c78414d978769c0a34c8f89d6..d71221084f0b5d3bdd39d7b1d26f862e9554d000 100644 --- a/alib2str/src/grammar/GrammarToStringComposer.cpp +++ b/alib2str/src/grammar/GrammarToStringComposer.cpp @@ -254,12 +254,12 @@ void GrammarToStringComposer::compose(std::ostream& output, const CSG < > & gram GrammarToStringComposer::RegistratorWrapper<void, CSG < > > GrammarToStringComposerCSG = GrammarToStringComposer::RegistratorWrapper<void, CSG < > >(GrammarToStringComposer::compose); -void GrammarToStringComposer::compose(std::ostream& output, const NonContractingGrammar& grammar) { +void GrammarToStringComposer::compose(std::ostream& output, const NonContractingGrammar < > & grammar) { output << "NON_CONTRACTING_GRAMMAR"; composeCSLikeGrammar(output, grammar); } -GrammarToStringComposer::RegistratorWrapper<void, NonContractingGrammar> GrammarToStringComposerNonContractingGrammar = GrammarToStringComposer::RegistratorWrapper<void, NonContractingGrammar>(GrammarToStringComposer::compose); +GrammarToStringComposer::RegistratorWrapper<void, NonContractingGrammar < > > GrammarToStringComposerNonContractingGrammar = GrammarToStringComposer::RegistratorWrapper<void, NonContractingGrammar < > >(GrammarToStringComposer::compose); void GrammarToStringComposer::compose(std::ostream& output, const ContextPreservingUnrestrictedGrammar& grammar) { output << "CONTEXT_PRESERVING_UNRESTRICTED_GRAMMAR"; diff --git a/alib2str/src/grammar/GrammarToStringComposer.h b/alib2str/src/grammar/GrammarToStringComposer.h index 1b6a2c888f05691d19045b2d011346a4f985b061..0d30cfe12550986d6f4276fd3d91b425ffc26b30 100644 --- a/alib2str/src/grammar/GrammarToStringComposer.h +++ b/alib2str/src/grammar/GrammarToStringComposer.h @@ -34,7 +34,7 @@ public: static void compose(std::ostream& output, const CNF < > & grammar); static void compose(std::ostream& output, const GNF < > & grammar); static void compose(std::ostream& output, const CSG < > & grammar); - static void compose(std::ostream& output, const NonContractingGrammar& grammar); + static void compose(std::ostream& output, const NonContractingGrammar < > & grammar); static void compose(std::ostream& output, const ContextPreservingUnrestrictedGrammar& grammar); static void compose(std::ostream& output, const UnrestrictedGrammar& grammar); };