Skip to content
Snippets Groups Projects
Commit 23b1c368 authored by Jan Trávníček's avatar Jan Trávníček
Browse files

Merge branch 'alib2' of gitlab.fit.cvut.cz:travnja3/automata-library into alib2

Conflicts:
	alib2algo/test-src/play/playTest.cpp
parents 733a03b6 97621abd
No related branches found
No related tags found
No related merge requests found
Showing
with 168 additions and 124 deletions
...@@ -338,9 +338,8 @@ void ConversionHandler::convertLRGtoRRG( void ) ...@@ -338,9 +338,8 @@ void ConversionHandler::convertLRGtoRRG( void )
switch( m_algorithm ) switch( m_algorithm )
{ {
default: default:
rg2rg::LeftToRightRegularGrammar conv( lrg ); rg2rg::LeftToRightRegularGrammar conv;
grammar::RightRG rrg = conv.convert(); alib::DataFactory::toStdout(conv.convert(lrg));
alib::DataFactory::toStdout(rrg);
break; break;
} }
} }
...@@ -352,9 +351,8 @@ void ConversionHandler::convertRRGtoLRG( void ) ...@@ -352,9 +351,8 @@ void ConversionHandler::convertRRGtoLRG( void )
switch( m_algorithm ) switch( m_algorithm )
{ {
default: default:
rg2rg::RightToLeftRegularGrammar conv( rrg ); rg2rg::RightToLeftRegularGrammar conv;
grammar::LeftRG lrg = conv.convert(); alib::DataFactory::toStdout(conv.convert(rrg));
alib::DataFactory::toStdout(lrg);
break; break;
} }
} }
......
...@@ -9,31 +9,22 @@ ...@@ -9,31 +9,22 @@
   
