|
1 "{ Package: 'stx:goodies/petitparser/compiler/tests' }" |
|
2 |
|
3 "{ NameSpace: Smalltalk }" |
|
4 |
|
5 TestCase subclass:#PEGFsaSequenceDeterminizationTest |
|
6 instanceVariableNames:'fsa a b c result d interpreter e t1 t2 state anotherState parser |
|
7 generator' |
|
8 classVariableNames:'' |
|
9 poolDictionaries:'' |
|
10 category:'PetitCompiler-Tests-FSA' |
|
11 ! |
|
12 |
|
13 !PEGFsaSequenceDeterminizationTest methodsFor:'as yet unclassified'! |
|
14 |
|
15 assert: anFsa fail: input |
|
16 | stream | |
|
17 stream := input asPetitStream. |
|
18 |
|
19 result := interpreter interpret: anFsa on: stream. |
|
20 |
|
21 self assert: result isEmpty. |
|
22 ^ result |
|
23 ! |
|
24 |
|
25 assert: anFsa parse: input |
|
26 ^ self assert: anFsa parse: input end: input size |
|
27 ! |
|
28 |
|
29 assert: anFsa parse: input end: end |
|
30 | stream | |
|
31 stream := input asPetitStream. |
|
32 |
|
33 result := interpreter interpret: anFsa on: stream. |
|
34 |
|
35 self assert: result size = 1. |
|
36 self assert: ((result anyOne) = end) description: 'wrong position'. |
|
37 |
|
38 ^ result anyOne |
|
39 ! |
|
40 |
|
41 determinizator |
|
42 ^ PEGFsaSequenceDeterminizator new |
|
43 ! |
|
44 |
|
45 determinize: anFsa |
|
46 ^ self determinizator determinize: anFsa |
|
47 ! |
|
48 |
|
49 fsaFrom: aNode |
|
50 ^ (aNode accept: generator) |
|
51 yourself |
|
52 ! |
|
53 |
|
54 joinState: s1 with: s2 |
|
55 ^ self determinizator joinState: s1 with: s2 |
|
56 ! |
|
57 |
|
58 setUp |
|
59 a := PEGFsaState new name: #a; retval: #token; yourself. |
|
60 b := PEGFsaState new name: #b; retval: #token; yourself. |
|
61 c := PEGFsaState new name: #c; retval: #token; yourself. |
|
62 d := PEGFsaState new name: #d; retval: #token; yourself. |
|
63 e := PEGFsaState new name: #e; retval: #token; yourself. |
|
64 |
|
65 state := PEGFsaState new name: #state; retval: #token; yourself. |
|
66 anotherState := PEGFsaState new name: #anotherState; retval: #token; yourself. |
|
67 |
|
68 t1 := PEGFsaCharacterTransition new. |
|
69 t2 := PEGFsaCharacterTransition new. |
|
70 |
|
71 fsa := PEGFsa new. |
|
72 generator := PEGFsaGenerator new. |
|
73 |
|
74 interpreter := PEGFsaInterpret new |
|
75 yourself. |
|
76 ! ! |
|
77 |
|
78 !PEGFsaSequenceDeterminizationTest methodsFor:'tests'! |
|
79 |
|
80 testAAplusA |
|
81 parser := 'aa' asParser plus, 'a' asParser. |
|
82 fsa := self fsaFrom: parser asCompilerTree. |
|
83 |
|
84 self determinize: fsa. |
|
85 |
|
86 self assert: fsa isDeterministic. |
|
87 self assert: fsa isWithoutEpsilons. |
|
88 |
|
89 self assert: fsa fail: 'a'. |
|
90 self assert: fsa fail: 'aa'. |
|
91 self assert: fsa fail: 'aaaa'. |
|
92 |
|
93 self assert: fsa parse: 'aaa'. |
|
94 self assert: fsa parse: 'aaaaa'. |
|
95 self assert: fsa parse: 'aaaaaaa'. |
|
96 ! |
|
97 |
|
98 testAB |
|
99 parser := $a asParser, $b asParser. |
|
100 fsa := self fsaFrom: parser asCompilerTree. |
|
101 |
|
102 self determinize: fsa. |
|
103 |
|
104 self assert: fsa states size = 3. |
|
105 self assert: fsa isDeterministic. |
|
106 self assert: fsa isWithoutEpsilons. |
|
107 self assert: fsa startState destination isFinal not. |
|
108 |
|
109 self assert: fsa parse: 'ab'. |
|
110 self assert: fsa parse: 'abc' end: 2. |
|
111 |
|
112 self assert: fsa fail: 'ac'. |
|
113 ! |
|
114 |
|
115 testAPlusA |
|
116 parser := $a asParser plus, $a asParser. |
|
117 fsa := self fsaFrom: parser asCompilerTree. |
|
118 |
|
119 self determinize: fsa. |
|
120 |
|
121 " self assert: fsa states size = 2." |
|
122 self assert: fsa isDeterministic. |
|
123 self assert: fsa isWithoutEpsilons. |
|
124 |
|
125 self assert: fsa fail: 'a'. |
|
126 self assert: fsa fail: 'aa'. |
|
127 self assert: fsa fail: 'b'. |
|
128 ! |
|
129 |
|
130 testAPlusB |
|
131 parser := $a asParser plus, $b asParser. |
|
132 fsa := self fsaFrom: parser asCompilerTree. |
|
133 |
|
134 self determinize: fsa. |
|
135 |
|
136 |
|
137 self assert: fsa states size = 3. |
|
138 self assert: fsa isDeterministic. |
|
139 self assert: fsa isWithoutEpsilons. |
|
140 |
|
141 self assert: fsa parse: 'ab'. |
|
142 self assert: fsa parse: 'aaaab'. |
|
143 self assert: fsa parse: 'aaaabc' end: 5. |
|
144 |
|
145 self assert: fsa fail: 'b'. |
|
146 ! |
|
147 |
|
148 testApriorityOrA |
|
149 parser := $a asParser / $a asParser. |
|
150 fsa := self fsaFrom: parser asCompilerTree. |
|
151 |
|
152 self determinize: fsa. |
|
153 |
|
154 self assert: fsa states size = 2. |
|
155 self assert: fsa isDeterministic. |
|
156 self assert: fsa isWithoutEpsilons. |
|
157 self assert: fsa finalStates size = 1. |
|
158 self assert: fsa finalStates anyOne isMultivalue not. |
|
159 |
|
160 self assert: fsa parse: 'a'. |
|
161 self assert: fsa fail: 'b'. |
|
162 ! |
|
163 |
|
164 testDeterminizeFsa |
|
165 fsa addState: a. |
|
166 fsa addState: b. |
|
167 fsa addState: c. |
|
168 fsa startState: a. |
|
169 fsa finalState: c. |
|
170 |
|
171 fsa addTransitionFrom: a to: b on: $a. |
|
172 fsa addTransitionFrom: a to: c on: $a. |
|
173 |
|
174 self determinize: fsa. |
|
175 |
|
176 self assert: fsa states size = 2. |
|
177 self assert: a transitions size = 1. |
|
178 ! |
|
179 |
|
180 testDeterminizeFsa2 |
|
181 | | |
|
182 fsa addState: a. |
|
183 fsa addState: b. |
|
184 fsa addState: c. |
|
185 fsa addState: d. |
|
186 |
|
187 fsa startState: a. |
|
188 fsa finalState: b. |
|
189 fsa finalState: c. |
|
190 fsa finalState: d. |
|
191 |
|
192 a priority: 0. |
|
193 b priority: 0. |
|
194 c priority: 0. |
|
195 d priority: 0. |
|
196 |
|
197 fsa addTransitionFrom: a to: b on: $a. |
|
198 fsa addTransitionFrom: b to: c on: $a. |
|
199 fsa addTransitionFrom: c to: d on: $a. |
|
200 |
|
201 fsa addTransitionFrom: b to: a on: $a. |
|
202 fsa addTransitionFrom: c to: a on: $a. |
|
203 fsa addTransitionFrom: d to: a on: $a. |
|
204 |
|
205 self determinize: fsa. |
|
206 self assert: fsa isDeterministic. |
|
207 ! |
|
208 |
|
209 testDeterminizeFsa3 |
|
210 | merged | |
|
211 fsa addState: a. |
|
212 fsa addState: b. |
|
213 fsa addState: c. |
|
214 fsa addState: d. |
|
215 fsa addState: e. |
|
216 |
|
217 fsa startState: a. |
|
218 fsa finalState: e. |
|
219 |
|
220 fsa addTransitionFrom: a to: b on: $a. |
|
221 fsa addTransitionFrom: a to: c on: $a. |
|
222 fsa addTransitionFrom: b to: e on: $e. |
|
223 fsa addTransitionFrom: c to: d on: $d. |
|
224 fsa addTransitionFrom: d to: e on: $e. |
|
225 |
|
226 self determinize: fsa. |
|
227 |
|
228 merged := a transitions anyOne destination. |
|
229 |
|
230 self assert: fsa states size = 4. |
|
231 self assert: a transitions size = 1. |
|
232 self assert: merged transitions size = 2. |
|
233 self assert: (merged transitions anySatisfy: [ :t | (t accepts: $d) and: [ t destination = d ]]). |
|
234 self assert: (merged transitions anySatisfy: [ :t | (t accepts: $e) and: [ t destination = e ]]). |
|
235 ! |
|
236 |
|
237 testDeterminizeFsa4 |
|
238 | merged | |
|
239 fsa addState: a. |
|
240 fsa addState: b. |
|
241 |
|
242 fsa startState: a. |
|
243 fsa finalState: b. |
|
244 |
|
245 fsa addTransitionFrom: a to: a on: $a. |
|
246 fsa addTransitionFrom: a to: b on: $a. |
|
247 |
|
248 b priority: -1. |
|
249 a priority: 0. |
|
250 |
|
251 self determinize: fsa. |
|
252 merged := a destination. |
|
253 |
|
254 self assert: fsa states size = 2. |
|
255 self assert: a transitions size = 1. |
|
256 self assert: merged transitions size = 1. |
|
257 self assert: ((merged name = #'a_b') or: [merged name = #'b_a']). |
|
258 self assert: (merged transitions anySatisfy: [ :t | (t accepts: $a) and: [ t destination = merged ]]). |
|
259 ! |
|
260 |
|
261 testDeterminizeFsa5 |
|
262 | merged | |
|
263 fsa addState: a. |
|
264 fsa addState: b. |
|
265 fsa addState: c. |
|
266 fsa addState: d. |
|
267 fsa startState: a. |
|
268 fsa finalState: d. |
|
269 |
|
270 fsa addTransitionFrom: a to: b on: $a. |
|
271 fsa addTransitionFrom: b to: a. |
|
272 fsa addTransitionFrom: b to: c. |
|
273 fsa addTransitionFrom: c to: d on: $a. |
|
274 b priority: 0. |
|
275 d priority: -1. |
|
276 |
|
277 self determinize: fsa. |
|
278 |
|
279 merged := b destination. |
|
280 |
|
281 self assert: fsa isDeterministic. |
|
282 self assert: fsa states size = 3. |
|
283 |
|
284 |
|
285 self assert: a transitions size = 1. |
|
286 self assert: b transitions size = 1. |
|
287 self assert: (fsa states noneSatisfy: [ :s | s isFinal ]). |
|
288 ! |
|
289 |
|
290 testDeterminizeFsa6 |
|
291 | merged | |
|
292 fsa addState: a. |
|
293 fsa addState: b. |
|
294 fsa addState: c. |
|
295 |
|
296 fsa startState: a. |
|
297 fsa finalState: c. |
|
298 |
|
299 |
|
300 fsa addTransitionFrom: a to: b on: $a. |
|
301 fsa addTransitionFrom: a to: c on: $a priority: -1. |
|
302 |
|
303 self determinize: fsa. |
|
304 self assert: fsa isDeterministic. |
|
305 self assert: fsa states size = 2. |
|
306 |
|
307 self assert: a transitions size = 1. |
|
308 self assert: a isFinal not. |
|
309 |
|
310 merged := a destination. |
|
311 self assert: merged isFinal. |
|
312 self assert: merged priority = 0. |
|
313 ! |
|
314 |
|
315 testDeterminizeFsa7 |
|
316 | merged | |
|
317 fsa addState: a. |
|
318 fsa addState: b. |
|
319 fsa addState: c. |
|
320 |
|
321 fsa startState: a. |
|
322 fsa finalState: b. |
|
323 fsa finalState: c. |
|
324 |
|
325 |
|
326 fsa addTransitionFrom: a to: b on: $a. |
|
327 fsa addTransitionFrom: a to: c on: $a priority: -1. |
|
328 |
|
329 b priority: 0. |
|
330 c priority: -1. |
|
331 |
|
332 self determinize: fsa. |
|
333 self assert: fsa isDeterministic. |
|
334 self assert: fsa states size = 2. |
|
335 |
|
336 self assert: a transitions size = 1. |
|
337 self assert: a isFinal not. |
|
338 |
|
339 merged := a destination. |
|
340 self assert: merged isFinal. |
|
341 self assert: merged priority = 0. |
|
342 ! |
|
343 |
|
344 testDeterminizeFsa8 |
|
345 | | |
|
346 fsa addState: a. |
|
347 fsa addState: b. |
|
348 fsa addState: c. |
|
349 |
|
350 fsa startState: a. |
|
351 fsa finalState: b. |
|
352 fsa finalState: c. |
|
353 |
|
354 a priority: 0. |
|
355 b priority: 0. |
|
356 c priority: 0. |
|
357 |
|
358 |
|
359 fsa addTransitionFrom: a to: b on: $a. |
|
360 fsa addTransitionFrom: a to: c on: $a. |
|
361 |
|
362 fsa addTransitionFrom: b to: a on: $a. |
|
363 fsa addTransitionFrom: b to: c on: $a. |
|
364 |
|
365 fsa addTransitionFrom: c to: a on: $a. |
|
366 fsa addTransitionFrom: c to: b on: $a. |
|
367 |
|
368 |
|
369 self determinize: fsa. |
|
370 self assert: fsa isDeterministic. |
|
371 ! |
|
372 |
|
373 testDeterminizeFsa9 |
|
374 | | |
|
375 fsa addState: a. |
|
376 fsa addState: b. |
|
377 fsa addState: c. |
|
378 fsa addState: d. |
|
379 |
|
380 fsa startState: a. |
|
381 fsa finalState: b. |
|
382 fsa finalState: c. |
|
383 fsa finalState: d. |
|
384 |
|
385 a priority: 0. |
|
386 b priority: 0. |
|
387 c priority: 0. |
|
388 d priority: 0. |
|
389 |
|
390 fsa addTransitionFrom: a to: b on: $a. |
|
391 fsa addTransitionFrom: b to: c on: $a. |
|
392 fsa addTransitionFrom: c to: d on: $a. |
|
393 |
|
394 fsa addTransitionFrom: b to: a on: $a. |
|
395 fsa addTransitionFrom: c to: a on: $a. |
|
396 fsa addTransitionFrom: d to: a on: $a. |
|
397 |
|
398 self determinize: fsa. |
|
399 self assert: fsa isDeterministic. |
|
400 ! ! |
|
401 |
|
402 !PEGFsaSequenceDeterminizationTest methodsFor:'tests - joining'! |
|
403 |
|
404 testJoinState |
|
405 | newState | |
|
406 state addTransition: t1. |
|
407 anotherState addTransition: t2. |
|
408 state final: true. |
|
409 |
|
410 t1 destination: (PEGFsaState named: #t1). |
|
411 t2 destination: (PEGFsaState named: #t2). |
|
412 |
|
413 newState := self joinState: state with: anotherState. |
|
414 |
|
415 self assert: (newState transitions contains: [ :t | t = t1 ]). |
|
416 self assert: (newState transitions contains: [ :t | t = t2 ]). |
|
417 self assert: (newState isFinal). |
|
418 ! |
|
419 |
|
420 testJoinState2 |
|
421 | newState | |
|
422 state addTransition: t1. |
|
423 anotherState addTransition: t2. |
|
424 state final: true. |
|
425 |
|
426 t1 destination: (PEGFsaState named: #t1). |
|
427 t2 destination: (PEGFsaState named: #t2). |
|
428 |
|
429 newState := self joinState: anotherState with: state. |
|
430 |
|
431 self assert: (newState transitions contains: [ :t | t = t1 ]). |
|
432 self assert: (newState transitions contains: [ :t | t = t2 ]). |
|
433 self assert: (newState isFinal). |
|
434 ! |
|
435 |
|
436 testJoinState3 |
|
437 | newState | |
|
438 state final: true. |
|
439 state retval: #foo. |
|
440 state priority: -1. |
|
441 |
|
442 anotherState final: true. |
|
443 anotherState retval: #foo. |
|
444 anotherState failure: true. |
|
445 anotherState priority: 0. |
|
446 |
|
447 newState := self joinState: anotherState with: state. |
|
448 |
|
449 self assert: (newState isMultivalue not). |
|
450 self assert: (newState retval value = #foo). |
|
451 self assert: (newState isFinal). |
|
452 self assert: (newState priority = 0). |
|
453 self assert: (newState isFsaFailure). |
|
454 ! |
|
455 |
|
456 testJoinState5 |
|
457 | newState | |
|
458 state final: true. |
|
459 state retval: #foo. |
|
460 state priority: 0. |
|
461 |
|
462 anotherState final: true. |
|
463 anotherState retval: #foo. |
|
464 anotherState priority: -1. |
|
465 |
|
466 |
|
467 newState := self joinState: anotherState with: state. |
|
468 |
|
469 self assert: (newState retval = #foo). |
|
470 self assert: (newState isFinal). |
|
471 self assert: (newState priority = 0). |
|
472 ! |
|
473 |
|
474 testJoinState6 |
|
475 | newState | |
|
476 state final: true. |
|
477 state priority: 0. |
|
478 |
|
479 anotherState final: true. |
|
480 anotherState priority: -1. |
|
481 anotherState failure: true. |
|
482 |
|
483 |
|
484 newState := self joinState: anotherState with: state. |
|
485 |
|
486 self assert: (newState isMultivalue not). |
|
487 self assert: (newState isFinal). |
|
488 self assert: (newState priority = 0). |
|
489 self assert: (newState isFsaFailure not). |
|
490 ! |
|
491 |
|
492 testJoinState7 |
|
493 | newState | |
|
494 state final: true. |
|
495 state retval: #foo. |
|
496 state priority: -1. |
|
497 |
|
498 anotherState final: true. |
|
499 anotherState retval: #foo. |
|
500 anotherState failure: true. |
|
501 anotherState priority: 0. |
|
502 |
|
503 newState := self joinState: anotherState with: state. |
|
504 |
|
505 self assert: (newState isMultivalue not). |
|
506 self assert: (newState retval value = #foo). |
|
507 self assert: (newState isFinal). |
|
508 self assert: (newState priority = 0). |
|
509 self assert: (newState isFsaFailure). |
|
510 ! ! |
|
511 |