Newer
Older
/*
* RandomGrammarFactory.cpp
*
* Created on: 27. 3. 2014
* Author: Tomas Pecka
*/
#include "RandomGrammarFactory.h"
#include <grammar/Grammar.h>
#include <algorithm>
namespace grammar {
namespace generate {
grammar::CFG RandomGrammarFactory::generateCFG( std::set<alphabet::Symbol> nonterminals, std::set<alphabet::Symbol> terminals, double density ) {
std::deque<alphabet::Symbol> terminals2(terminals.begin(), terminals.end());
std::deque<alphabet::Symbol> nonterminals2(nonterminals.begin(), nonterminals.end());
return RandomGrammarFactory::randomCFG( nonterminals2, terminals2, density );
}
grammar::CFG RandomGrammarFactory::generateCFG( size_t nonterminalsCount, size_t terminalsCount, bool randomizedAlphabet, double density ) {
srand( time( NULL ) );
if(terminalsCount > 26)
throw exception::AlibException("Too big terminals count.");
std::vector<alphabet::Symbol> symbols;
for(int i = 0; i < 26; i++) symbols.push_back(alphabet::symbolFrom(i + 'a'));
if(randomizedAlphabet) random_shuffle(symbols.begin(), symbols.end());
std::deque<alphabet::Symbol> terminals(symbols.begin(), symbols.begin() + terminalsCount);
if(nonterminalsCount > 26)
throw exception::AlibException("Too big nonterminals count.");
std::vector<alphabet::Symbol> symbols2;
for(int i = 0; i < 26; i++) symbols2.push_back(alphabet::symbolFrom(i + 'A'));
if(randomizedAlphabet) random_shuffle(symbols2.begin(), symbols2.end());
std::deque<alphabet::Symbol> nonterminals(symbols2.begin(), symbols2.begin() + nonterminalsCount);
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
return RandomGrammarFactory::randomCFG( nonterminals, terminals, density );
}
grammar::CFG RandomGrammarFactory::randomCFG( const std::deque<alphabet::Symbol>& nonterminals, const std::deque<alphabet::Symbol> & terminals, double density ) {
if( terminals.size( ) <= 0 )
throw exception::AlibException( "Terminals count must be greater than 0." );
if( nonterminals.size( ) <= 0 )
throw exception::AlibException( "Nonterminals count must be greater than 0." );
srand( time( NULL ) );
grammar::CFG grammar(nonterminals.front());
grammar.setTerminalAlphabet({terminals.begin(), terminals.end()});
grammar.setNonterminalAlphabet({nonterminals.begin(), nonterminals.end()});
if(rand() % 2)
grammar.addRule(grammar.getInitialSymbol(), {});
int rules = 0;
while(rules < terminals.size() * nonterminals.size() * density / 100) {
const alphabet::Symbol& lhs = nonterminals[rand() % nonterminals.size()];
int rhsSize = rand() % 5;
std::vector<alphabet::Symbol> rhs;
int nonterminalsOnRHS = 0;
for(int i = 0; i < rhsSize; i++) {
if(rand() % (nonterminals.size() + terminals.size()) < nonterminals.size()) {
rhs.push_back(nonterminals[rand() % nonterminals.size()]);
nonterminalsOnRHS++;
} else {
rhs.push_back(terminals[rand() % terminals.size()]);
}
}
rules += nonterminalsOnRHS;
grammar.addRule(lhs, rhs);
}
return grammar;
}
} /* namespace generate */
} /* namespace grammar */