namespace rg2rg { namespace rg2rg {
   
LeftToRightRegularGrammar::LeftToRightRegularGrammar( const grammar::LeftRG & lrg ) : m_lrg( lrg ) { grammar::RightRG LeftToRightRegularGrammar::convert(const grammar::LeftRG& lrg)
}
LeftToRightRegularGrammar::~LeftToRightRegularGrammar( void )
{
}
grammar::RightRG LeftToRightRegularGrammar::convert( void )
{ {
// 1. // 1.
alphabet::Symbol s = alphabet::createUniqueSymbol( m_lrg.getInitialSymbol( ), m_lrg.getNonterminalAlphabet(), m_lrg.getTerminalAlphabet() ); alphabet::Symbol s = alphabet::createUniqueSymbol( lrg.getInitialSymbol( ), lrg.getNonterminalAlphabet(), lrg.getTerminalAlphabet() );
   
grammar::RightRG rrg( s ); grammar::RightRG rrg( s );
   
for(const auto & nonterminalSymbol : m_lrg.getNonterminalAlphabet() ) { for(const auto & nonterminalSymbol : lrg.getNonterminalAlphabet() ) {
rrg.addNonterminalSymbol( nonterminalSymbol ); rrg.addNonterminalSymbol( nonterminalSymbol );
} }
   
rrg.setTerminalAlphabet( m_lrg.getTerminalAlphabet( ) ); rrg.setTerminalAlphabet( lrg.getTerminalAlphabet( ) );
rrg.setGeneratesEpsilon( m_lrg.getGeneratesEpsilon( ) ); rrg.setGeneratesEpsilon( lrg.getGeneratesEpsilon( ) );
   
// 2 // 2
for( const auto & rule : m_lrg.getRules( ) ) { for( const auto & rule : lrg.getRules( ) ) {
const alphabet::Symbol& lhs = rule.first; const alphabet::Symbol& lhs = rule.first;
   
for(const auto & ruleRHS : rule.second ) { for(const auto & ruleRHS : rule.second ) {
...@@ -44,7 +35,7 @@ grammar::RightRG LeftToRightRegularGrammar::convert( void ) ...@@ -44,7 +35,7 @@ grammar::RightRG LeftToRightRegularGrammar::convert( void )
std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair( rhs.second, lhs ); std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair( rhs.second, lhs );
rrg.addRule( leftSide, rightSide ); rrg.addRule( leftSide, rightSide );
   
if( lhs == m_lrg.getInitialSymbol( ) ) { if( lhs == lrg.getInitialSymbol( ) ) {
alphabet::Symbol leftSide = rhs.first; alphabet::Symbol leftSide = rhs.first;
alphabet::Symbol rightSide = rhs.second; alphabet::Symbol rightSide = rhs.second;
rrg.addRule( leftSide, rightSide ); rrg.addRule( leftSide, rightSide );
...@@ -56,7 +47,7 @@ grammar::RightRG LeftToRightRegularGrammar::convert( void ) ...@@ -56,7 +47,7 @@ grammar::RightRG LeftToRightRegularGrammar::convert( void )
std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair( rhs, lhs ); std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair( rhs, lhs );
rrg.addRule( leftSide, rightSide ); rrg.addRule( leftSide, rightSide );
   
if( lhs == m_lrg.getInitialSymbol( ) ) { if( lhs == lrg.getInitialSymbol( ) ) {
alphabet::Symbol leftSide = rrg.getInitialSymbol( ); alphabet::Symbol leftSide = rrg.getInitialSymbol( );
alphabet::Symbol rightSide = rhs; alphabet::Symbol rightSide = rhs;
rrg.addRule( leftSide, rightSide ); rrg.addRule( leftSide, rightSide );
......
...@@ -17,24 +17,11 @@ namespace rg2rg ...@@ -17,24 +17,11 @@ namespace rg2rg
class LeftToRightRegularGrammar class LeftToRightRegularGrammar
{ {
public: public:
/** /**
* @param lrg Original left regular grammar.
*/
LeftToRightRegularGrammar( const grammar::LeftRG & lrg );
~LeftToRightRegularGrammar( void );
/**
* Performs conversion. * Performs conversion.
* @return right regular grammar which is equivalent to source left regular grammar. * @return right regular grammar which is equivalent to source left regular grammar.
*/ */
grammar::RightRG convert( void ); grammar::RightRG convert(const grammar::LeftRG& lrg);
protected:
/**
* input grammar
*/
const grammar::LeftRG & m_lrg;
}; };
   
} /* namespace rg2rg */ } /* namespace rg2rg */
......
...@@ -10,32 +10,22 @@ ...@@ -10,32 +10,22 @@
namespace rg2rg namespace rg2rg
{ {
   
RightToLeftRegularGrammar::RightToLeftRegularGrammar( const grammar::RightRG & rrg ) : m_rrg( rrg ) grammar::LeftRG RightToLeftRegularGrammar::convert(const grammar::RightRG& rrg)
{
}
RightToLeftRegularGrammar::~RightToLeftRegularGrammar( void )
{
}
grammar::LeftRG RightToLeftRegularGrammar::convert( void )
{ {
// 1. // 1.
alphabet::Symbol s = alphabet::createUniqueSymbol( m_rrg.getInitialSymbol( ), m_rrg.getNonterminalAlphabet(), m_rrg.getTerminalAlphabet() ); alphabet::Symbol s = alphabet::createUniqueSymbol( rrg.getInitialSymbol( ), rrg.getNonterminalAlphabet(), rrg.getTerminalAlphabet() );
   
grammar::LeftRG lrg(s); grammar::LeftRG lrg(s);
   
for(const auto & nonterminalSymbol : m_rrg.getNonterminalAlphabet()) { for(const auto & nonterminalSymbol : rrg.getNonterminalAlphabet()) {
lrg.addNonterminalSymbol( nonterminalSymbol ); lrg.addNonterminalSymbol( nonterminalSymbol );
} }
   
lrg.setTerminalAlphabet( m_rrg.getTerminalAlphabet( ) ); lrg.setTerminalAlphabet( rrg.getTerminalAlphabet( ) );
lrg.setGeneratesEpsilon( m_rrg.getGeneratesEpsilon( ) ); lrg.setGeneratesEpsilon( rrg.getGeneratesEpsilon( ) );
   
// 2. // 2.
for( const auto & rule : m_rrg.getRules( ) ) { for( const auto & rule : rrg.getRules( ) ) {
const alphabet::Symbol& lhs = rule.first; const alphabet::Symbol& lhs = rule.first;
   
for(const auto & ruleRHS : rule.second ) { for(const auto & ruleRHS : rule.second ) {
...@@ -46,7 +36,7 @@ grammar::LeftRG RightToLeftRegularGrammar::convert( void ) ...@@ -46,7 +36,7 @@ grammar::LeftRG RightToLeftRegularGrammar::convert( void )
std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair( lhs, rhs.first ); std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair( lhs, rhs.first );
lrg.addRule( leftSide, rightSide ); lrg.addRule( leftSide, rightSide );
   
if( lhs == m_rrg.getInitialSymbol( ) ) { if( lhs == rrg.getInitialSymbol( ) ) {
alphabet::Symbol leftSide = rhs.second; alphabet::Symbol leftSide = rhs.second;
alphabet::Symbol rightSide = rhs.first; alphabet::Symbol rightSide = rhs.first;
lrg.addRule( leftSide, rightSide ); lrg.addRule( leftSide, rightSide );
...@@ -58,7 +48,7 @@ grammar::LeftRG RightToLeftRegularGrammar::convert( void ) ...@@ -58,7 +48,7 @@ grammar::LeftRG RightToLeftRegularGrammar::convert( void )
std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair ( lhs, rhs ); std::pair<alphabet::Symbol, alphabet::Symbol> rightSide = std::make_pair ( lhs, rhs );
lrg.addRule( leftSide, rightSide ); lrg.addRule( leftSide, rightSide );
   
if( lhs == m_rrg.getInitialSymbol( ) ) { if( lhs == rrg.getInitialSymbol( ) ) {
alphabet::Symbol leftSide = lrg.getInitialSymbol( ); alphabet::Symbol leftSide = lrg.getInitialSymbol( );
alphabet::Symbol rightSide = rhs; alphabet::Symbol rightSide = rhs;
lrg.addRule( leftSide, rightSide ); lrg.addRule( leftSide, rightSide );
......
...@@ -20,24 +20,11 @@ namespace rg2rg ...@@ -20,24 +20,11 @@ namespace rg2rg
class RightToLeftRegularGrammar class RightToLeftRegularGrammar
{ {
public: public:
/**
* @param rrg Original right regular grammar.
*/
RightToLeftRegularGrammar( const grammar::RightRG & rrg );
~RightToLeftRegularGrammar( void );
/** /**
* Performs conversion. * Performs conversion.
* @return left regular grammar which is equivalent to source right regular grammar. * @return left regular grammar which is equivalent to source right regular grammar.
*/ */
grammar::LeftRG convert( void ); grammar::LeftRG convert(const grammar::RightRG& rrg);
private:
/**
*
*/
const grammar::RightRG & m_rrg;
}; };
   
} /* namespace rg2rg */ } /* namespace rg2rg */
......
...@@ -11,6 +11,11 @@ ...@@ -11,6 +11,11 @@
   
namespace epsilon { namespace epsilon {
   
automaton::NFA EpsilonNFAEpsilonRemover::remove(const automaton::NFA& origFSM)
{
return origFSM;
}
automaton::NFA EpsilonNFAEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM ) { automaton::NFA EpsilonNFAEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM ) {
automaton::NFA fsm; automaton::NFA fsm;
   
......
...@@ -19,7 +19,8 @@ namespace epsilon { ...@@ -19,7 +19,8 @@ namespace epsilon {
   
class EpsilonNFAEpsilonRemover { class EpsilonNFAEpsilonRemover {
public: public:
static automaton::NFA remove( const automaton::EpsilonNFA & ); static automaton::NFA remove(const automaton::EpsilonNFA &);
static automaton::NFA remove(const automaton::NFA &);
}; };
   
} /* namespace epsilon */ } /* namespace epsilon */
......
#include "playTest.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "determinize/nfa/NFADeterminizer.h"
#include "minimize/dfa/MinimizeDFA.h"
#include "generator/RandomAutomatonFactory.h"
#include "normalize/dfa/NormalizeDFA.h"
#include "trim/automaton/TrimFSM.h"
#include "epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h"
#include "minimize/dfa/MinimizeDFA.h"
//#include "conversions/fa2re/StateElimination.h"
//#include "conversions/fa2re/BrzozowskiAlgebraic.h"
//#include "conversions/re2fa/Glushkov.h"
//#include "conversions/re2fa/Thompson.h"
//#include "conversions/re2fa/Brzozowski.h"
#include "conversions/fa2rg/fa2lrg/FAtoLRGConverter.h"
#include "conversions/fa2rg/fa2rrg/FAtoRRGConverter.h"
#include "conversions/rg2fa/lrg2fa/LRGtoFAConverter.h"
#include "conversions/rg2fa/rrg2fa/RRGtoFAConverter.h"
//#include "conversions/rg2re/rrg2re/RRGAlgebraic.h"
//#include "conversions/rg2re/lrg2re/LRGAlgebraic.h"
//#include "conversions/re2rg/re2rrg/GlushkovRRG.h"
//#include "conversions/re2rg/re2rrg/BrzozowskiDerivationRRG.h"
#include "conversions/rg2rg/lrg2rrg/LeftToRightRegularGrammar.h"
#include "conversions/rg2rg/rrg2lrg/RightToLeftRegularGrammar.h"
#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
#define TEST_ITERATIONS 100
#define TEST_AUTOMATON_STATES_MAX 18
#define TEST_AUTOMATON_DENSITY_MAX 2.5
#define TEST_AUTOMATON_ALPHABET_MAX 4
CPPUNIT_TEST_SUITE_REGISTRATION( playTest );
void playTest::setUp()
{
srand(time(NULL));
}
void playTest::tearDown(){}
automaton::NFA playTest::randomNFA(void) const
{
return generator::RandomAutomatonFactory::generateNFA(
rand() % TEST_AUTOMATON_STATES_MAX + 1,
rand() % TEST_AUTOMATON_ALPHABET_MAX + 1,
static_cast<double> (rand()) / (static_cast<double> (RAND_MAX/TEST_AUTOMATON_DENSITY_MAX))
);
}
automaton::DFA playTest::mDFA(const automaton::NFA& automaton) const
{
automaton::NFA nfa = epsilon::EpsilonNFAEpsilonRemover::remove(automaton);
nfa = trim::TrimFSM::trim(nfa);
automaton::DFA dfa = determinize::NFADeterminizer::determinize(nfa);
dfa = trim::TrimFSM::trim(dfa);
dfa = minimize::MinimizeDFA::minimize(dfa);
dfa = normalize::NormalizeDFA::normalize(dfa);
return dfa;
}
/**
* Test case 1:
* - covers: FA -> LRG, FA -> RRG, RRG <-> LRG, RRG -> FA, LRG -> FA
* a. FA -> RRG -> LRG -> FA
* b. FA -> LRG -> RRG -> FA
*/
void playTest::testPlay1()
{
for(int i = 0; i < TEST_ITERATIONS; i++)
this->case1a();
for(int i = 0; i < TEST_ITERATIONS; i++)
this->case1b();
}
void playTest::case1a(void) const
{
fa2rg::FAtoRRGConverter fa2rrg;
rg2rg::RightToLeftRegularGrammar rrg2lrg;
rg2fa::LRGtoFAConverter lrg2fa;
automaton::NFA a1 = this->randomNFA();
automaton::NFA a2 = lrg2fa.convert(rrg2lrg.convert(fa2rrg.convert(a1)));
CPPUNIT_ASSERT(this->mDFA(a1) == this->mDFA(a2));
}
void playTest::case1b(void) const
{
fa2rg::FAtoLRGConverter fa2lrg;
rg2rg::LeftToRightRegularGrammar lrg2rrg;
rg2fa::RRGtoFAConverter rrg2fa;
automaton::NFA a1 = this->randomNFA();
automaton::NFA a2 = rrg2fa.convert(lrg2rrg.convert(fa2lrg.convert(a1)));
CPPUNIT_ASSERT(this->mDFA(a1) == this->mDFA(a2));
}
...@@ -3,17 +3,27 @@ ...@@ -3,17 +3,27 @@
   
#include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/HelperMacros.h>
   
#include <automaton/FSM/NFA.h>
#include <automaton/FSM/DFA.h>
class playTest : public CppUnit::TestFixture class playTest : public CppUnit::TestFixture
{ {
CPPUNIT_TEST_SUITE( playTest ); CPPUNIT_TEST_SUITE( playTest );
CPPUNIT_TEST( testPlay ); CPPUNIT_TEST( testPlay1 );
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
   
public: public:
void setUp(); void setUp();
void tearDown(); void tearDown();
   
void testPlay(); void testPlay1();
private:
automaton::NFA randomNFA(void) const;
automaton::DFA mDFA(const automaton::NFA& automaton) const;
void case1a(void) const;
void case1b(void) const;
}; };
   
#endif // PLAY_TEST_H_ #endif // PLAY_TEST_H_
...@@ -32,8 +32,8 @@ void rg2rgTest::testConversion() { ...@@ -32,8 +32,8 @@ void rg2rgTest::testConversion() {
rrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))))); rrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3))))));
rrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a"))))); rrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))));
   
rg2rg::RightToLeftRegularGrammar convertor(rrGrammar); rg2rg::RightToLeftRegularGrammar convertor;;
grammar::LeftRG lrGrammar = convertor.convert(); grammar::LeftRG lrGrammar = convertor.convert(rrGrammar);
   
grammar::LeftRG lrGrammarRef(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(4))))); grammar::LeftRG lrGrammarRef(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(4)))));
   
...@@ -64,8 +64,8 @@ void rg2rgTest::testConversion2() { ...@@ -64,8 +64,8 @@ void rg2rgTest::testConversion2() {
lrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2)))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))))); lrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2)))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b"))))));
lrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(4)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))))); lrGrammar.addRule(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(4)))), std::make_pair(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a"))))));
   
rg2rg::LeftToRightRegularGrammar convertor(lrGrammar); rg2rg::LeftToRightRegularGrammar convertor;
grammar::RightRG rrGrammar = convertor.convert(); grammar::RightRG rrGrammar = convertor.convert(lrGrammar);
   
grammar::RightRG rrGrammarRef(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(5))))); grammar::RightRG rrGrammarRef(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(5)))));
   
