Updated to PetitCompiler-JanKurs.160, PetitCompiler-Tests-JanKurs.112, PetitCompiler-Extras-Tests-JanKurs.25, PetitCompiler-Benchmarks-JanKurs.17
Name: PetitCompiler-JanKurs.160
Author: JanKurs
Time: 17-08-2015, 09:52:26.291 AM
UUID: 3b4bfc98-8098-4951-af83-a59e2585b121
Name: PetitCompiler-Tests-JanKurs.112
Author: JanKurs
Time: 16-08-2015, 05:00:32.936 PM
UUID: 85613d47-08f3-406f-9823-9cdab451e805
Name: PetitCompiler-Extras-Tests-JanKurs.25
Author: JanKurs
Time: 16-08-2015, 05:00:10.328 PM
UUID: 09731810-51a1-4151-8d3a-56b636fbd1f7
Name: PetitCompiler-Benchmarks-JanKurs.17
Author: JanKurs
Time: 05-08-2015, 05:29:32.407 PM
UUID: e544b5f1-bcf8-470b-93a6-d2363e4dfc8a
"{ Package: 'stx:goodies/petitparser/compiler' }"
"{ NameSpace: Smalltalk }"
Object subclass:#PEGFsaMinimizator
instanceVariableNames:'fsa joinDictionary'
classVariableNames:''
poolDictionaries:''
category:'PetitCompiler-FSA'
!
!PEGFsaMinimizator methodsFor:'comparison'!
info: info equals: anotherInfo
(info == anotherInfo) ifTrue: [ ^ true ].
(info class == anotherInfo class) ifFalse: [ ^ false ].
"
I suppose I don't if someone does not have the priority set.
Please note that equals is used for minimization, so I try to
be as liberal as possible to get as small automaton as possible.
"
(info hasPriority and: [anotherInfo hasPriority]) ifTrue: [
(info priority == anotherInfo priority) ifFalse: [ ^ false ].
].
(info isFinal == anotherInfo isFinal) ifFalse: [ ^ false ].
(info isFsaFailure == anotherInfo isFsaFailure) ifFalse: [ ^ false ].
^ true
!
state: state equals: anotherState
(state == anotherState) ifTrue: [ ^ true ].
(state class == anotherState class) ifFalse: [ ^ false ].
(state isFinal = anotherState isFinal) ifFalse: [ ^ false ].
(state stateInfos size == anotherState stateInfos size) ifFalse: [ ^ false ].
state retvals do: [:retval |
(self info: (state infoFor: retval) equals: (anotherState infoFor: retval ifAbsent: [ ^ false ])) ifFalse: [ ^ false ]
].
(state transitions size == anotherState transitions size) ifFalse: [ ^ false ].
anotherState transitions do: [ :anotherStateT |
(state transitions contains: [ :stateT |
(anotherStateT equals: stateT) or: [
"this is condition for self reference"
(anotherStateT destination == anotherState) and: [ stateT destination == state ]
] ] ) ifFalse: [ ^ false ]
].
^ true
! !
!PEGFsaMinimizator methodsFor:'joining'!
joinInfo: state with: anotherState
self assert: state stateInfos size == anotherState stateInfos size.
state stateInfos do: [ :si1 |
self assert: (anotherState stateInfos contains: [ :si2 |
si1 isFinal == si2 isFinal and: [ si1 isFsaFailure == si2 isFsaFailure ]
])
]
!
joinName: state with: anotherState
state name: state name asString, '+', anotherState name asString.
!
joinState: state with: anotherState
self assert: state hasZeroPriorityOnly.
self assert: anotherState hasZeroPriorityOnly.
self joinName: state with: anotherState.
self joinInfo: state with: anotherState.
! !
!PEGFsaMinimizator methodsFor:'minimization'!
minimize
| pair |
pair := fsa statePairs detect: [ :p | self state: p first equals: p second ] ifNone: [ nil ].
[ pair isNil not ] whileTrue: [
"Join priorities, because equivalency of priorities does not follow from the `equals:` of states"
self joinState: pair first with: pair second.
fsa replace: pair second with: pair first.
fsa mergeTransitions.
pair := fsa statePairs detect: [ :p | self state: p first equals: p second ] ifNone: [ nil ].
].
!
minimize: anFsa
fsa := anFsa.
self minimize.
fsa checkSanity.
^ fsa
! !