Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
RandomGrammarFactory.h
Go to the documentation of this file.
1
6#pragma once
7
8#include <string>
9
10#include <ext/algorithm>
11#include <ext/random>
12
13#include <alib/deque>
14#include <alib/set>
15
17
19
20namespace grammar {
21
22namespace generate {
23
25public:
38 template < class TerminalSymbolType, class NonterminalSymbolType >
40
54 static grammar::CFG < std::string, std::string > generateCFG( size_t nonterminalsCount, size_t terminalsCount, bool randomizedAlphabet, double density );
55
56private:
57 template < class TerminalSymbolType, class NonterminalSymbolType >
59};
60
61template < class TerminalSymbolType, class NonterminalSymbolType >
63 ext::deque < TerminalSymbolType > terminals2 ( terminals.begin ( ), terminals.end ( ) );
64 ext::deque < NonterminalSymbolType > nonterminals2 ( nonterminals.begin ( ), nonterminals.end ( ) );
65 return RandomGrammarFactory::randomCFG ( nonterminals2, terminals2, density );
66}
67
68template < class TerminalSymbolType, class NonterminalSymbolType >
69grammar::CFG < TerminalSymbolType, NonterminalSymbolType > RandomGrammarFactory::randomCFG ( const ext::deque < NonterminalSymbolType > & nonterminals, const ext::deque < TerminalSymbolType > & terminals, double density ) {
70 if( terminals.empty ( ) )
71 throw exception::CommonException( "Terminals count must be greater than 0." );
72
73 if( nonterminals.empty ( ) )
74 throw exception::CommonException( "Nonterminals count must be greater than 0." );
75
77 grammar.setTerminalAlphabet({terminals.begin(), terminals.end()});
78 grammar.setNonterminalAlphabet({nonterminals.begin(), nonterminals.end()});
79
81 grammar.addRule(grammar.getInitialSymbol(), {});
82
83 int rules = 0;
84 while(rules < terminals.size() * nonterminals.size() * density / 100) {
85 const NonterminalSymbolType& lhs = nonterminals[ext::random_devices::semirandom() % nonterminals.size()];
86
87 int rhsSize = ext::random_devices::semirandom() % 5;
89 int nonterminalsOnRHS = 0;
90 for(int i = 0; i < rhsSize; i++) {
91 if(ext::random_devices::semirandom() % (nonterminals.size() + terminals.size()) < nonterminals.size()) {
92 rhs.push_back(ext::variant < TerminalSymbolType, NonterminalSymbolType > ( nonterminals[ext::random_devices::semirandom() % nonterminals.size()]));
93 nonterminalsOnRHS++;
94 } else {
96 }
97 }
98 rules += nonterminalsOnRHS;
99 grammar.addRule(lhs, rhs);
100 }
101
102 return grammar;
103}
104
105} /* namespace generate */
106
107} /* namespace grammar */
108
Basic exception from which all other exceptions are derived.
Definition: CommonException.h:21
Class extending the deque class from the standard library. Original reason is to allow printing of th...
Definition: deque.hpp:44
auto begin() &
Inherited behavior of begin for non-const instance.
Definition: deque.hpp:100
auto end() &
Inherited behavior of end for non-const instance.
Definition: deque.hpp:130
static semirandom_device & semirandom
The reference to singleton semirandom device.
Definition: random.hpp:147
Definition: set.hpp:44
auto begin() &
Inherited behavior of begin for non-const instance.
Definition: set.hpp:99
auto end() &
Inherited behavior of end for non-const instance.
Definition: set.hpp:129
Implementation of the variant class allowing to store any type of those listed in the template parame...
Definition: variant.hpp:98
Class extending the vector class from the standard library. Original reason is to allow printing of t...
Definition: vector.hpp:45
Context free grammar in Chomsky hierarchy or type 2 in Chomsky hierarchy. Generates context free lang...
Definition: CFG.h:67
Definition: RandomGrammarFactory.h:24
static grammar::CFG< TerminalSymbolType, NonterminalSymbolType > generateCFG(ext::set< NonterminalSymbolType > nonterminals, ext::set< TerminalSymbolType > terminals, double density)
Definition: RandomGrammarFactory.h:62
return grammar
Definition: ToGrammarLeftRG.h:99
int i
Definition: AllEpsilonClosure.h:118
Definition: ToAutomaton.h:24