......
#include <list>
#include "playTest.h"
#include "conversions/re2fa/Glushkov.h"
#include "conversions/fa2re/BrzozowskiAlgebraic.h"
#include "determinize/nfa/NFADeterminizer.h"
#include "minimize/dfa/MinimizeDFA.h"
#include "regexp/unbounded/UnboundedRegExp.h"
#include "regexp/RegExpFromStringParser.h"
#include "automaton/FSM/NFA.h"
#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
CPPUNIT_TEST_SUITE_REGISTRATION( playTest );
void playTest::setUp() {
}
void playTest::tearDown() {
}
void playTest::testPlay() {
{
std::string input = "a+a* b*";
std::stringstream inputs(input);
regexp::RegExpFromStringParser parser(inputs);
regexp::UnboundedRegExp regexp1( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) );
re2fa::Glushkov glushkov1;
automaton::NFA nfa1 = glushkov1.convert(regexp1);
regexp::UnboundedRegExp regexp2( static_cast<const regexp::UnboundedRegExp &>( fa2re::BrzozowskiAlgebraic::convert(nfa1) ) );
re2fa::Glushkov glushkov2;
automaton::NFA nfa2 = glushkov2.convert(regexp2);
automaton::DFA dfa1 = determinize::NFADeterminizer::determinize(nfa1);
automaton::DFA dfa2 = determinize::NFADeterminizer::determinize(nfa2);
automaton::DFA mdfa1 = minimize::MinimizeDFA::minimize(dfa1);
automaton::DFA mdfa2 = minimize::MinimizeDFA::minimize(dfa2);
CPPUNIT_ASSERT( mdfa1 == mdfa2);
}
}
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