Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
AddRawRule.h
Go to the documentation of this file.
1
6#pragma once
7
8#include <alib/set>
9#include <alib/map>
19
20#include <grammar/Grammar.h>
21
22namespace grammar {
23
28public:
39 template < class TerminalSymbolType, class NonterminalSymbolType >
41
45 template < class TerminalSymbolType, class NonterminalSymbolType >
47
51 template < class TerminalSymbolType, class NonterminalSymbolType >
53
57 template < class TerminalSymbolType, class NonterminalSymbolType >
59
63 template < class TerminalSymbolType, class NonterminalSymbolType >
65
69 template < class TerminalSymbolType, class NonterminalSymbolType >
71
75 template < class TerminalSymbolType, class NonterminalSymbolType >
77
81 template < class TerminalSymbolType, class NonterminalSymbolType >
83
87 template < class TerminalSymbolType, class NonterminalSymbolType >
89};
90
91template < class TerminalSymbolType, class NonterminalSymbolType >
93 typename ext::vector < ext::variant < TerminalSymbolType, NonterminalSymbolType > >::iterator nonterminalPosition = rightHandSide.begin ( );
94
95 for ( ; nonterminalPosition != rightHandSide.end ( ); ++nonterminalPosition )
96 if ( grammar.getNonterminalAlphabet ( ).count ( * nonterminalPosition ) ) break;
97
98 if ( nonterminalPosition == rightHandSide.end ( ) ) {
100
102 rhs.push_back ( std::move ( symbol.template get < TerminalSymbolType > ( ) ) );
103
104 return grammar.addRule ( std::move ( leftHandSide ), std::move ( rhs ) );
105 } else {
108
109 std::for_each ( rightHandSide.begin ( ), nonterminalPosition, [ & ] ( ext::variant < TerminalSymbolType, NonterminalSymbolType > & symbol ) {
110 rhs1.push_back ( std::move ( symbol.template get < TerminalSymbolType > ( ) ) );
111 } );
112 std::for_each ( std::next ( nonterminalPosition ), rightHandSide.end ( ), [ & ] ( ext::variant < TerminalSymbolType, NonterminalSymbolType > & symbol ) {
113 rhs2.push_back ( std::move ( symbol.template get < TerminalSymbolType > ( ) ) );
114 } );
115
116 return grammar.addRule ( leftHandSide, ext::make_tuple ( std::move ( rhs1 ), std::move ( nonterminalPosition->template get < NonterminalSymbolType > ( ) ), std::move ( rhs2 ) ) );
117 }
118}
119
120template < class TerminalSymbolType, class NonterminalSymbolType >
122 if ( rightHandSide.empty ( ) ) {
123 if ( leftHandSide != grammar.getInitialSymbol ( ) )
124 throw GrammarException ( "Illegal left hand side of epsilon rule" );
125
126 bool res = grammar.getGeneratesEpsilon ( );
127 grammar.setGeneratesEpsilon ( true );
128 return !res;
129 } else {
130 TerminalSymbolType first = std::move ( rightHandSide[0].template get < TerminalSymbolType > ( ) );
131
133 std::for_each ( rightHandSide.begin ( ) + 1, rightHandSide.end ( ), [ & ] ( ext::variant < TerminalSymbolType, NonterminalSymbolType > & element ) {
134 rest.push_back ( std::move ( element.template get < NonterminalSymbolType > ( ) ) );
135 } );
136
137 return grammar.addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( first ), std::move ( rest ) ) );
138 }
139}
140
141template < class TerminalSymbolType, class NonterminalSymbolType >
143 if ( rightHandSide.empty ( ) ) {
144 if ( leftHandSide != grammar.getInitialSymbol ( ) )
145 throw GrammarException ( "Illegal left hand side of epsilon rule" );
146
147 bool res = grammar.getGeneratesEpsilon ( );
148 grammar.setGeneratesEpsilon ( true );
149 return ! res;
150 } else {
151 return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) );
152 }
153}
154
155template < class TerminalSymbolType, class NonterminalSymbolType >
157 if ( rightHandSide.empty ( ) ) {
158 if ( leftHandSide != grammar.getInitialSymbol ( ) )
159 throw GrammarException ( "Illegal left hand side of epsilon rule" );
160
161 bool res = grammar.getGeneratesEpsilon ( );
162 grammar.setGeneratesEpsilon ( true );
163 return ! res;
164 } else if ( rightHandSide.size ( ) == 1 ) {
165 return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide [ 0 ].template get < TerminalSymbolType > ( ) ) );
166 } else if ( rightHandSide.size ( ) == 2 ) {
167 return grammar.addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( rightHandSide [ 0 ].template get < NonterminalSymbolType > ( ) ), std::move ( rightHandSide [ 1 ].template get < NonterminalSymbolType > ( ) ) ) );
168 } else {
169 throw GrammarException ( "Invalid right hand side" );
170 }
171}
172
173template < class TerminalSymbolType, class NonterminalSymbolType >
175 return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide ) );
176}
177
178template < class TerminalSymbolType, class NonterminalSymbolType >
180 if ( rightHandSide.empty ( ) )
181 return grammar.addRule ( std::move ( leftHandSide ), ext::vector < TerminalSymbolType > { } );
182 else if ( grammar.getNonterminalAlphabet ( ).count ( rightHandSide [ 0 ] ) ) {
184 std::for_each ( rightHandSide.begin ( ) + 1, rightHandSide.end ( ), [ & ] ( ext::variant < TerminalSymbolType, NonterminalSymbolType > & element ) {
185 rhs.push_back ( std::move ( element.template get < TerminalSymbolType > ( ) ) );
186 } );
187
188 return grammar.addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( rightHandSide [ 0 ].template get < NonterminalSymbolType > ( ) ), std::move ( rhs ) ) );
189 } else {
191 std::for_each ( rightHandSide.begin ( ), rightHandSide.end ( ), [ & ] ( ext::variant < TerminalSymbolType, NonterminalSymbolType > & element ) {
192 rhs.push_back ( std::move ( element.template get < TerminalSymbolType > ( ) ) );
193 } );
194
195 return grammar.addRule ( std::move ( leftHandSide ), std::move ( rhs ) );
196 }
197}
198
199template < class TerminalSymbolType, class NonterminalSymbolType >
201 if ( rightHandSide.empty ( ) ) {
202 if ( leftHandSide != grammar.getInitialSymbol ( ) )
203 throw GrammarException ( "Illegal left hand side of epsilon rule" );
204
205 bool res = grammar.getGeneratesEpsilon ( );
206 grammar.setGeneratesEpsilon ( true );
207 return res;
208 } else if ( rightHandSide.size ( ) == 1 ) {
209 return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide [ 0 ].template get < TerminalSymbolType > ( ) ) );
210 } else if ( rightHandSide.size ( ) == 2 ) {
211 return grammar.addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( rightHandSide [ 0 ].template get < NonterminalSymbolType > ( ) ), std::move ( rightHandSide [ 1 ].template get < TerminalSymbolType > ( ) ) ) );
212 } else {
213 throw GrammarException ( "Invalid right hand side" );
214 }
215}
216
217template < class TerminalSymbolType, class NonterminalSymbolType >
219 if ( rightHandSide.empty ( ) ) {
220 if ( leftHandSide != grammar.getInitialSymbol ( ) )
221 throw GrammarException ( "Illegal left hand side of epsilon rule" );
222
223 bool res = grammar.getGeneratesEpsilon ( );
224 grammar.setGeneratesEpsilon ( true );
225 return res;
226 } else if ( rightHandSide.size ( ) == 1 ) {
227 return grammar.addRule ( std::move ( leftHandSide ), std::move ( rightHandSide[0].template get < TerminalSymbolType > ( ) ) );
228 } else if ( rightHandSide.size ( ) == 2 ) {
229 return grammar.addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( rightHandSide[0].template get < TerminalSymbolType > ( ) ), std::move ( rightHandSide[1].template get < NonterminalSymbolType > ( ) ) ) );
230 } else {
231 throw GrammarException ( "Invalid right hand side" );
232 }
233}
234
235template < class TerminalSymbolType, class NonterminalSymbolType >
237 if ( rightHandSide.empty ( ) )
238 return grammar.addRule ( std::move ( leftHandSide ), ext::vector < TerminalSymbolType > { } );
239 else if ( grammar.getNonterminalAlphabet ( ).count ( rightHandSide [ rightHandSide.size ( ) - 1 ] ) ) {
241 std::for_each ( rightHandSide.begin ( ), rightHandSide.end ( ) - 1, [ & ] ( ext::variant < TerminalSymbolType, NonterminalSymbolType > & element ) {
242 rhs.push_back ( std::move ( element.template get < TerminalSymbolType > ( ) ) );
243 } );
244
245 return grammar.addRule ( std::move ( leftHandSide ), ext::make_pair ( std::move ( rhs ), std::move ( rightHandSide [ rightHandSide.size ( ) - 1 ].template get < NonterminalSymbolType > ( ) ) ) );
246 } else {
248 std::for_each ( rightHandSide.begin ( ), rightHandSide.end ( ), [ & ] ( ext::variant < TerminalSymbolType, NonterminalSymbolType > & element ) {
249 rhs.push_back ( std::move ( element.template get < TerminalSymbolType > ( ) ) );
250 } );
251
252 return grammar.addRule ( std::move ( leftHandSide ), std::move ( rhs ) );
253 }
254}
255
256} /* namespace grammar */
257
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
auto begin() &
Inherited behavior of begin for non-const instance.
Definition: vector.hpp:125
auto end() &
Inherited behavior of end for non-const instance.
Definition: vector.hpp:155
Definition: AddRawRule.h:27
static bool addRawRule(LG< TerminalSymbolType, NonterminalSymbolType > &grammar, NonterminalSymbolType leftHandSide, ext::vector< ext::variant< TerminalSymbolType, NonterminalSymbolType > > rightHandSide)
Definition: AddRawRule.h:92
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
Definition: GrammarException.h:15
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
return res
Definition: MinimizeByPartitioning.h:145
constexpr auto make_tuple(Elements &&... args)
Helper of extended tuple construction. The tuple is constructed from values pack, types are deduced.
Definition: tuple.hpp:203
constexpr auto make_pair(T1 &&x, T2 &&y)
Definition: pair.hpp:79
Definition: ToAutomaton.h:24