Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
ToGNF.h
Go to the documentation of this file.
1
6#pragma once
7
8#include <ext/algorithm>
9
10#include <alib/map>
11
21
22#include "EpsilonRemover.h"
23#include "SimpleRulesRemover.h"
27
28namespace grammar {
29
30namespace simplify {
31
36class ToGNF {
37 template < class TerminalSymbolType, class NonterminalSymbolType >
39 template < class TerminalSymbolType, class NonterminalSymbolType >
41
42public:
53 template < class TerminalSymbolType, class NonterminalSymbolType >
55
66 template < class TerminalSymbolType, class NonterminalSymbolType >
68
79 template < class TerminalSymbolType, class NonterminalSymbolType >
81
92 template < class TerminalSymbolType, class NonterminalSymbolType >
94
105 template < class TerminalSymbolType, class NonterminalSymbolType >
107
118 template < class TerminalSymbolType, class NonterminalSymbolType >
120
131 template < class TerminalSymbolType, class NonterminalSymbolType >
133
144 template < class TerminalSymbolType, class NonterminalSymbolType >
146
157 template < class TerminalSymbolType, class NonterminalSymbolType >
159};
160
161template < class TerminalSymbolType, class NonterminalSymbolType >
164 res.setNonterminalAlphabet(grammar.getNonterminalAlphabet());
165 res.setTerminalAlphabet(grammar.getTerminalAlphabet());
166 res.setGeneratesEpsilon(grammar.getGeneratesEpsilon());
167
168 for ( const std::pair < const NonterminalSymbolType, ext::set<ext::vector<ext::variant < TerminalSymbolType, NonterminalSymbolType > > > > & rule : grammar.getRules ( ) ) {
169 for(const ext::vector < ext::variant < TerminalSymbolType, NonterminalSymbolType > > & singleRHS : rule.second) {
170 if(res.getTerminalAlphabet().count(singleRHS[0])) { //do not substitute terminals
171 res.addRule(rule.first, singleRHS);
172 continue;
173 }
174 const ext::variant < TerminalSymbolType, NonterminalSymbolType > & secondLHS = singleRHS[0];
175 if(grammar.getRules().find(secondLHS) == grammar.getRules().end()) { //is there any right hand side to substitue with?
176 //if not well this rule does not generate anything anyway
177 continue;
178 }
179
180 for(const ext::vector < ext::variant < TerminalSymbolType, NonterminalSymbolType > > & secondSingleRHS : grammar.getRules().find(secondLHS)->second) { // do the substitution
182 newRHS.insert(newRHS.end(), singleRHS.begin() + 1, singleRHS.end());
183 res.addRule(rule.first, newRHS);
184 }
185 }
186 }
187 return res;
188}
189
190template < class TerminalSymbolType, class NonterminalSymbolType >
193 while(true) {
195
196 if(step == nextStep) break;
197 step = std::move(nextStep);
198 }
199
201 res.setTerminalAlphabet(step.getTerminalAlphabet());
202 for ( const NonterminalSymbolType & nonterminal : step.getNonterminalAlphabet ( ) )
203 res.addNonterminalSymbol ( ext::variant < TerminalSymbolType, NonterminalSymbolType > ( nonterminal ) );
204 res.setGeneratesEpsilon(step.getGeneratesEpsilon());
206 for ( const TerminalSymbolType & terminal : step.getTerminalAlphabet ( ) ) {
207 ext::variant < TerminalSymbolType, NonterminalSymbolType > primed = common::createUnique ( terminal, res.getTerminalAlphabet(), res.getNonterminalAlphabet());
208 terminalToPrimed.insert(std::make_pair(terminal, primed));
209 res.addNonterminalSymbol(primed);
211 }
212 for(const auto& rule : step.getRules()) {
213 for(const auto& rhs : rule.second) {
215 bool first = true;
217 if(first) {
218 first = false;
219 continue;
220 }
221
222 if(res.getNonterminalAlphabet().count(rhsSymbol))
223 convertedNonterminals.push_back(rhsSymbol);
224 else
225 convertedNonterminals.push_back(terminalToPrimed.find(rhsSymbol)->second);
226 }
227 res.addRule(rule.first, ext::make_pair(rhs[0].template get < TerminalSymbolType > ( ), std::move(convertedNonterminals)));
228 }
229 }
230 return res;
231}
232
233template < class TerminalSymbolType, class NonterminalSymbolType >
236}
237
238template < class TerminalSymbolType, class NonterminalSymbolType >
241}
242
243template < class TerminalSymbolType, class NonterminalSymbolType >
246}
247
248template < class TerminalSymbolType, class NonterminalSymbolType >
250 return grammar;
251}
252
253template < class TerminalSymbolType, class NonterminalSymbolType >
256}
257
258template < class TerminalSymbolType, class NonterminalSymbolType >
261}
262
263template < class TerminalSymbolType, class NonterminalSymbolType >
266}
267
268template < class TerminalSymbolType, class NonterminalSymbolType >
271}
272
273template < class TerminalSymbolType, class NonterminalSymbolType >
275 return grammar;
276}
277
278} /* namespace simplify */
279
280} /* namespace grammar */
281
Class extending the map class from the standard library. Original reason is to allow printing of the ...
Definition: map.hpp:48
std::pair< iterator, bool > insert(const T &key, const R &value)
Insert variant with explicit key and value parameters.
Definition: map.hpp:118
Definition: set.hpp:44
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
Chomsky normal form of a context free grammar in Chomsky hierarchy or type 2 in Chomsky hierarchy....
Definition: CNF.h:66
Context free grammar without epsilon rules in Chomsky hierarchy or type 2 in Chomsky hierarchy....
Definition: EpsilonFreeCFG.h:65
Greibach normal form of a context free grammar in Chomsky hierarchy or type 2 in Chomsky hierarchy....
Definition: GNF.h:65
Context free grammar in Chomsky hierarchy or type 2 in Chomsky hierarchy. Generates context free lang...
Definition: LG.h:67
Left linear grammar in Chomsky hierarchy or type 3 in Chomsky hierarchy. Generates regular languages.
Definition: LeftLG.h:66
Left regular grammar in Chomsky hierarchy or type 3 in Chomsky hierarchy. Generates regular languages...
Definition: LeftRG.h:70
Right linear grammar in Chomsky hierarchy or type 3 in Chomsky hierarchy. Generates regular languages...
Definition: RightLG.h:65
Right regular grammar in Chomsky hierarchy or type 3 in Chomsky hierarchy. Generates regular language...
Definition: RightRG.h:70
static grammar::RightRG< TerminalSymbolType, NonterminalSymbolType > convert(const grammar::LeftRG< TerminalSymbolType, NonterminalSymbolType > &grammar)
Definition: ToGrammarRightRG.h:37
static grammar::EpsilonFreeCFG< TerminalSymbolType, NonterminalSymbolType > remove(const grammar::CFG< TerminalSymbolType, NonterminalSymbolType > &grammar)
Definition: EpsilonRemover.h:202
static grammar::EpsilonFreeCFG< TerminalSymbolType, NonterminalSymbolType > remove(const grammar::EpsilonFreeCFG< TerminalSymbolType, NonterminalSymbolType > &grammar)
Definition: LeftRecursionRemover.h:225
static grammar::CFG< TerminalSymbolType, NonterminalSymbolType > remove(const grammar::CFG< TerminalSymbolType, NonterminalSymbolType > &grammar)
Definition: SimpleRulesRemover.h:181
Definition: ToGNF.h:36
static grammar::GNF< TerminalSymbolType, ext::variant< TerminalSymbolType, NonterminalSymbolType > > convert(const grammar::CFG< TerminalSymbolType, NonterminalSymbolType > &grammar)
Definition: ToGNF.h:234
return grammar
Definition: ToGrammarLeftRG.h:99
return res
Definition: MinimizeByPartitioning.h:145
T createUnique(T object, const Alphabets &... alphabets)
Definition: createUnique.hpp:46
constexpr auto make_pair(T1 &&x, T2 &&y)
Definition: pair.hpp:79
Definition: ToAutomaton.h:24