Skip to content
Snippets Groups Projects
Commit 8d7892de authored by Ing. Jan Trávníček's avatar Ing. Jan Trávníček
Browse files

Merge branch 'grammarprop_nullable_unitrules' into 'master'

Grammarprop Nullable Unitrules

Dear emperor,
 please consider merging this branch.
parents 49a3ca04 8b714c74
No related branches found
No related tags found
No related merge requests found
......@@ -104,5 +104,81 @@ template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols(
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::RightLG & grammar );
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::RightRG & grammar );
 
template<class T>
std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals(const T& grammar) {
std::deque<std::set<alphabet::Symbol>> Ni;
Ni.push_back(std::set<alphabet::Symbol>{ });
int i = 1;
while(true) {
Ni.push_back(std::set<alphabet::Symbol>{ });
for(const auto& rule : grammar.getRawRules()) {
for(const auto& rhs : rule.second) {
if(rhs.size() == 0 || std::all_of(rhs.begin(), rhs.end(), [Ni, i](const alphabet::Symbol& symb){return Ni.at(i-1).count(symb);})) {
Ni.at(i).insert(rule.first);
}
}
}
if(Ni.at(i) == Ni.at(i-1))
break;
i += 1;
}
return Ni.at(i);
}
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::CFG& grammar );
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::EpsilonFreeCFG& grammar );
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::GNF& grammar );
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::CNF& grammar );
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::LG& grammar );
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::LeftLG& grammar );
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::LeftRG& grammar );
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::RightLG& grammar );
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::RightRG& grammar );
template<class T>
std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const T& grammar, const alphabet::Symbol& nonterminal) {
if(grammar.getNonterminalAlphabet().count(nonterminal) == 0) {
throw exception::AlibException("Nonterminal symbol \"" + (std::string) nonterminal + "\" is not present in grammar.");
}
std::deque<std::set<alphabet::Symbol>> Ni;
Ni.push_back(std::set<alphabet::Symbol>{nonterminal});
int i = 1;
while(true) {
Ni.push_back(Ni.at(i-1));
for(const auto&rule : grammar.getRawRules()) {
const alphabet::Symbol& lhs = rule.first;
for(const auto& rhs : rule.second) {
if(Ni.at(i-1).count(lhs) && rhs.size() == 1 && grammar.getNonterminalAlphabet().count(rhs.front())) {
Ni.at(i).insert(rhs.front());
}
}
}
if(Ni.at(i) == Ni.at(i-1))
break;
i += 1;
}
return Ni.at(i);
}
 
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::CFG& grammar, const alphabet::Symbol& nonterminal);
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::EpsilonFreeCFG& grammar, const alphabet::Symbol& nonterminal);
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::GNF& grammar, const alphabet::Symbol& nonterminal);
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::CNF& grammar, const alphabet::Symbol& nonterminal);
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::LG& grammar, const alphabet::Symbol& nonterminal);
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::LeftLG& grammar, const alphabet::Symbol& nonterminal);
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::LeftRG& grammar, const alphabet::Symbol& nonterminal);
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::RightLG& grammar, const alphabet::Symbol& nonterminal);
template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::RightRG& grammar, const alphabet::Symbol& nonterminal);
} /* namespace grammar */
......@@ -5,8 +5,8 @@
* Author: Tomas Pecka
*/
 
#ifndef GRAMMAR_PROPERTIED_CFG_H_
#define GRAMMAR_PROPERTIED_CFG_H_
#ifndef GRAMMAR_PROPERTIES_CFG_H_
#define GRAMMAR_PROPERTIES_CFG_H_
 
#include <algorithm>
#include <deque>
......@@ -30,12 +30,36 @@ public:
static std::set<alphabet::Symbol> getProductiveNonterminals( const T & grammar );
 
/**
* Implements
* Implements
*/
template<class T>
static std::set<alphabet::Symbol> getUnreachableSymbols( const T & grammar );
/**
* Retrieve all nullable nonterminals from grammar
* Nullable nonterminal is such nonterminal A for which holds that A ->^* \eps
*
* Source: Melichar, algorithm 2.4, step 1
*
* @param grammar grammar
* @return set of nullable nonterminals from grammar
*/
template<class T>
static std::set<alphabet::Symbol> getNullableNonterminals(const T& grammar);
/**
* Retrieves set N = {B : A->^* B} for given grammar and nonterminal
*
* Source: Melichar, algorithm 2.6, step 1
*
* @param grammar grammar
* @param nonterminal nonterminal
* @return set of nonterminals for which we can be derived from giveUnitRuleCyclen nonterminals in finite number of steps
*/
template<class T>
static std::set<alphabet::Symbol> getNonterminalUnitRuleCycle(const T& grammar, const alphabet::Symbol& nonterminal);
};
 
}
} /* namespace grammar */
 
