Newer
Older
/*
* RandomGrammarFactory.cpp
*
* Created on: 27. 3. 2014
* Author: Tomas Pecka
*/
#include "RandomGrammarFactory.h"
#include <exception/CommonException.h>
#include <alib/algorithm>
#include <alib/random>
#include <registration/AlgoRegistration.hpp>
namespace grammar {
namespace generate {
grammar::CFG < > RandomGrammarFactory::generateCFG( ext::set<DefaultSymbolType> nonterminals, ext::set<DefaultSymbolType> terminals, double density ) {
ext::deque<DefaultSymbolType> terminals2(terminals.begin(), terminals.end());
ext::deque<DefaultSymbolType> nonterminals2(nonterminals.begin(), nonterminals.end());
return RandomGrammarFactory::randomCFG( nonterminals2, terminals2, density );
}
auto GenerateCFG1 = registration::AbstractRegister < RandomGrammarFactory, grammar::CFG < >, ext::set < DefaultSymbolType >, ext::set < DefaultSymbolType >, double > ( RandomGrammarFactory::generateCFG, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "nonterminals", "terminals", "density" );
grammar::CFG < > RandomGrammarFactory::generateCFG( size_t nonterminalsCount, size_t terminalsCount, bool randomizedAlphabet, double density ) {
throw exception::CommonException("Too big terminals count.");
for(int i = 0; i < 26; i++) symbols.push_back(DefaultSymbolType((char)(i + 'a')));
if(randomizedAlphabet) shuffle(symbols.begin(), symbols.end(), ext::random_devices::semirandom);
ext::deque<DefaultSymbolType> terminals(symbols.begin(), symbols.begin() + terminalsCount);
throw exception::CommonException("Too big nonterminals count.");
for(int i = 0; i < 26; i++) symbols2.push_back(DefaultSymbolType((char)(i + 'A')));
if(randomizedAlphabet) shuffle(symbols2.begin(), symbols2.end(), ext::random_devices::semirandom);
ext::deque<DefaultSymbolType> nonterminals(symbols2.begin(), symbols2.begin() + nonterminalsCount);
return RandomGrammarFactory::randomCFG( nonterminals, terminals, density );
}
auto GenerateCFG2 = registration::AbstractRegister < RandomGrammarFactory, grammar::CFG < >, size_t, size_t, bool, double> ( RandomGrammarFactory::generateCFG, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "nonterminalsCount", "terminalsCount", "randomizedAlphabet", "density" );
grammar::CFG < > RandomGrammarFactory::randomCFG( const ext::deque<DefaultSymbolType>& nonterminals, const ext::deque<DefaultSymbolType> & terminals, double density ) {
throw exception::CommonException( "Terminals count must be greater than 0." );
throw exception::CommonException( "Nonterminals count must be greater than 0." );
grammar.setTerminalAlphabet({terminals.begin(), terminals.end()});
grammar.setNonterminalAlphabet({nonterminals.begin(), nonterminals.end()});
grammar.addRule(grammar.getInitialSymbol(), {});
int rules = 0;
while(rules < terminals.size() * nonterminals.size() * density / 100) {
const DefaultSymbolType& lhs = nonterminals[ext::random_devices::semirandom() % nonterminals.size()];
int rhsSize = ext::random_devices::semirandom() % 5;
ext::vector<ext::variant<DefaultSymbolType, DefaultSymbolType>> rhs;
int nonterminalsOnRHS = 0;
for(int i = 0; i < rhsSize; i++) {
if(ext::random_devices::semirandom() % (nonterminals.size() + terminals.size()) < nonterminals.size()) {
rhs.push_back(ext::variant < DefaultSymbolType, DefaultSymbolType > ( nonterminals[ext::random_devices::semirandom() % nonterminals.size()]));
rhs.push_back(ext::variant < DefaultSymbolType, DefaultSymbolType > ( terminals[ext::random_devices::semirandom() % terminals.size()]));