diff --git a/alib2algo/src/grammar/generate/GenerateUpToLength.h b/alib2algo/src/grammar/generate/GenerateUpToLength.h index b8595b9df6773308602d2e5601967b5a0f36f84e..ab6cdd066bf99eb886d3c92b620acbd66093a3aa 100644 --- a/alib2algo/src/grammar/generate/GenerateUpToLength.h +++ b/alib2algo/src/grammar/generate/GenerateUpToLength.h @@ -19,6 +19,8 @@ #include <grammar/Regular/LeftRG.h> #include <grammar/Regular/RightRG.h> +#include <grammar/RawRules.h> + namespace grammar { namespace generate { @@ -36,7 +38,7 @@ template < class T, class SymbolType > ext::set < string::LinearString < SymbolType > > GenerateUpToLength::generate ( const T & grammar, unsigned length ) { ext::set < string::LinearString < SymbolType > > res; - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > rules = grammar.getRawRules(); + ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > rules = grammar::RawRules::getRawRules ( grammar ); if ( grammar.getGeneratesEpsilon ( ) ) { res.insert ( string::LinearString < SymbolType > { } ); rules [ grammar.getInitialSymbol ( ) ].erase ( ext::vector < SymbolType > { } ); diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h index f355f7d9510dda3e5c2793459b611b7548578ab3..35040e65fbdb42c1aba065eaf9ddd0a44cfaa175 100644 --- a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h +++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h @@ -13,6 +13,8 @@ #include <exception/CommonException.h> +#include <grammar/RawRules.h> + namespace grammar { namespace properties { @@ -41,13 +43,15 @@ ext::set<SymbolType> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const throw exception::CommonException("Nonterminal symbol \"" + ext::to_string ( nonterminal ) + "\" is not present in grammar."); } + auto rawRules = grammar::RawRules::getRawRules ( grammar ); + ext::deque<ext::set<SymbolType>> Ni; Ni.push_back(ext::set<SymbolType>{nonterminal}); int i = 1; while(true) { Ni.push_back(Ni.at(i-1)); - for(const auto &rule : grammar.getRawRules()) { + for ( const auto & rule : rawRules ) { const SymbolType& lhs = rule.first; for(const auto& rhs : rule.second) { diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.h b/alib2algo/src/grammar/properties/NullableNonterminals.h index f4fd694e8018c391620826b23637ac647060b48e..d0446cfa6afee96f32795f12323e6a67dd1f110e 100644 --- a/alib2algo/src/grammar/properties/NullableNonterminals.h +++ b/alib2algo/src/grammar/properties/NullableNonterminals.h @@ -14,6 +14,8 @@ #include <grammar/Grammar.h> +#include <grammar/RawRules.h> + namespace grammar { namespace properties { @@ -38,6 +40,8 @@ public: template<class T, class SymbolType > ext::set<SymbolType> NullableNonterminals::getNullableNonterminals(const T& grammar) { + auto rawRules = grammar::RawRules::getRawRules ( grammar ); + ext::deque<ext::set<SymbolType>> Ni; Ni.push_back(ext::set<SymbolType>{ }); @@ -45,7 +49,7 @@ ext::set<SymbolType> NullableNonterminals::getNullableNonterminals(const T& gram while(true) { Ni.push_back(ext::set<SymbolType>{ }); - for(const auto& rule : grammar.getRawRules()) { + for ( const auto & rule : rawRules ) { for(const auto& rhs : rule.second) { if(rhs.size() == 0 || std::all_of(rhs.begin(), rhs.end(), [Ni, i](const SymbolType& symb){return Ni.at(i-1).count(symb);})) { Ni.at(i).insert(rule.first); diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.h b/alib2algo/src/grammar/properties/ProductiveNonterminals.h index 8a394c2d82f4a4b75b118f0a6acb53496bc96f06..b70b7077a0191664a54a6e07a4b0f47d6548b174 100644 --- a/alib2algo/src/grammar/properties/ProductiveNonterminals.h +++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.h @@ -14,6 +14,8 @@ #include <grammar/Grammar.h> +#include <grammar/RawRules.h> + namespace grammar { namespace properties { @@ -32,6 +34,8 @@ public: template<class T, class SymbolType > ext::set<SymbolType> ProductiveNonterminals::getProductiveNonterminals( const T & grammar ) { + auto rawRules = grammar::RawRules::getRawRules ( grammar ); + // 1. ext::deque<ext::set<SymbolType>> Ni; Ni.push_back( ext::set<SymbolType>( ) ); @@ -42,7 +46,7 @@ ext::set<SymbolType> ProductiveNonterminals::getProductiveNonterminals( const T while( true ) { Ni.push_back( Ni.at( i - 1 ) ); - for( const auto & rule : grammar.getRawRules( ) ) { + for( const auto & rule : rawRules ) { for( const auto & rhs : rule.second ) { if( std::all_of( rhs.begin( ), rhs.end( ), [ i, Ni, grammar ]( const SymbolType & symbol ) -> bool { return Ni.at( i - 1 ) . count( symbol ) || grammar.getTerminalAlphabet( ). count( symbol ); diff --git a/alib2algo/src/grammar/properties/RecursiveNonterminal.h b/alib2algo/src/grammar/properties/RecursiveNonterminal.h index 63839bd182f9ba0456960b64c8583bc80b01db26..4add4074b4243baaad1d3197357ac4e0762742ec 100644 --- a/alib2algo/src/grammar/properties/RecursiveNonterminal.h +++ b/alib2algo/src/grammar/properties/RecursiveNonterminal.h @@ -15,6 +15,8 @@ #include <exception/CommonException.h> +#include <grammar/RawRules.h> + namespace grammar { namespace properties { @@ -45,7 +47,7 @@ bool RecursiveNonterminal::isNonterminalRecursive ( const T & grammar, const Sym Ni.push_back ( ext::set < SymbolType > { nonterminal } ); unsigned i = 1; - auto rawRules = grammar.getRawRules ( ); + auto rawRules = grammar::RawRules::getRawRules ( grammar ); auto nullable = grammar::properties::NullableNonterminals::getNullableNonterminals ( grammar ); while ( i <= grammar.getNonterminalAlphabet ( ).size ( ) ) { diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.h b/alib2algo/src/grammar/properties/UnreachableSymbols.h index df052b812e64f281d42d9be606d17d421e1a5b60..8cf54ffd3ddfd54c63006d2397b19c5f474452f7 100644 --- a/alib2algo/src/grammar/properties/UnreachableSymbols.h +++ b/alib2algo/src/grammar/properties/UnreachableSymbols.h @@ -14,6 +14,8 @@ #include <grammar/Grammar.h> +#include <grammar/RawRules.h> + namespace grammar { namespace properties { @@ -32,6 +34,8 @@ public: template<class T, class SymbolType > ext::set<DefaultSymbolType> UnreachableSymbols::getUnreachableSymbols( const T & grammar ) { + auto rawRules = grammar::RawRules::getRawRules ( grammar ); + // 1 ext::deque<ext::set<DefaultSymbolType>> Vi; Vi.push_back( ext::set<DefaultSymbolType>( ) ); @@ -43,7 +47,7 @@ ext::set<DefaultSymbolType> UnreachableSymbols::getUnreachableSymbols( const T & while( true ) { Vi.push_back( Vi.at( i - 1 ) ); - for( const auto & rule : grammar.getRawRules( ) ) { + for( const auto & rule : rawRules ) { if( Vi.at( i - 1 ).count( rule.first ) ) { for( const auto & rhs : rule.second ) { Vi.at( i ).insert( rhs.begin( ), rhs.end( ) ); diff --git a/alib2algo/src/grammar/simplify/EpsilonRemover.h b/alib2algo/src/grammar/simplify/EpsilonRemover.h index 775ee0543844556b4a954bd8500964d37f673bd6..d01d2611bc56f6f4c42308b41cf91955c1eed986 100644 --- a/alib2algo/src/grammar/simplify/EpsilonRemover.h +++ b/alib2algo/src/grammar/simplify/EpsilonRemover.h @@ -25,6 +25,8 @@ #include <grammar/properties/NullableNonterminals.h> +#include <grammar/RawRules.h> + namespace grammar { namespace simplify { @@ -83,7 +85,9 @@ grammar::EpsilonFreeCFG < SymbolType > EpsilonRemover::removeInternal( const T & ext::set<SymbolType> nullableNonterminals = grammar::properties::NullableNonterminals::getNullableNonterminals(origGrammar); - for( const auto & rule : origGrammar.getRawRules( ) ) + auto rawRules = grammar::RawRules::getRawRules ( origGrammar ); + + for( const auto & rule : rawRules ) for(const auto & rhs : rule.second) { if(rhs.size() == 0) continue; diff --git a/alib2algo/src/grammar/simplify/SimpleRulesRemover.h b/alib2algo/src/grammar/simplify/SimpleRulesRemover.h index 7904e04aef0ea92106e18fe0001ce727233ef4df..b5fbd9c303481ee138c2fe970ee42e274731629d 100644 --- a/alib2algo/src/grammar/simplify/SimpleRulesRemover.h +++ b/alib2algo/src/grammar/simplify/SimpleRulesRemover.h @@ -24,6 +24,9 @@ #include <grammar/Grammar.h> +#include <grammar/RawRules.h> +#include <grammar/AddRawRule.h> + namespace grammar { namespace simplify { @@ -63,15 +66,15 @@ T SimpleRulesRemover::removeNonEpsilonFree( const T & origGrammar ) { for( const auto & symbol : origGrammar.getTerminalAlphabet() ) grammar.addTerminalSymbol( symbol ); - auto origRules = origGrammar.getRawRules(); + auto rawRules = grammar::RawRules::getRawRules ( origGrammar ); for( const auto & symbol : origGrammar.getNonterminalAlphabet() ) { ext::set<SymbolType> simpleRulesClosure = grammar::properties::NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(origGrammar, symbol); for( const auto & closureSymbol : simpleRulesClosure ) { - auto rules = origRules.find(closureSymbol); - if(rules != origRules.end()) for( const auto& rawRule : rules->second ) { + auto rules = rawRules.find(closureSymbol); + if(rules != rawRules.end()) for( const auto& rawRule : rules->second ) { if(rawRule.size() == 0 || (rawRule.size() == 1 && !origGrammar.getNonterminalAlphabet().count(rawRule[0])) || rawRule.size() >= 2) - grammar.addRawRule(symbol, rawRule); + grammar::AddRawRule::addRawRule ( grammar, symbol, rawRule); } } } diff --git a/alib2algo/src/grammar/simplify/ToCNF.cpp b/alib2algo/src/grammar/simplify/ToCNF.cpp index b5d5ff21eeeebf02e1f560c0e39383fb386f9f88..3b5fc083ac040c715269a5f9e4a866f00a304a62 100644 --- a/alib2algo/src/grammar/simplify/ToCNF.cpp +++ b/alib2algo/src/grammar/simplify/ToCNF.cpp @@ -14,6 +14,9 @@ #include <common/createUnique.hpp> #include <registration/AlgoRegistration.hpp> +#include <grammar/RawRules.h> +#include <grammar/AddRawRule.h> + namespace grammar { namespace simplify { @@ -31,7 +34,7 @@ ext::pair<DefaultSymbolType, DefaultSymbolType> splitToPairs(T& grammar, const e createdSymbols.insert(std::make_pair(secondProposal, common::createUnique(secondProposal, grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet()))); } grammar.addNonterminalSymbol(createdSymbols.find(secondProposal)->second); - grammar.addRawRule(createdSymbols.find(secondProposal)->second, {std::move(second.first), std::move(second.second)}); + grammar::AddRawRule::addRawRule(grammar,createdSymbols.find(secondProposal)->second, {std::move(second.first), std::move(second.second)}); return ext::make_pair(std::move(firstLhs), createdSymbols.find(secondProposal)->second); } else { @@ -41,7 +44,7 @@ ext::pair<DefaultSymbolType, DefaultSymbolType> splitToPairs(T& grammar, const e createdSymbols.insert(std::make_pair(firstProposal, common::createUnique(firstProposal, grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet()))); } grammar.addNonterminalSymbol(createdSymbols.find(firstProposal)->second); - grammar.addRawRule(createdSymbols.find(firstProposal)->second, {std::move(first.first), std::move(first.second)}); + grammar::AddRawRule::addRawRule ( grammar, createdSymbols.find(firstProposal)->second, {std::move(first.first), std::move(first.second)}); auto second = splitToPairs(grammar, rhs, from + size / 2, size - size / 2, createdSymbols); DefaultSymbolType secondProposal{DefaultSymbolsPairType(second)}; @@ -49,7 +52,7 @@ ext::pair<DefaultSymbolType, DefaultSymbolType> splitToPairs(T& grammar, const e createdSymbols.insert(std::make_pair(secondProposal, common::createUnique(secondProposal, grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet()))); } grammar.addNonterminalSymbol(createdSymbols.find(secondProposal)->second); - grammar.addRawRule(createdSymbols.find(secondProposal)->second, {std::move(second.first), std::move(second.second)}); + grammar::AddRawRule::addRawRule(grammar,createdSymbols.find(secondProposal)->second, {std::move(second.first), std::move(second.second)}); return ext::make_pair(createdSymbols.find(firstProposal)->second, createdSymbols.find(secondProposal)->second); } @@ -63,14 +66,14 @@ grammar::CNF < > convertInternal( const T & origGrammar ) { grammarTmp.setTerminalAlphabet( origGrammar.getTerminalAlphabet() ); ext::map<DefaultSymbolType, DefaultSymbolType> createdSymbols; - auto origRules = origGrammar.getRawRules(); + auto origRules = grammar::RawRules::getRawRules(origGrammar); for( const auto & origRule : origRules ) { for( const auto& origRhs : origRule.second ) { if(origRhs.size() == 1 || origRhs.size() == 2) - grammarTmp.addRawRule(origRule.first, origRhs); + grammar::AddRawRule::addRawRule(grammarTmp,origRule.first, origRhs); else if(origRhs.size() > 2) { auto second = splitToPairs(grammarTmp, origRhs, 0, origRhs.size(), createdSymbols); - grammarTmp.addRawRule(origRule.first, {std::move(second.first), std::move(second.second)}); + grammar::AddRawRule::addRawRule(grammarTmp,origRule.first, {std::move(second.first), std::move(second.second)}); } } } @@ -90,25 +93,25 @@ grammar::CNF < > convertInternal( const T & origGrammar ) { grammar.addRule(std::move(shadowSymbol), symbol); } - auto tmpRules = grammarTmp.getRawRules(); + auto tmpRules = grammar::RawRules::getRawRules(grammarTmp); for( const auto & tmpRule : tmpRules ) { for( const auto& tmpRhs : tmpRule.second ) { if(tmpRhs.size() == 2) { if(grammarTmp.getNonterminalAlphabet().count(tmpRhs[0])) { if(grammarTmp.getNonterminalAlphabet().count(tmpRhs[1])) { - grammar.addRawRule(tmpRule.first, tmpRhs); + grammar::AddRawRule::addRawRule(grammar,tmpRule.first, tmpRhs); } else { - grammar.addRawRule(tmpRule.first, {tmpRhs[0], terminalToShadowNonterminal.find(tmpRhs[1])->second}); + grammar::AddRawRule::addRawRule(grammar,tmpRule.first, {tmpRhs[0], terminalToShadowNonterminal.find(tmpRhs[1])->second}); } } else { if(grammarTmp.getNonterminalAlphabet().count(tmpRhs[1])) { - grammar.addRawRule(tmpRule.first, {terminalToShadowNonterminal.find(tmpRhs[0])->second, tmpRhs[1]}); + grammar::AddRawRule::addRawRule(grammar,tmpRule.first, {terminalToShadowNonterminal.find(tmpRhs[0])->second, tmpRhs[1]}); } else { - grammar.addRawRule(tmpRule.first, {terminalToShadowNonterminal.find(tmpRhs[0])->second, terminalToShadowNonterminal.find(tmpRhs[1])->second }); + grammar::AddRawRule::addRawRule(grammar,tmpRule.first, {terminalToShadowNonterminal.find(tmpRhs[0])->second, terminalToShadowNonterminal.find(tmpRhs[1])->second }); } } } else // tmpRhs.size() == 1 - grammar.addRawRule(tmpRule.first, tmpRhs); + grammar::AddRawRule::addRawRule(grammar,tmpRule.first, tmpRhs); } } diff --git a/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h index 426c84e6c907f1f41e67c9c062bf0e52f0225d58..c815ce14d810eaaf1878129eb4d5b7c0321d396e 100644 --- a/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h +++ b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h @@ -22,6 +22,9 @@ #include <alib/algorithm> #include <grammar/properties/ProductiveNonterminals.h> +#include <grammar/RawRules.h> +#include <grammar/AddRawRule.h> + #include <exception/CommonException.h> namespace grammar { @@ -53,14 +56,16 @@ T UnproductiveSymbolsRemover::remove( const T & grammar ) { for( const auto & symbol : grammar.getTerminalAlphabet( ) ) ret.addTerminalSymbol( symbol ); + auto rawRules = grammar::RawRules::getRawRules ( grammar ); + const ext::set<SymbolType> & terminals = ret.getTerminalAlphabet( ); - for( const auto & rule : grammar.getRawRules( ) ) { + for( const auto & rule : rawRules ) { if( Nt.count( rule.first ) ) { for( const auto & rhs : rule.second ) { if( all_of( rhs.begin( ), rhs.end( ), [ Nt, terminals ]( const SymbolType & symbol ) { return Nt.count( symbol ) || terminals.count( symbol ); } ) ) - ret.addRawRule( rule.first, rhs ); + grammar::AddRawRule::addRawRule ( ret, rule.first, rhs ); } } } diff --git a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h index 4b7144d9f816b001e16b8b43e4f0cbbcc40c501d..b7b91e19ccf1b71c8effeccaf0a9cd1582385e11 100644 --- a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h +++ b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h @@ -23,6 +23,9 @@ #include <grammar/properties/UnreachableSymbols.h> +#include <grammar/RawRules.h> +#include <grammar/AddRawRule.h> + namespace grammar { namespace simplify { @@ -56,14 +59,16 @@ T UnreachableSymbolsRemover::remove( const T & grammar) { for( const auto & symbol : newTerminals ) ret.addTerminalSymbol( symbol ); + auto rawRules = grammar::RawRules::getRawRules ( grammar ); + // A->\alpha: if A \in N' and \alpha in V_i*, then A->\alpha in P - for( const auto & rule : grammar.getRawRules( ) ) { + for( const auto & rule : rawRules ) { if( newNonTerminals.count( rule.first ) ) { for( const auto& rhs : rule.second ) { if( all_of( rhs.begin( ), rhs.end( ), [ Vt ]( SymbolType const& symb ) -> bool { return Vt.count( symb ); } ) ) - ret.addRawRule( rule.first, rhs ); + grammar::AddRawRule::addRawRule ( ret, rule.first, rhs ); } } } diff --git a/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp index 5b1db35cb0758ae5d289b0a0bcd17281ca448339..cc47bb2c46ce867796617dc6bac8771443345180 100644 --- a/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp +++ b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp @@ -64,17 +64,17 @@ grammar::RightRG < > ToGrammarRightRGGlushkov::convert ( const regexp::Unbounded * add Rule: leftSide -> symbol.getSymbol( ) * unless it already exists */ - for ( const auto & rule : grammar.getRawRules ( ) ) { - for ( const auto & rhs : rule.second ) - for ( const regexp::UnboundedRegExpSymbol < ext::pair < DefaultSymbolType, unsigned > > & symbol : last ) { + for ( const auto & rule : grammar.getRules ( ) ) + for ( const auto & rhs : rule.second ) { + if ( ! rhs.is < ext::pair < DefaultSymbolType, DefaultSymbolType > > ( ) ) + continue; - const ext::pair < DefaultSymbolType, unsigned > & a = symbol.getSymbol ( ); + const ext::pair < DefaultSymbolType, DefaultSymbolType > & rawRhs = rhs.get < ext::pair < DefaultSymbolType, DefaultSymbolType > > ( ); - if ( std::find ( rhs.begin ( ), rhs.end ( ), DefaultSymbolType ( container::ObjectsPair < DefaultSymbolType, unsigned > ( a ) ) ) != rhs.end ( ) ) - grammar.addRule ( rule.first, rhs.at ( 0 ) ); - } - - } + for ( const regexp::UnboundedRegExpSymbol < ext::pair < DefaultSymbolType, unsigned > > & symbol : last ) + if ( rawRhs.second == DefaultSymbolType ( container::ObjectsPair < DefaultSymbolType, unsigned > ( symbol.getSymbol ( ) ) ) ) + grammar.addRule ( rule.first, rawRhs.first ); + } if ( regexp::properties::RegExpEpsilon::languageContainsEpsilon ( regexp ) ) grammar.setGeneratesEpsilon ( true ); diff --git a/alib2algo_experimental/src/grammar/parsing/First.h b/alib2algo_experimental/src/grammar/parsing/First.h index 8b24a2ace34451df05badcade6288983a119ce5c..21a53135f9f9fc27221af63fdd10eebd83e7bfdd 100644 --- a/alib2algo_experimental/src/grammar/parsing/First.h +++ b/alib2algo_experimental/src/grammar/parsing/First.h @@ -14,6 +14,7 @@ #include <string/Epsilon.h> #include <grammar/Grammar.h> +#include <grammar/RawRules.h> namespace grammar { @@ -101,11 +102,13 @@ ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < S template < class T, class SymbolType > ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > First::first ( const T & grammar ) { - ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) ); + auto rawRules = grammar::RawRules::getRawRules ( grammar ); + + ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), rawRules ); ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > res; - for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & rule : grammar.getRawRules ( ) ) + for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & rule : rawRules ) for ( const ext::vector < SymbolType > & rhs : rule.second ) res.insert ( std::make_pair ( rhs, first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), firstNt, rhs ) ) ); @@ -114,7 +117,9 @@ ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, str template < class T, class SymbolType > ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > First::first ( const T & grammar, const ext::vector < SymbolType > & rhs ) { - ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) ); + auto rawRules = grammar::RawRules::getRawRules ( grammar ); + + ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), rawRules ); return first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), firstNt, rhs ); } diff --git a/alib2algo_experimental/src/grammar/parsing/Follow.h b/alib2algo_experimental/src/grammar/parsing/Follow.h index 341b1e006e44e9f5c027d7883d6202c96bed7907..b23686f8be577519c9705b2d6168b703d6edc1cb 100644 --- a/alib2algo_experimental/src/grammar/parsing/Follow.h +++ b/alib2algo_experimental/src/grammar/parsing/Follow.h @@ -39,7 +39,8 @@ public: template < class T, class SymbolType > void Follow::follow ( const T & grammar, ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > & followSet ) { - for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & rule : grammar.getRawRules ( ) ) { + auto rawRules = grammar::RawRules::getRawRules ( grammar ); + for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & rule : rawRules ) { const SymbolType & X = rule.first; for ( const ext::vector < SymbolType > & rhs : rule.second ) diff --git a/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h b/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h index ef2120525ce8511bd99eceea2772290c324f45b4..0d2708390e9be9164344ad3690b88dea86b89009 100644 --- a/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h +++ b/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h @@ -37,7 +37,8 @@ ext::map < ext::pair < ext::variant < SymbolType, string::Epsilon < > >, SymbolT ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > first = First::first ( grammar ); ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > follow = Follow::follow ( grammar ); - for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & transition : grammar.getRawRules ( ) ) { + auto rawRules = grammar::RawRules::getRawRules ( grammar ); + for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & transition : rawRules ) { const SymbolType & lhs = transition.first; for ( const ext::vector < SymbolType > & rhs : transition.second ) { diff --git a/alib2algo_experimental/test-src/grammar/parsing/FirstTest.cpp b/alib2algo_experimental/test-src/grammar/parsing/FirstTest.cpp index 0f9fb8a7c5fe756932cff95523d4123d4e156c1b..3c448587f43064b3552e782f0d132fe26553b867 100644 --- a/alib2algo_experimental/test-src/grammar/parsing/FirstTest.cpp +++ b/alib2algo_experimental/test-src/grammar/parsing/FirstTest.cpp @@ -69,7 +69,7 @@ void FirstTest::testFirst ( ) { ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > firstAlgo; - for ( const auto & rule : grammar.getRawRules ( ) ) + for ( const auto & rule : grammar::RawRules::getRawRules ( grammar ) ) for ( const auto & rhs : rule.second ) firstAlgo[rhs] = grammar::parsing::First::first ( grammar, rhs ); @@ -175,7 +175,7 @@ void FirstTest::testFirst ( ) { ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > firstAlgo; - for ( const auto & rule : grammar.getRawRules ( ) ) + for ( const auto & rule : grammar::RawRules::getRawRules ( grammar ) ) for ( const auto & rhs : rule.second ) firstAlgo[rhs] = grammar::parsing::First::first ( grammar, rhs ); diff --git a/alib2data/src/grammar/AddRawRule.cpp b/alib2data/src/grammar/AddRawRule.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5c0bef880845134c25cfc5b1b26fd4f04ede9177 --- /dev/null +++ b/alib2data/src/grammar/AddRawRule.cpp @@ -0,0 +1,23 @@ +/* + * AddRawRule.cpp + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#include "AddRawRule.h" +#include <registration/AlgoRegistration.hpp> + +namespace grammar { + +auto AddRawRuleCFG = registration::AbstractRegister < AddRawRule, bool, grammar::CFG < > &, DefaultSymbolType, ext::vector < DefaultSymbolType > > ( AddRawRule::addRawRule ); +auto AddRawRuleEpsilonFreeCFG = registration::AbstractRegister < AddRawRule, bool, grammar::EpsilonFreeCFG < > &, DefaultSymbolType, ext::vector < DefaultSymbolType > > ( AddRawRule::addRawRule ); +auto AddRawRuleGNF = registration::AbstractRegister < AddRawRule, bool, grammar::GNF < > &, DefaultSymbolType, ext::vector < DefaultSymbolType > > ( AddRawRule::addRawRule ); +auto AddRawRuleCNF = registration::AbstractRegister < AddRawRule, bool, grammar::CNF < > &, DefaultSymbolType, ext::vector < DefaultSymbolType > > ( AddRawRule::addRawRule ); +auto AddRawRuleLG = registration::AbstractRegister < AddRawRule, bool, grammar::LG < > &, DefaultSymbolType, ext::vector < DefaultSymbolType > > ( AddRawRule::addRawRule ); +auto AddRawRuleLeftLG = registration::AbstractRegister < AddRawRule, bool, grammar::LeftLG < > &, DefaultSymbolType, ext::vector < DefaultSymbolType > > ( AddRawRule::addRawRule ); +auto AddRawRuleLeftRG = registration::AbstractRegister < AddRawRule, bool, grammar::LeftRG < > &, DefaultSymbolType, ext::vector < DefaultSymbolType > > ( AddRawRule::addRawRule ); +auto AddRawRuleRightLG = registration::AbstractRegister < AddRawRule, bool, grammar::RightLG < > &, DefaultSymbolType, ext::vector < DefaultSymbolType > > ( AddRawRule::addRawRule ); +auto AddRawRuleRightRG = registration::AbstractRegister < AddRawRule, bool, grammar::RightRG < > &, DefaultSymbolType, ext::vector < DefaultSymbolType > > ( AddRawRule::addRawRule ); + +} /* namespace grammar */ diff --git a/alib2data/src/grammar/AddRawRule.h b/alib2data/src/grammar/AddRawRule.h new file mode 100644 index 0000000000000000000000000000000000000000..30d110caf6478654227d7841646544fef6308b92 --- /dev/null +++ b/alib2data/src/grammar/AddRawRule.h @@ -0,0 +1,217 @@ +/* + * AddRawRule.h + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef _ADD_RAW_RULE_H__ +#define _ADD_RAW_RULE_H__ + +#include <alib/set> +#include <alib/map> +#include <grammar/ContextFree/CFG.h> +#include <grammar/ContextFree/EpsilonFreeCFG.h> +#include <grammar/ContextFree/GNF.h> +#include <grammar/ContextFree/CNF.h> +#include <grammar/ContextFree/LG.h> +#include <grammar/Regular/LeftLG.h> +#include <grammar/Regular/LeftRG.h> +#include <grammar/Regular/RightLG.h> +#include <grammar/Regular/RightRG.h> + +#include <grammar/Grammar.h> + +namespace grammar { + +/** + * Implementation of transformation from grammar specific rules to common representation, i.e. A -> (N \cup T) where A \in N and N is set of nonterminal symbols and T is set of terminal symbols of the grammar. + */ +class AddRawRule { +public: + /** + * Get rules in most common format of rules as mapping from leftHandSide to rightHandSides represented as vectors of symbols. + * + * \tparam SymbolType the type of symbols in the grammar + * + * \param grammar the source grammar of rules to transform + * + * \returns rules of the grammar in a common representation + */ + template < class SymbolType > + static bool addRawRule ( LG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); + + /** + * \override + */ + template < class SymbolType > + static bool addRawRule ( GNF < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); + + /** + * \override + */ + template < class SymbolType > + static bool addRawRule ( EpsilonFreeCFG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); + + /** + * \override + */ + template < class SymbolType > + static bool addRawRule ( CNF < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); + + /** + * \override + */ + template < class SymbolType > + static bool addRawRule ( CFG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); + + /** + * \override + */ + template < class SymbolType > + static bool addRawRule ( LeftLG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); + + /** + * \override + */ + template < class SymbolType > + static bool addRawRule ( LeftRG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); + + /** + * \override + */ + template < class SymbolType > + static bool addRawRule ( RightLG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); + + /** + * \override + */ + template < class SymbolType > + static bool addRawRule ( RightRG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); +}; + +template < class SymbolType > +bool AddRawRule::addRawRule ( LG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { + typename ext::vector < SymbolType >::iterator nonterminalPosition = rightHandSide.begin ( ); + + for ( ; nonterminalPosition != rightHandSide.end ( ); ++nonterminalPosition ) + if ( grammar.getNonterminalAlphabet ( ).count ( * nonterminalPosition ) ) break; + + if ( nonterminalPosition == rightHandSide.end ( ) ) + return grammar.addRule ( leftHandSide, rightHandSide ); + else + return grammar.addRule ( leftHandSide, ext::make_tuple ( ext::vector < SymbolType > ( std::make_move_iterator ( rightHandSide.begin ( ) ), std::make_move_iterator ( nonterminalPosition ) ), std::move ( * nonterminalPosition ), ext::vector < SymbolType > ( std::make_move_iterator ( nonterminalPosition ) + 1, std::make_move_iterator ( rightHandSide.end ( ) ) ) ) ); +} + +template < class SymbolType > +bool AddRawRule::addRawRule ( GNF < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { + if ( rightHandSide.size ( ) == 0 ) { + if ( leftHandSide != grammar.getInitialSymbol ( ) ) + throw GrammarException ( "Illegal left hand side of epsilon rule" ); + + bool res = grammar.getGeneratesEpsilon ( ); + grammar.setGeneratesEpsilon ( true ); + return !res; + } else { + SymbolType first = std::move ( rightHandSide[0] ); + ext::vector < SymbolType > rest ( std::make_move_iterator ( rightHandSide.begin ( ) ) + 1, std::make_move_iterator ( rightHandSide.end ( ) ) ); + return grammar.addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( first ), std::move ( rest ) ) ); + } +} + +template < class SymbolType > +bool AddRawRule::addRawRule ( EpsilonFreeCFG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { + if ( rightHandSide.size ( ) == 0 ) { + if ( leftHandSide != grammar.getInitialSymbol ( ) ) + throw GrammarException ( "Illegal left hand side of epsilon rule" ); + + bool res = grammar.getGeneratesEpsilon ( ); + grammar.setGeneratesEpsilon ( true ); + return ! res; + } else { + return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) ); + } +} + +template < class SymbolType > +bool AddRawRule::addRawRule ( CNF < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { + if ( rightHandSide.size ( ) == 0 ) { + if ( leftHandSide != grammar.getInitialSymbol ( ) ) + throw GrammarException ( "Illegal left hand side of epsilon rule" ); + + bool res = grammar.getGeneratesEpsilon ( ); + grammar.setGeneratesEpsilon ( true ); + return ! res; + } else if ( rightHandSide.size ( ) == 1 ) { + return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide[0] ) ); + } else if ( rightHandSide.size ( ) == 2 ) { + return grammar.addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( rightHandSide[0] ), std::move ( rightHandSide[1] ) ) ); + } else { + throw GrammarException ( "Invalid right hand side" ); + } +} + +template < class SymbolType > +bool AddRawRule::addRawRule ( CFG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { + return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) ); +} + +template < class SymbolType > +bool AddRawRule::addRawRule ( LeftLG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { + if ( rightHandSide.size ( ) == 0 ) + return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) ); + else if ( grammar.getNonterminalAlphabet ( ).count ( rightHandSide[0] ) ) + return grammar.addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( rightHandSide[0] ), ext::vector < SymbolType > ( std::make_move_iterator ( rightHandSide.begin ( ) ), std::make_move_iterator ( rightHandSide.end ( ) ) ) ) ); + else + return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) ); +} + +template < class SymbolType > +bool AddRawRule::addRawRule ( LeftRG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { + if ( rightHandSide.size ( ) == 0 ) { + if ( leftHandSide != grammar.getInitialSymbol ( ) ) + throw GrammarException ( "Illegal left hand side of epsilon rule" ); + + bool res = grammar.getGeneratesEpsilon ( ); + grammar.setGeneratesEpsilon ( true ); + return res; + } else if ( rightHandSide.size ( ) == 1 ) { + return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide[0] ) ); + } else if ( rightHandSide.size ( ) == 2 ) { + return grammar.addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( rightHandSide[0] ), std::move ( rightHandSide[1] ) ) ); + } else { + throw GrammarException ( "Invalid right hand side" ); + } +} + +template < class SymbolType > +bool AddRawRule::addRawRule ( RightRG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { + if ( rightHandSide.size ( ) == 0 ) { + if ( leftHandSide != grammar.getInitialSymbol ( ) ) + throw GrammarException ( "Illegal left hand side of epsilon rule" ); + + bool res = grammar.getGeneratesEpsilon ( ); + grammar.setGeneratesEpsilon ( true ); + return res; + } else if ( rightHandSide.size ( ) == 1 ) { + return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide[0] ) ); + } else if ( rightHandSide.size ( ) == 2 ) { + return grammar.addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( rightHandSide[0] ), std::move ( rightHandSide[1] ) ) ); + } else { + throw GrammarException ( "Invalid right hand side" ); + } +} + +template < class SymbolType > +bool AddRawRule::addRawRule ( RightLG < SymbolType > & grammar, SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { + if ( rightHandSide.size ( ) == 0 ) + return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) ); + else if ( grammar.getNonterminalAlphabet ( ).count ( rightHandSide[rightHandSide.size ( ) - 1] ) ) + return grammar.addRule ( std::move ( leftHandSide ), ext::make_pair ( ext::vector < SymbolType > ( std::make_move_iterator ( rightHandSide.begin ( ) ), std::make_move_iterator ( rightHandSide.end ( ) ) - 1 ), std::move ( rightHandSide[rightHandSide.size ( ) - 1] ) ) ); + else + return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) ); +} + +} /* namespace grammar */ + +#endif /* _ADD_RAW_RULE_H__ */ diff --git a/alib2data/src/grammar/ContextFree/CFG.h b/alib2data/src/grammar/ContextFree/CFG.h index 77b7a2bc7b724507c39a7701fc8f5493aa5a3fcf..5bb00f51e282bc7212d92b3c70f018d1399ee1f2 100644 --- a/alib2data/src/grammar/ContextFree/CFG.h +++ b/alib2data/src/grammar/ContextFree/CFG.h @@ -151,30 +151,6 @@ public: */ bool removeRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ); - /** - * Add a new rule of a grammar in form of A -> B, where A \in N and B \in (N \cup T)* as stored in combination of leftHandSide and rightHandSide represented as vector of symbols. - * - * \param leftHandSide the left hand side of the rule - * \param rightHandSide the right hand side of the rule - * - * \returns true if the rule was indeed added, false othervise - */ - bool addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); - - /** - * Get rules in most common format of rules as mapping from leftHandSide to rightHandSides represented as vectors of symbols. - * - * \returns rules of the grammar - */ - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( ) const; - - /** - * Remove a rule of a grammar in form of A -> B, where A \in N and B \in (N \cup T)* as stored in combination of leftHandSide and rightHandSide - * - * \returns true if the rule was indeed removed, false othervise - */ - bool removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ); - /** * Getter of initial symbol. * @@ -377,21 +353,6 @@ ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > && CFG < Symbol return std::move ( rules ); } -template < class SymbolType > -bool CFG < SymbolType >::addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { - return addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) ); -} - -template < class SymbolType > -ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > CFG < SymbolType >::getRawRules ( ) const { - return rules; -} - -template < class SymbolType > -bool CFG < SymbolType >::removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ) { - return removeRule ( leftHandSide, rightHandSide ); -} - template < class SymbolType > bool CFG < SymbolType >::removeRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ) { return rules[leftHandSide].erase ( rightHandSide ); diff --git a/alib2data/src/grammar/ContextFree/CNF.h b/alib2data/src/grammar/ContextFree/CNF.h index de9be7e41b82657f282e53254d476c70ff997b35..6a32e8d711dfd4b20c7ff8fe5fa1f612c6153cb5 100644 --- a/alib2data/src/grammar/ContextFree/CNF.h +++ b/alib2data/src/grammar/ContextFree/CNF.h @@ -192,30 +192,6 @@ public: */ bool removeRule ( const SymbolType & leftHandSide, const ext::pair < SymbolType, SymbolType > & rightHandSide ); - /** - * Add a new rule of a grammar in form of A -> BC or A -> a, where A, B, C \in N and a \in T as stored in combination of leftHandSide and rightHandSide represented as vector of symbols. - * - * \param leftHandSide the left hand side of the rule - * \param rightHandSide the right hand side of the rule - * - * \returns true if the rule was indeed added, false othervise - */ - bool addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); - - /** - * Get rules in most common format of rules as mapping from leftHandSide to rightHandSides represented as vectors of symbols. - * - * \returns rules of the grammar - */ - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( ) const; - - /** - * Remove a rule of a grammar in form of A -> BC or A -> a, where A, B, C \in N and a \in T as stored in combination of leftHandSide and rightHandSide - * - * \returns true if the rule was indeed removed, false othervise - */ - bool removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ); - /** * Getter of initial symbol. * @@ -474,62 +450,6 @@ bool CNF < SymbolType >::removeRule ( const SymbolType & leftHandSide, const ext return removeRule ( leftHandSide, rhs ); } -template < class SymbolType > -bool CNF < SymbolType >::addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) { - if ( leftHandSide != getInitialSymbol ( ) ) throw GrammarException ( "Illegal left hand side of epsilon rule" ); - - bool res = getGeneratesEpsilon ( ); - setGeneratesEpsilon ( true ); - return !res; - } else if ( rightHandSide.size ( ) == 1 ) { - return addRule ( std::move ( leftHandSide ), std::move ( rightHandSide[0] ) ); - } else if ( rightHandSide.size ( ) == 2 ) { - return addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( rightHandSide[0] ), std::move ( rightHandSide[1] ) ) ); - } else { - throw GrammarException ( "Invalid right hand side" ); - } -} - -template < class SymbolType > -ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > CNF < SymbolType >::getRawRules ( ) const { - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; - - for ( const auto & rule : getRules ( ) ) - for ( const auto & rhs : rule.second ) { - if ( rhs.template is < SymbolType > ( ) ) { - ext::vector < SymbolType > tmp { rhs.template get < SymbolType > ( ) }; - res[rule.first].insert ( std::move ( tmp ) ); - } else { - const auto & realRHS = rhs.template get < ext::pair < SymbolType, SymbolType > > ( ); - ext::vector < SymbolType > tmp { realRHS.first, realRHS.second }; - res[rule.first].insert ( std::move ( tmp ) ); - } - } - - if ( getGeneratesEpsilon ( ) ) - res[getInitialSymbol ( )].insert ( ext::vector < SymbolType > { } ); - - return res; -} - -template < class SymbolType > -bool CNF < SymbolType >::removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) { - if ( leftHandSide != getInitialSymbol ( ) ) throw GrammarException ( "Illegal left hand side of epsilon rule" ); - - bool res = getGeneratesEpsilon ( ); - setGeneratesEpsilon ( false ); - return res; - } else if ( rightHandSide.size ( ) == 1 ) { - return removeRule ( leftHandSide, rightHandSide[0] ); - } else if ( rightHandSide.size ( ) == 2 ) { - return removeRule ( leftHandSide, ext::make_pair ( rightHandSide[0], rightHandSide[1] ) ); - } else { - throw GrammarException ( "Invalid right hand side" ); - } -} - template < class SymbolType > void CNF < SymbolType >::setGeneratesEpsilon ( bool genEps ) { generatesEpsilon = genEps; diff --git a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h index a5744fe7b1e529e7e006c0d34b8d5a8b71e8129d..6e4e36ae9bf65da6e1d11c55bf67097c342f50b9 100644 --- a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h +++ b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h @@ -147,30 +147,6 @@ public: */ bool removeRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ); - /** - * Add a new rule of a grammar in form of A -> B, where A \in N and B \in (N \cup T)+ as stored in combination of leftHandSide and rightHandSide represented as vector of symbols. - * - * \param leftHandSide the left hand side of the rule - * \param rightHandSide the right hand side of the rule - * - * \returns true if the rule was indeed added, false othervise - */ - bool addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); - - /** - * Get rules in most common format of rules as mapping from leftHandSide to rightHandSides represented as vectors of symbols. - * - * \returns rules of the grammar - */ - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( ) const; - - /** - * Remove a rule of a grammar in form of A -> B, where A \in N and B \in (N \cup T)+ as stored in combination of leftHandSide and rightHandSide - * - * \returns true if the rule was indeed removed, false othervise - */ - bool removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ); - /** * Getter of initial symbol. * @@ -389,42 +365,6 @@ bool EpsilonFreeCFG < SymbolType >::removeRule ( const SymbolType & leftHandSide return rules[leftHandSide].erase ( rightHandSide ); } -template < class SymbolType > -bool EpsilonFreeCFG < SymbolType >::addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) { - if ( leftHandSide != getInitialSymbol ( ) ) throw GrammarException ( "Illegal left hand side of epsilon rule" ); - - bool res = getGeneratesEpsilon ( ); - setGeneratesEpsilon ( true ); - return !res; - } else { - return addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) ); - } -} - -template < class SymbolType > -ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > EpsilonFreeCFG < SymbolType >::getRawRules ( ) const { - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res ( getRules ( ).begin ( ), getRules ( ).end ( ) ); - - if ( getGeneratesEpsilon ( ) ) - res [ getInitialSymbol ( ) ].insert ( ext::vector < SymbolType > { } ); - - return res; -} - -template < class SymbolType > -bool EpsilonFreeCFG < SymbolType >::removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) { - if ( leftHandSide != getInitialSymbol ( ) ) throw GrammarException ( "Illegal left hand side of epsilon rule" ); - - bool res = getGeneratesEpsilon ( ); - setGeneratesEpsilon ( false ); - return res; - } else { - return removeRule ( leftHandSide, rightHandSide ); - } -} - template < class SymbolType > void EpsilonFreeCFG < SymbolType >::setGeneratesEpsilon ( bool genEps ) { generatesEpsilon = genEps; diff --git a/alib2data/src/grammar/ContextFree/GNF.h b/alib2data/src/grammar/ContextFree/GNF.h index 0964857cbcef43f460dfc1924d9958ab01021018..0de4d45fb84a6f26d2824187b98564a60c86ab4a 100644 --- a/alib2data/src/grammar/ContextFree/GNF.h +++ b/alib2data/src/grammar/ContextFree/GNF.h @@ -147,30 +147,6 @@ public: */ bool removeRule ( const SymbolType & leftHandSide, const ext::pair < SymbolType, ext::vector < SymbolType > > & rightHandSide ); - /** - * Add a new rule of a grammar in form of A -> aB, where A \in N, a \in T, and B \in N* as stored in combination of leftHandSide and rightHandSide represented as vector of symbols. - * - * \param leftHandSide the left hand side of the rule - * \param rightHandSide the right hand side of the rule - * - * \returns true if the rule was indeed added, false othervise - */ - bool addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); - - /** - * Get rules in most common format of rules as mapping from leftHandSide to rightHandSides represented as vectors of symbols. - * - * \returns rules of the grammar - */ - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( ) const; - - /** - * Remove a rule of a grammar in form of A -> aB, where A \in N, a \in T, and B \in N* as stored in combination of leftHandSide and rightHandSide - * - * \returns true if the rule was indeed removed, false othervise - */ - bool removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ); - /** * Getter of initial symbol. * @@ -389,53 +365,6 @@ bool GNF < SymbolType >::removeRule ( const SymbolType & leftHandSide, const ext return rules[leftHandSide].erase ( rightHandSide ); } -template < class SymbolType > -bool GNF < SymbolType >::addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) { - if ( leftHandSide != getInitialSymbol ( ) ) throw GrammarException ( "Illegal left hand side of epsilon rule" ); - - bool res = getGeneratesEpsilon ( ); - setGeneratesEpsilon ( true ); - return !res; - } else { - SymbolType first = std::move ( rightHandSide[0] ); - ext::vector < SymbolType > rest ( std::make_move_iterator ( rightHandSide.begin ( ) ) + 1, std::make_move_iterator ( rightHandSide.end ( ) ) ); - return addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( first ), std::move ( rest ) ) ); - } -} - -template < class SymbolType > -ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > GNF < SymbolType >::getRawRules ( ) const { - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; - - for ( const auto & rule : getRules ( ) ) - for ( const auto & rhs : rule.second ) { - ext::vector < SymbolType > tmp { rhs.first }; - tmp.insert ( tmp.end ( ), rhs.second.begin ( ), rhs.second.end ( ) ); - res[rule.first].insert ( std::move ( tmp ) ); - } - - if ( getGeneratesEpsilon ( ) ) - res[getInitialSymbol ( )].insert ( ext::vector < SymbolType > { } ); - - return res; -} - -template < class SymbolType > -bool GNF < SymbolType >::removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) { - if ( leftHandSide != getInitialSymbol ( ) ) throw GrammarException ( "Illegal left hand side of epsilon rule" ); - - bool res = getGeneratesEpsilon ( ); - setGeneratesEpsilon ( false ); - return res; - } else { - SymbolType first = rightHandSide[0]; - ext::vector < SymbolType > rest ( rightHandSide.begin ( ) + 1, rightHandSide.end ( ) ); - return removeRule ( leftHandSide, ext::make_pair ( first, rest ) ); - } -} - template < class SymbolType > void GNF < SymbolType >::setGeneratesEpsilon ( bool genEps ) { generatesEpsilon = genEps; diff --git a/alib2data/src/grammar/ContextFree/LG.h b/alib2data/src/grammar/ContextFree/LG.h index a39f2abc2fe4e9e86f860384bdc62493323cb816..858a033bd0602f8ecc5bf582b79c5e9f1dc3d310 100644 --- a/alib2data/src/grammar/ContextFree/LG.h +++ b/alib2data/src/grammar/ContextFree/LG.h @@ -188,30 +188,6 @@ public: */ bool removeRule ( const SymbolType & leftHandSide, const ext::tuple < ext::vector < SymbolType >, SymbolType, ext::vector < SymbolType > > & rightHandSide ); - /** - * Add a new rule of a grammar in form of A -> aBb or A -> a, where A, B \in N and a, b \in T* as stored in combination of leftHandSide and rightHandSide represented as vector of symbols. - * - * \param leftHandSide the left hand side of the rule - * \param rightHandSide the right hand side of the rule - * - * \returns true if the rule was indeed added, false othervise - */ - bool addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); - - /** - * Get rules in most common format of rules as mapping from leftHandSide to rightHandSides represented as vectors of symbols. - * - * \returns rules of the grammar - */ - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( ) const; - - /** - * Remove a rule of a grammar in form of A -> aBb or A -> a, where A, B \in N and a, b \in T* as stored in combination of leftHandSide and rightHandSide - * - * \returns true if the rule was indeed removed, false othervise - */ - bool removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ); - /** * Getter of initial symbol. * @@ -472,52 +448,6 @@ bool LG < SymbolType >::removeRule ( const SymbolType & leftHandSide, const ext: return removeRule ( leftHandSide, rhs ); } -template < class SymbolType > -bool LG < SymbolType >::addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { - typename ext::vector < SymbolType >::iterator nonterminalPosition = rightHandSide.begin ( ); - - for ( ; nonterminalPosition != rightHandSide.end ( ); ++nonterminalPosition ) - if ( getNonterminalAlphabet ( ).count ( * nonterminalPosition ) ) break; - - if ( nonterminalPosition == rightHandSide.end ( ) ) - return addRule ( leftHandSide, rightHandSide ); - else - return addRule ( leftHandSide, ext::make_tuple ( ext::vector < SymbolType > ( std::make_move_iterator ( rightHandSide.begin ( ) ), std::make_move_iterator ( nonterminalPosition ) ), std::move ( * nonterminalPosition ), ext::vector < SymbolType > ( std::make_move_iterator ( nonterminalPosition ) + 1, std::make_move_iterator ( rightHandSide.end ( ) ) ) ) ); -} - -template < class SymbolType > -ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > LG < SymbolType >::getRawRules ( ) const { - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; - - for ( const auto & rule : getRules ( ) ) - for ( const auto & rhs : rule.second ) { - if ( rhs.template is < ext::vector < SymbolType > > ( ) ) { - res[rule.first].insert ( rhs.template get < ext::vector < SymbolType > > ( ) ); - } else { - const auto & rhsTuple = rhs.template get < ext::tuple < ext::vector < SymbolType >, SymbolType, ext::vector < SymbolType > > > ( ); - ext::vector < SymbolType > tmp { std::get < 0 > ( rhsTuple ).begin ( ), std::get < 0 > ( rhsTuple ).end ( ) }; - tmp.push_back ( std::get < 1 > ( rhsTuple ) ); - tmp.insert ( tmp.end ( ), std::get < 2 > ( rhsTuple ).begin ( ), std::get < 2 > ( rhsTuple ).end ( ) ); - res[rule.first].insert ( std::move ( tmp ) ); - } - } - - return res; -} - -template < class SymbolType > -bool LG < SymbolType >::removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ) { - typename ext::vector < SymbolType >::const_iterator nonterminalPosition = rightHandSide.begin ( ); - - for ( ; nonterminalPosition != rightHandSide.end ( ); ++nonterminalPosition ) - if ( getNonterminalAlphabet ( ).count ( * nonterminalPosition ) ) break; - - if ( nonterminalPosition == rightHandSide.end ( ) ) - return removeRule ( leftHandSide, rightHandSide ); - else - return removeRule ( leftHandSide, ext::make_tuple ( ext::vector < SymbolType > ( rightHandSide.begin ( ), nonterminalPosition ), * nonterminalPosition, ext::vector < SymbolType > ( nonterminalPosition + 1, rightHandSide.end ( ) ) ) ); -} - template < class SymbolType > int LG < SymbolType >::compare ( const LG & other ) const { auto first = ext::tie ( getTerminalAlphabet ( ), getNonterminalAlphabet ( ), getInitialSymbol ( ), rules ); diff --git a/alib2data/src/grammar/RawRules.cpp b/alib2data/src/grammar/RawRules.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55f86cb52cc6ebd42c98910ba5657f82dc4eaeb3 --- /dev/null +++ b/alib2data/src/grammar/RawRules.cpp @@ -0,0 +1,23 @@ +/* + * RawRules.cpp + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#include "RawRules.h" +#include <registration/AlgoRegistration.hpp> + +namespace grammar { + +auto RawRulesCFG = registration::AbstractRegister < RawRules, ext::map < DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::CFG < > & > ( RawRules::getRawRules ); +auto RawRulesEpsilonFreeCFG = registration::AbstractRegister < RawRules, ext::map < DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::EpsilonFreeCFG < > & > ( RawRules::getRawRules ); +auto RawRulesGNF = registration::AbstractRegister < RawRules, ext::map < DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::GNF < > & > ( RawRules::getRawRules ); +auto RawRulesCNF = registration::AbstractRegister < RawRules, ext::map < DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::CNF < > & > ( RawRules::getRawRules ); +auto RawRulesLG = registration::AbstractRegister < RawRules, ext::map < DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::LG < > & > ( RawRules::getRawRules ); +auto RawRulesLeftLG = registration::AbstractRegister < RawRules, ext::map < DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::LeftLG < > & > ( RawRules::getRawRules ); +auto RawRulesLeftRG = registration::AbstractRegister < RawRules, ext::map < DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::LeftRG < > & > ( RawRules::getRawRules ); +auto RawRulesRightLG = registration::AbstractRegister < RawRules, ext::map < DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::RightLG < > & > ( RawRules::getRawRules ); +auto RawRulesRightRG = registration::AbstractRegister < RawRules, ext::map < DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::RightRG < > & > ( RawRules::getRawRules ); + +} /* namespace grammar */ diff --git a/alib2data/src/grammar/RawRules.h b/alib2data/src/grammar/RawRules.h new file mode 100644 index 0000000000000000000000000000000000000000..9cb29cbd880bbcb46bbdc5d4e4e34b90dcf7ceaf --- /dev/null +++ b/alib2data/src/grammar/RawRules.h @@ -0,0 +1,251 @@ +/* + * RawRules.h + * + * Created on: 22. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef _RAW_RULES_H__ +#define _RAW_RULES_H__ + +#include <alib/set> +#include <alib/map> +#include <grammar/ContextFree/CFG.h> +#include <grammar/ContextFree/EpsilonFreeCFG.h> +#include <grammar/ContextFree/GNF.h> +#include <grammar/ContextFree/CNF.h> +#include <grammar/ContextFree/LG.h> +#include <grammar/Regular/LeftLG.h> +#include <grammar/Regular/LeftRG.h> +#include <grammar/Regular/RightLG.h> +#include <grammar/Regular/RightRG.h> + +#include <grammar/Grammar.h> + +namespace grammar { + +/** + * Implementation of transformation from grammar specific rules to common representation, i.e. A -> (N \cup T) where A \in N and N is set of nonterminal symbols and T is set of terminal symbols of the grammar. + */ +class RawRules { +public: + /** + * Get rules in most common format of rules as mapping from leftHandSide to rightHandSides represented as vectors of symbols. + * + * \tparam SymbolType the type of symbols in the grammar + * + * \param grammar the source grammar of rules to transform + * + * \returns rules of the grammar in a common representation + */ + template < class SymbolType > + static ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( const LG < SymbolType > & grammar ); + + /** + * \override + */ + template < class SymbolType > + static ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( const GNF < SymbolType > & grammar ); + + /** + * \override + */ + template < class SymbolType > + static ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( const EpsilonFreeCFG < SymbolType > & grammar ); + + /** + * \override + */ + template < class SymbolType > + static ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( const CNF < SymbolType > & grammar ); + + /** + * \override + */ + template < class SymbolType > + static ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( const CFG < SymbolType > & grammar ); + + /** + * \override + */ + template < class SymbolType > + static ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( const LeftLG < SymbolType > & grammar ); + + /** + * \override + */ + template < class SymbolType > + static ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( const LeftRG < SymbolType > & grammar ); + + /** + * \override + */ + template < class SymbolType > + static ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( const RightLG < SymbolType > & grammar ); + + /** + * \override + */ + template < class SymbolType > + static ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( const RightRG < SymbolType > & grammar ); +}; + +template < class SymbolType > +ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > RawRules::getRawRules ( const LG < SymbolType > & grammar ) { + ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; + + for ( const auto & rule : grammar.getRules ( ) ) + for ( const auto & rhs : rule.second ) { + if ( rhs.template is < ext::vector < SymbolType > > ( ) ) { + res[rule.first].insert ( rhs.template get < ext::vector < SymbolType > > ( ) ); + } else { + const auto & rhsTuple = rhs.template get < ext::tuple < ext::vector < SymbolType >, SymbolType, ext::vector < SymbolType > > > ( ); + ext::vector < SymbolType > tmp { std::get < 0 > ( rhsTuple ).begin ( ), std::get < 0 > ( rhsTuple ).end ( ) }; + tmp.push_back ( std::get < 1 > ( rhsTuple ) ); + tmp.insert ( tmp.end ( ), std::get < 2 > ( rhsTuple ).begin ( ), std::get < 2 > ( rhsTuple ).end ( ) ); + res[rule.first].insert ( std::move ( tmp ) ); + } + } + + return res; +} + +template < class SymbolType > +ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > RawRules::getRawRules ( const GNF < SymbolType > & grammar ) { + ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; + + for ( const auto & rule : grammar.getRules ( ) ) + for ( const auto & rhs : rule.second ) { + ext::vector < SymbolType > tmp { rhs.first }; + tmp.insert ( tmp.end ( ), rhs.second.begin ( ), rhs.second.end ( ) ); + res[rule.first].insert ( std::move ( tmp ) ); + } + + if ( grammar.getGeneratesEpsilon ( ) ) + res [ grammar.getInitialSymbol ( ) ].insert ( ext::vector < SymbolType > { } ); + + return res; +} + +template < class SymbolType > +ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > RawRules::getRawRules ( const EpsilonFreeCFG < SymbolType > & grammar ) { + ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res ( grammar.getRules ( ) ); + + if ( grammar.getGeneratesEpsilon ( ) ) + res [ grammar.getInitialSymbol ( ) ].insert ( ext::vector < SymbolType > { } ); + + return res; +} + +template < class SymbolType > +ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > RawRules::getRawRules ( const CNF < SymbolType > & grammar ) { + ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; + + for ( const auto & rule : grammar.getRules ( ) ) + for ( const auto & rhs : rule.second ) { + if ( rhs.template is < SymbolType > ( ) ) { + ext::vector < SymbolType > tmp { rhs.template get < SymbolType > ( ) }; + res[rule.first].insert ( std::move ( tmp ) ); + } else { + const auto & realRHS = rhs.template get < ext::pair < SymbolType, SymbolType > > ( ); + ext::vector < SymbolType > tmp { realRHS.first, realRHS.second }; + res[rule.first].insert ( std::move ( tmp ) ); + } + } + + if ( grammar.getGeneratesEpsilon ( ) ) + res [ grammar.getInitialSymbol ( ) ].insert ( ext::vector < SymbolType > { } ); + + return res; +} + +template < class SymbolType > +ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > RawRules::getRawRules ( const CFG < SymbolType > & grammar ) { + return grammar.getRules ( ); +} + +template < class SymbolType > +ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > RawRules::getRawRules ( const LeftLG < SymbolType > & grammar ) { + ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; + + for ( const auto & rule : grammar.getRules ( ) ) + for ( const auto & rhs : rule.second ) { + if ( rhs.template is < ext::vector < SymbolType > > ( ) ) { + res[rule.first].insert ( rhs.template get < ext::vector < SymbolType > > ( ) ); + } else { + const auto & rhsTuple = rhs.template get < ext::pair < SymbolType, ext::vector < SymbolType > > > ( ); + ext::vector < SymbolType > tmp { rhsTuple.first }; + tmp.insert ( tmp.end ( ), rhsTuple.second.begin ( ), rhsTuple.second.end ( ) ); + res[rule.first].insert ( std::move ( tmp ) ); + } + } + + return res; +} + +template < class SymbolType > +ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > RawRules::getRawRules ( const LeftRG < SymbolType > & grammar ) { + ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; + + for ( const auto & rule : grammar.getRules ( ) ) + for ( const auto & rhs : rule.second ) { + if ( rhs.template is < SymbolType > ( ) ) { + ext::vector < SymbolType > tmp { rhs.template get < SymbolType > ( ) }; + res[rule.first].insert ( std::move ( tmp ) ); + } else { + const auto & rhsPair = rhs.template get < ext::pair < SymbolType, SymbolType > > ( ); + ext::vector < SymbolType > tmp { rhsPair.first, rhsPair.second }; + res[rule.first].insert ( std::move ( tmp ) ); + } + } + + if ( grammar.getGeneratesEpsilon ( ) ) + res [ grammar.getInitialSymbol ( ) ].insert ( ext::vector < SymbolType > { } ); + + return res; +} + +template < class SymbolType > +ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > RawRules::getRawRules ( const RightRG < SymbolType > & grammar ) { + ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; + + for ( const auto & rule : grammar.getRules ( ) ) + for ( const auto & rhs : rule.second ) { + if ( rhs.template is < SymbolType > ( ) ) { + ext::vector < SymbolType > tmp { rhs.template get < SymbolType > ( ) }; + res[rule.first].insert ( std::move ( tmp ) ); + } else { + const auto & rhsPair = rhs.template get < ext::pair < SymbolType, SymbolType > > ( ); + ext::vector < SymbolType > tmp { rhsPair.first, rhsPair.second }; + res[rule.first].insert ( std::move ( tmp ) ); + } + } + + if ( grammar.getGeneratesEpsilon ( ) ) + res [ grammar.getInitialSymbol ( ) ].insert ( ext::vector < SymbolType > { } ); + + return res; +} + +template < class SymbolType > +ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > RawRules::getRawRules ( const RightLG < SymbolType > & grammar ) { + ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; + + for ( const auto & rule : grammar.getRules ( ) ) + for ( const auto & rhs : rule.second ) { + if ( rhs.template is < ext::vector < SymbolType > > ( ) ) { + res[rule.first].insert ( rhs.template get < ext::vector < SymbolType > > ( ) ); + } else { + const auto & rhsTuple = rhs.template get < ext::pair < ext::vector < SymbolType >, SymbolType > > ( ); + ext::vector < SymbolType > tmp { rhsTuple.first.begin ( ), rhsTuple.first.end ( ) }; + tmp.push_back ( rhsTuple.second ); + res[rule.first].insert ( std::move ( tmp ) ); + } + } + + return res; +} + +} /* namespace grammar */ + +#endif /* _RAW_RULES_H__ */ diff --git a/alib2data/src/grammar/Regular/LeftLG.h b/alib2data/src/grammar/Regular/LeftLG.h index 12d7e209737366d1653e6db64bfb6d53692a45cb..a4656e35aad748239fb6ef5c21e4e1816f9de0a8 100644 --- a/alib2data/src/grammar/Regular/LeftLG.h +++ b/alib2data/src/grammar/Regular/LeftLG.h @@ -187,30 +187,6 @@ public: */ bool removeRule ( const SymbolType & leftHandSide, const ext::pair < SymbolType, ext::vector < SymbolType > > & rightHandSide ); - /** - * Add a new rule of a grammar in form of A -> Ba or A -> a, where A, B \in N and a \in T* as stored in combination of leftHandSide and rightHandSide represented as vector of symbols. - * - * \param leftHandSide the left hand side of the rule - * \param rightHandSide the right hand side of the rule - * - * \returns true if the rule was indeed added, false othervise - */ - bool addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); - - /** - * Get rules in most common format of rules as mapping from leftHandSide to rightHandSides represented as vectors of symbols. - * - * \returns rules of the grammar - */ - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( ) const; - - /** - * Remove a rule of a grammar in form of A -> Ba or A -> a, where A, B \in N and a \in T* as stored in combination of leftHandSide and rightHandSide - * - * \returns true if the rule was indeed removed, false othervise - */ - bool removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ); - /** * Getter of initial symbol. * @@ -461,45 +437,6 @@ bool LeftLG < SymbolType >::removeRule ( const SymbolType & leftHandSide, const return removeRule ( leftHandSide, rhs ); } -template < class SymbolType > -bool LeftLG < SymbolType >::addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) - return addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) ); - else if ( getNonterminalAlphabet ( ).count ( rightHandSide[0] ) ) - return addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( rightHandSide[0] ), ext::vector < SymbolType > ( std::make_move_iterator ( rightHandSide.begin ( ) ), std::make_move_iterator ( rightHandSide.end ( ) ) ) ) ); - else - return addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) ); -} - -template < class SymbolType > -ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > LeftLG < SymbolType >::getRawRules ( ) const { - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; - - for ( const auto & rule : getRules ( ) ) - for ( const auto & rhs : rule.second ) { - if ( rhs.template is < ext::vector < SymbolType > > ( ) ) { - res[rule.first].insert ( rhs.template get < ext::vector < SymbolType > > ( ) ); - } else { - const auto & rhsTuple = rhs.template get < ext::pair < SymbolType, ext::vector < SymbolType > > > ( ); - ext::vector < SymbolType > tmp { rhsTuple.first }; - tmp.insert ( tmp.end ( ), rhsTuple.second.begin ( ), rhsTuple.second.end ( ) ); - res[rule.first].insert ( std::move ( tmp ) ); - } - } - - return res; -} - -template < class SymbolType > -bool LeftLG < SymbolType >::removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) - return removeRule ( leftHandSide, rightHandSide ); - else if ( getNonterminalAlphabet ( ).count ( rightHandSide[0] ) ) - return removeRule ( leftHandSide, ext::make_pair ( rightHandSide[0], ext::vector < SymbolType > ( rightHandSide.begin ( ) + 1, rightHandSide.end ( ) ) ) ); - else - return removeRule ( leftHandSide, rightHandSide ); -} - template < class SymbolType > int LeftLG < SymbolType >::compare ( const LeftLG & other ) const { auto first = ext::tie ( getTerminalAlphabet ( ), getNonterminalAlphabet ( ), getInitialSymbol ( ), rules ); diff --git a/alib2data/src/grammar/Regular/LeftRG.h b/alib2data/src/grammar/Regular/LeftRG.h index 921fd946ca501ad8313eab61d5dc07f19a1d3235..96132d643e08b19d6c38db34b87707220a730c00 100644 --- a/alib2data/src/grammar/Regular/LeftRG.h +++ b/alib2data/src/grammar/Regular/LeftRG.h @@ -196,30 +196,6 @@ public: */ bool removeRule ( const SymbolType & leftHandSide, const ext::pair < SymbolType, SymbolType > & rightHandSide ); - /** - * Add a new rule of a grammar in form of A -> Ba or A -> a, where A, B \in N and a \in T as stored in combination of leftHandSide and rightHandSide represented as vector of symbols. - * - * \param leftHandSide the left hand side of the rule - * \param rightHandSide the right hand side of the rule - * - * \returns true if the rule was indeed added, false othervise - */ - bool addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); - - /** - * Get rules in most common format of rules as mapping from leftHandSide to rightHandSides represented as vectors of symbols. - * - * \returns rules of the grammar - */ - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( ) const; - - /** - * Remove a rule of a grammar in form of A -> Ba or A -> a, where A, B \in N and a \in T as stored in combination of leftHandSide and rightHandSide - * - * \returns true if the rule was indeed removed, false othervise - */ - bool removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ); - /** * Getter of initial symbol. * @@ -477,62 +453,6 @@ bool LeftRG < SymbolType >::removeRule ( const SymbolType & leftHandSide, const return removeRule ( leftHandSide, rhs ); } -template < class SymbolType > -bool LeftRG < SymbolType >::addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) { - if ( leftHandSide != getInitialSymbol ( ) ) throw GrammarException ( "Illegal left hand side of epsilon rule" ); - - bool res = getGeneratesEpsilon ( ); - setGeneratesEpsilon ( true ); - return res; - } else if ( rightHandSide.size ( ) == 1 ) { - return addRule ( std::move ( leftHandSide ), std::move ( rightHandSide[0] ) ); - } else if ( rightHandSide.size ( ) == 2 ) { - return addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( rightHandSide[0] ), std::move ( rightHandSide[1] ) ) ); - } else { - throw GrammarException ( "Invalid right hand side" ); - } -} - -template < class SymbolType > -ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > LeftRG < SymbolType >::getRawRules ( ) const { - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; - - for ( const auto & rule : getRules ( ) ) - for ( const auto & rhs : rule.second ) { - if ( rhs.template is < SymbolType > ( ) ) { - ext::vector < SymbolType > tmp { rhs.template get < SymbolType > ( ) }; - res[rule.first].insert ( std::move ( tmp ) ); - } else { - const auto & rhsPair = rhs.template get < ext::pair < SymbolType, SymbolType > > ( ); - ext::vector < SymbolType > tmp { rhsPair.first, rhsPair.second }; - res[rule.first].insert ( std::move ( tmp ) ); - } - } - - if ( getGeneratesEpsilon ( ) ) - res[getInitialSymbol ( )].insert ( ext::vector < SymbolType > { } ); - - return res; -} - -template < class SymbolType > -bool LeftRG < SymbolType >::removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) { - if ( leftHandSide != getInitialSymbol ( ) ) throw GrammarException ( "Illegal left hand side of epsilon rule" ); - - bool res = getGeneratesEpsilon ( ); - setGeneratesEpsilon ( false ); - return res; - } else if ( rightHandSide.size ( ) == 1 ) { - return removeRule ( leftHandSide, rightHandSide[0] ); - } else if ( rightHandSide.size ( ) == 2 ) { - return removeRule ( leftHandSide, ext::make_pair ( rightHandSide[0], rightHandSide[1] ) ); - } else { - throw GrammarException ( "Invalid right hand side" ); - } -} - template < class SymbolType > void LeftRG < SymbolType >::setGeneratesEpsilon ( bool genEps ) { generatesEpsilon = genEps; diff --git a/alib2data/src/grammar/Regular/RightLG.h b/alib2data/src/grammar/Regular/RightLG.h index 3b7a46471ac5bdf4efad6d8655ea11c4be28dca9..23a20acbe41a4877e2a6c75d7df5b7e54725f099 100644 --- a/alib2data/src/grammar/Regular/RightLG.h +++ b/alib2data/src/grammar/Regular/RightLG.h @@ -187,30 +187,6 @@ public: */ bool removeRule ( const SymbolType & leftHandSide, const ext::pair < ext::vector < SymbolType >, SymbolType > & rightHandSide ); - /** - * Add a new rule of a grammar in form of A -> aB or A -> a, where A, B \in N and a \in T* as stored in combination of leftHandSide and rightHandSide represented as vector of symbols. - * - * \param leftHandSide the left hand side of the rule - * \param rightHandSide the right hand side of the rule - * - * \returns true if the rule was indeed added, false othervise - */ - bool addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); - - /** - * Get rules in most common format of rules as mapping from leftHandSide to rightHandSides represented as vectors of symbols. - * - * \returns rules of the grammar - */ - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( ) const; - - /** - * Remove a rule of a grammar in form of A -> aB or A -> a, where A, B \in N and a \in T* as stored in combination of leftHandSide and rightHandSide - * - * \returns true if the rule was indeed removed, false othervise - */ - bool removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ); - /** * Getter of initial symbol. * @@ -472,45 +448,6 @@ bool RightLG < SymbolType >::removeRule ( const SymbolType & leftHandSide, const return removeRule ( leftHandSide, rhs ); } -template < class SymbolType > -bool RightLG < SymbolType >::addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) - return addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) ); - else if ( getNonterminalAlphabet ( ).count ( rightHandSide[rightHandSide.size ( ) - 1] ) ) - return addRule ( std::move ( leftHandSide ), ext::make_pair ( ext::vector < SymbolType > ( std::make_move_iterator ( rightHandSide.begin ( ) ), std::make_move_iterator ( rightHandSide.end ( ) ) - 1 ), std::move ( rightHandSide[rightHandSide.size ( ) - 1] ) ) ); - else - return addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) ); -} - -template < class SymbolType > -ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > RightLG < SymbolType >::getRawRules ( ) const { - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; - - for ( const auto & rule : getRules ( ) ) - for ( const auto & rhs : rule.second ) { - if ( rhs.template is < ext::vector < SymbolType > > ( ) ) { - res[rule.first].insert ( rhs.template get < ext::vector < SymbolType > > ( ) ); - } else { - const auto & rhsTuple = rhs.template get < ext::pair < ext::vector < SymbolType >, SymbolType > > ( ); - ext::vector < SymbolType > tmp { rhsTuple.first.begin ( ), rhsTuple.first.end ( ) }; - tmp.push_back ( rhsTuple.second ); - res[rule.first].insert ( std::move ( tmp ) ); - } - } - - return res; -} - -template < class SymbolType > -bool RightLG < SymbolType >::removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) - return removeRule ( leftHandSide, rightHandSide ); - else if ( getNonterminalAlphabet ( ).count ( rightHandSide[rightHandSide.size ( ) - 1] ) ) - return removeRule ( leftHandSide, ext::make_pair ( ext::vector < SymbolType > ( rightHandSide.begin ( ), rightHandSide.end ( ) - 1 ), rightHandSide[rightHandSide.size ( ) - 1] ) ); - else - return removeRule ( leftHandSide, rightHandSide ); -} - template < class SymbolType > int RightLG < SymbolType >::compare ( const RightLG & other ) const { auto first = ext::tie ( getTerminalAlphabet ( ), getNonterminalAlphabet ( ), getInitialSymbol ( ), rules ); diff --git a/alib2data/src/grammar/Regular/RightRG.h b/alib2data/src/grammar/Regular/RightRG.h index 8c33263b0e7e23ee8d22a5f713b8347c013e3919..54ee6f6dd791926a310c805a1f2f1ba6903ab0f8 100644 --- a/alib2data/src/grammar/Regular/RightRG.h +++ b/alib2data/src/grammar/Regular/RightRG.h @@ -196,30 +196,6 @@ public: */ bool removeRule ( const SymbolType & leftHandSide, const ext::pair < SymbolType, SymbolType > & rightHandSide ); - /** - * Add a new rule of a grammar in form of A -> aB or A -> a, where A, B \in N and a \in T as stored in combination of leftHandSide and rightHandSide represented as vector of symbols. - * - * \param leftHandSide the left hand side of the rule - * \param rightHandSide the right hand side of the rule - * - * \returns true if the rule was indeed added, false othervise - */ - bool addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ); - - /** - * Get rules in most common format of rules as mapping from leftHandSide to rightHandSides represented as vectors of symbols. - * - * \returns rules of the grammar - */ - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > getRawRules ( ) const; - - /** - * Remove a rule of a grammar in form of A -> aB or A -> a, where A, B \in N and a \in T as stored in combination of leftHandSide and rightHandSide - * - * \returns true if the rule was indeed removed, false othervise - */ - bool removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ); - /** * Getter of initial symbol. * @@ -476,62 +452,6 @@ bool RightRG < SymbolType >::removeRule ( const SymbolType & leftHandSide, const return removeRule ( leftHandSide, rhs ); } -template < class SymbolType > -bool RightRG < SymbolType >::addRawRule ( SymbolType leftHandSide, ext::vector < SymbolType > rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) { - if ( leftHandSide != getInitialSymbol ( ) ) throw GrammarException ( "Illegal left hand side of epsilon rule" ); - - bool res = getGeneratesEpsilon ( ); - setGeneratesEpsilon ( true ); - return res; - } else if ( rightHandSide.size ( ) == 1 ) { - return addRule ( std::move ( leftHandSide ), std::move ( rightHandSide[0] ) ); - } else if ( rightHandSide.size ( ) == 2 ) { - return addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( rightHandSide[0] ), std::move ( rightHandSide[1] ) ) ); - } else { - throw GrammarException ( "Invalid right hand side" ); - } -} - -template < class SymbolType > -ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > RightRG < SymbolType >::getRawRules ( ) const { - ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > res; - - for ( const auto & rule : getRules ( ) ) - for ( const auto & rhs : rule.second ) { - if ( rhs.template is < SymbolType > ( ) ) { - ext::vector < SymbolType > tmp { rhs.template get < SymbolType > ( ) }; - res[rule.first].insert ( std::move ( tmp ) ); - } else { - const auto & rhsPair = rhs.template get < ext::pair < SymbolType, SymbolType > > ( ); - ext::vector < SymbolType > tmp { rhsPair.first, rhsPair.second }; - res[rule.first].insert ( std::move ( tmp ) ); - } - } - - if ( getGeneratesEpsilon ( ) ) - res[getInitialSymbol ( )].insert ( ext::vector < SymbolType > { } ); - - return res; -} - -template < class SymbolType > -bool RightRG < SymbolType >::removeRawRule ( const SymbolType & leftHandSide, const ext::vector < SymbolType > & rightHandSide ) { - if ( rightHandSide.size ( ) == 0 ) { - if ( leftHandSide != getInitialSymbol ( ) ) throw GrammarException ( "Illegal left hand side of epsilon rule" ); - - bool res = getGeneratesEpsilon ( ); - setGeneratesEpsilon ( false ); - return res; - } else if ( rightHandSide.size ( ) == 1 ) { - return removeRule ( leftHandSide, rightHandSide[0] ); - } else if ( rightHandSide.size ( ) == 2 ) { - return removeRule ( leftHandSide, ext::make_pair ( rightHandSide[0], rightHandSide[1] ) ); - } else { - throw GrammarException ( "Invalid right hand side" ); - } -} - template < class SymbolType > void RightRG < SymbolType >::setGeneratesEpsilon ( bool genEps ) { generatesEpsilon = genEps; diff --git a/alib2data/src/grammar/xml/ContextFree/LG.h b/alib2data/src/grammar/xml/ContextFree/LG.h index 18da53d7a5d9bf93f3fe4c9bed319ae16ec9e462..08be7de72639d4c61d3499e6843500116588f39f 100644 --- a/alib2data/src/grammar/xml/ContextFree/LG.h +++ b/alib2data/src/grammar/xml/ContextFree/LG.h @@ -27,6 +27,7 @@ #include <grammar/ContextFree/LG.h> #include "../common/GrammarFromXMLParser.h" #include "../common/GrammarToXMLComposer.h" +#include <grammar/AddRawRule.h> namespace core { @@ -114,7 +115,7 @@ void xmlApi < grammar::LG < SymbolType > >::parseRule ( ext::deque < sax::Token SymbolType lhs = grammar::GrammarFromXMLParser::parseRuleSingleSymbolLHS < SymbolType > ( input ); ext::vector < SymbolType > rhs = grammar::GrammarFromXMLParser::parseRuleRHS < SymbolType > ( input ); - grammar.addRawRule ( std::move ( lhs ), std::move ( rhs ) ); + grammar::AddRawRule::addRawRule ( grammar, std::move ( lhs ), std::move ( rhs ) ); } template < class SymbolType > diff --git a/alib2data/src/grammar/xml/Regular/LeftLG.h b/alib2data/src/grammar/xml/Regular/LeftLG.h index a55316387d41291888252cd2f88e39bc25af0d86..87a3628ae7c60fca53340fa5446e9ea23fa1c57b 100644 --- a/alib2data/src/grammar/xml/Regular/LeftLG.h +++ b/alib2data/src/grammar/xml/Regular/LeftLG.h @@ -28,6 +28,8 @@ #include "../common/GrammarFromXMLParser.h" #include "../common/GrammarToXMLComposer.h" +#include <grammar/AddRawRule.h> + namespace core { template < class SymbolType > @@ -114,7 +116,7 @@ void xmlApi < grammar::LeftLG < SymbolType > >::parseRule ( ext::deque < sax::To SymbolType lhs = grammar::GrammarFromXMLParser::parseRuleSingleSymbolLHS < SymbolType > ( input ); ext::vector < SymbolType > rhs = grammar::GrammarFromXMLParser::parseRuleRHS < SymbolType > ( input ); - grammar.addRawRule ( std::move ( lhs ), std::move ( rhs ) ); + grammar::AddRawRule::addRawRule ( grammar, std::move ( lhs ), std::move ( rhs ) ); } template < class SymbolType > diff --git a/alib2data/src/grammar/xml/Regular/RightLG.h b/alib2data/src/grammar/xml/Regular/RightLG.h index 163b34f321c5c5f784da9bc7e3b143f3303338f7..347ab204aa076647d3dc8ffb61c1d9162db058b0 100644 --- a/alib2data/src/grammar/xml/Regular/RightLG.h +++ b/alib2data/src/grammar/xml/Regular/RightLG.h @@ -28,6 +28,8 @@ #include "../common/GrammarFromXMLParser.h" #include "../common/GrammarToXMLComposer.h" +#include <grammar/AddRawRule.h> + namespace core { template < class SymbolType > @@ -114,7 +116,7 @@ void xmlApi < grammar::RightLG < SymbolType > >::parseRule ( ext::deque < sax::T SymbolType lhs = grammar::GrammarFromXMLParser::parseRuleSingleSymbolLHS < SymbolType > ( input ); ext::vector < SymbolType > rhs = grammar::GrammarFromXMLParser::parseRuleRHS < SymbolType > ( input ); - grammar.addRawRule ( std::move ( lhs ), std::move ( rhs ) ); + grammar::AddRawRule::addRawRule ( grammar, std::move ( lhs ), std::move ( rhs ) ); } template < class SymbolType > diff --git a/alib2str/src/grammar/properties/IsFITDefinition.h b/alib2str/src/grammar/properties/IsFITDefinition.h index ebd9679411d6ca5d725c3ead691f7c4ef3f6cc0e..cc73dc14873fccb46c41267af3c038065731743c 100644 --- a/alib2str/src/grammar/properties/IsFITDefinition.h +++ b/alib2str/src/grammar/properties/IsFITDefinition.h @@ -26,7 +26,8 @@ bool IsFITDefinition::isFITDefinition( const T & grammar ) { if ( ! grammar.getGeneratesEpsilon( ) ) return true; - for ( const auto & rule : grammar.getRawRules ( ) ) + auto rawRules = grammar::RawRules::getRawRules ( grammar ); + for ( const auto & rule : rawRules ) for ( const auto & rhs : rule.second ) if ( std::find ( rhs.begin ( ), rhs.end ( ), grammar.getInitialSymbol ( ) ) != rhs.end ( ) ) return false; diff --git a/alib2str/src/grammar/string/common/GrammarFromStringParserCommon.h b/alib2str/src/grammar/string/common/GrammarFromStringParserCommon.h index 3fb6bc532b0f9dd461dfdd2ed3ce0b49e26e8929..bc40f61eadaf59a5aaca6b48230beb69ff003a94 100644 --- a/alib2str/src/grammar/string/common/GrammarFromStringParserCommon.h +++ b/alib2str/src/grammar/string/common/GrammarFromStringParserCommon.h @@ -19,6 +19,8 @@ #include <core/stringApi.hpp> +#include <grammar/AddRawRule.h> + namespace grammar { class GrammarFromStringParserCommon { @@ -182,7 +184,7 @@ T GrammarFromStringParserCommon::parseCFLikeGrammar(std::istream& input) { T grammar(nonterminals, terminals, initialSymbol); for(const auto& rule : rules) { for(const auto& ruleRHS : rule.second) { - grammar.addRawRule(rule.first, ruleRHS); + grammar::AddRawRule::addRawRule(grammar,rule.first, ruleRHS); } } return grammar; diff --git a/alib2str/src/grammar/string/common/GrammarToStringComposerCommon.h b/alib2str/src/grammar/string/common/GrammarToStringComposerCommon.h index d10aad65ae782637c4904c4eb44bebd845e85aa8..2a836af1428a54f087d873063e59217280fb3da1 100644 --- a/alib2str/src/grammar/string/common/GrammarToStringComposerCommon.h +++ b/alib2str/src/grammar/string/common/GrammarToStringComposerCommon.h @@ -12,6 +12,8 @@ #include <core/stringApi.hpp> +#include <grammar/RawRules.h> + namespace grammar { class GrammarToStringComposerCommon { @@ -52,7 +54,8 @@ void GrammarToStringComposerCommon::composeCFLikeGrammar(std::ostream& output, c output << "}," << std::endl; output << "{ "; first = true; - for(const auto& rule : grammar.getRawRules() ) { + auto rawRules = grammar::RawRules::getRawRules ( grammar ); + for(const auto& rule : rawRules ) { if(first) first = false; else