#endif /* GRAMMAR_PROPERTIED_CFG_H_ */
#endif /* GRAMMAR_PROPERTIES_CFG_H_ */
#include "GrammarPropertiesTest.h"
#include <factory/DataFactory.hpp>
#include <label/PrimitiveLabel.h>
#include <alphabet/LabeledSymbol.h>
#include <alphabet/Symbol.h>
#include "grammar/GrammarPropertiesCFG.h"
#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
CPPUNIT_TEST_SUITE_REGISTRATION( GrammarPropertiesTest );
void GrammarPropertiesTest::setUp() {
}
void GrammarPropertiesTest::tearDown() {
}
void GrammarPropertiesTest::testNullable() {
alphabet::Symbol X = alphabet::symbolFrom('X');
alphabet::Symbol Y = alphabet::symbolFrom('Y');
alphabet::Symbol Z = alphabet::symbolFrom('Z');
alphabet::Symbol d = alphabet::symbolFrom('d');
grammar::CFG grammar(X);
grammar.setTerminalAlphabet({d});
grammar.setNonterminalAlphabet({{X, Y, Z}});
grammar.setInitialSymbol(X);
grammar.addRule(X, std::vector<alphabet::Symbol>{ d });
grammar.addRule(X, std::vector<alphabet::Symbol>{ Y });
grammar.addRule(Y, std::vector<alphabet::Symbol>{ d });
grammar.addRule(Y, std::vector<alphabet::Symbol>{ });
grammar.addRule(Z, std::vector<alphabet::Symbol>{ d });
grammar.addRule(Z, std::vector<alphabet::Symbol>{ X, Y, Z });
std::set<alphabet::Symbol> res = {X, Y};
CPPUNIT_ASSERT(res == grammar::GrammarPropertiesCFG::getNullableNonterminals(grammar));
}
void GrammarPropertiesTest::testUnitRules() {
alphabet::Symbol S = alphabet::symbolFrom('S');
alphabet::Symbol A = alphabet::symbolFrom('A');
alphabet::Symbol B = alphabet::symbolFrom('B');
alphabet::Symbol C = alphabet::symbolFrom('C');
alphabet::Symbol a = alphabet::symbolFrom('a');
alphabet::Symbol b = alphabet::symbolFrom('b');
grammar::LeftLG llg(S);
llg.setTerminalAlphabet({a, b});
llg.setNonterminalAlphabet({S, A, B, C});
llg.setInitialSymbol(S);
llg.addRule(S, std::make_pair(A, std::vector<alphabet::Symbol>{}));
llg.addRule(S, std::make_pair(B, std::vector<alphabet::Symbol>{}));
llg.addRule(A, std::make_pair(A, std::vector<alphabet::Symbol>{a}));
llg.addRule(A, std::make_pair(B, std::vector<alphabet::Symbol>{}));
llg.addRule(A, std::make_pair(C, std::vector<alphabet::Symbol>{}));
llg.addRule(B, std::make_pair(B, std::vector<alphabet::Symbol>{b, a}));
llg.addRule(B, std::make_pair(C, std::vector<alphabet::Symbol>{b}));
llg.addRule(C, {b});
llg.addRule(C, std::make_pair(C, std::vector<alphabet::Symbol>{a}));
std::set<alphabet::Symbol> N_S = {S, A, B, C};
std::set<alphabet::Symbol> N_A = {A, B, C};
std::set<alphabet::Symbol> N_B = {B};
std::set<alphabet::Symbol> N_C = {C};
CPPUNIT_ASSERT(N_S == grammar::GrammarPropertiesCFG::getNonterminalUnitRuleCycle(llg, S));
CPPUNIT_ASSERT(N_A == grammar::GrammarPropertiesCFG::getNonterminalUnitRuleCycle(llg, A));
CPPUNIT_ASSERT(N_B == grammar::GrammarPropertiesCFG::getNonterminalUnitRuleCycle(llg, B));
CPPUNIT_ASSERT(N_C == grammar::GrammarPropertiesCFG::getNonterminalUnitRuleCycle(llg, C));
}
#ifndef GRAMMAR_PROPERTIES_TEST_H_
#define GRAMMAR_PROPERTIES_TEST_H_
#include <cppunit/extensions/HelperMacros.h>
class GrammarPropertiesTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( GrammarPropertiesTest );
CPPUNIT_TEST( testUnitRules );
CPPUNIT_TEST( testNullable );
CPPUNIT_TEST_SUITE_END();
public:
void setUp();
void tearDown();
void testUnitRules();
void testNullable();
};
#endif /* GRAMMAR_PROPERTIES_TEST_H_ */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment