Class { #name : 'PEGFsaAbstractDeterminizator', #superclass : 'Object', #instVars : [ 'fsa', 'joinDictionary' ], #category : 'PetitCompiler-FSA' } { #category : 'as yet unclassified' } PEGFsaAbstractDeterminizator class >> new [ ^ self basicNew initialize ] { #category : 'determinization' } PEGFsaAbstractDeterminizator >> determinize [ | states | " fsa checkSanity." fsa removeEpsilons. fsa removeUnreachableStates. fsa mergeTransitions. states := fsa topologicalOrder asOrderedCollection. states do: [ :state | self determinizeState: state ]. fsa states: fsa startState reachableStates. fsa removeUnreachableStates. fsa mergeTransitions. ] { #category : 'determinization' } PEGFsaAbstractDeterminizator >> determinize: anFsa [ fsa := anFsa. joinDictionary := Dictionary new. self determinize. ^ fsa ] { #category : 'determinization' } PEGFsaAbstractDeterminizator >> determinizeOverlap: t1 second: t2 state: state [ | t1Prime t2Prime tIntersection | self assert: (state transitions includes: t1). self assert: (state transitions includes: t2). tIntersection := self joinTransition: t1 with: t2. t1Prime := PEGFsaCharacterTransition new destination: t1 destination; characterSet: (t1 complement: t2); yourself. t2Prime := PEGFsaCharacterTransition new destination: t2 destination; characterSet: (t2 complement: t1); yourself. state removeTransition: t1. state removeTransition: t2. tIntersection isEmpty ifFalse: [ state addTransition: tIntersection ]. t1Prime isEmpty ifFalse: [ state addTransition: t1Prime ]. t2Prime isEmpty ifFalse: [ state addTransition: t2Prime ]. ] { #category : 'determinization' } PEGFsaAbstractDeterminizator >> determinizeState: state [ | pairs | pairs := state transitionPairs asOrderedCollection. [pairs isEmpty] whileFalse: [ | pair | (joinDictionary size > 100) ifTrue: [ self error: 'Oh man, this is really big FSA. Are you sure you want to continue?' ]. pair := pairs removeFirst. self assert:((pair first destination = pair second destination) not or: [pair first isPredicateTransition not or: [pair second isPredicateTransition not ] ]). self assert: (pair contains: #isEpsilon) not. (pair first overlapsWith: pair second) ifTrue: [ self determinizeOverlap: pair first second: pair second state: state. "recompute pairs after the determinization" pairs := state transitionPairs asOrderedCollection. ] ]. ] { #category : 'initialization' } PEGFsaAbstractDeterminizator >> initialize [ super initialize. joinDictionary := Dictionary new ] { #category : 'accessing - keys' } PEGFsaAbstractDeterminizator >> joinKey: key with: anotherKey [ ^ Set new addAll: key; addAll: anotherKey; yourself. ] { #category : 'joining' } PEGFsaAbstractDeterminizator >> joinName: state with: anotherState into: newState [ newState name: state name asString, '_', anotherState name asString. ] { #category : 'joining' } PEGFsaAbstractDeterminizator >> joinState: state with: anotherState [ | key newState | key := self keyFor: state and: anotherState. (joinDictionary includesKey: key) ifTrue: [ ^ joinDictionary at: key ]. newState := PEGFsaState new. joinDictionary at: key put: newState. self joinRetval: state with: anotherState into: newState. self joinInfo: state with: anotherState into: newState. self joinName: state with: anotherState into: newState. self joinTransitions: state with: anotherState into: newState. self determinizeState: newState. self assert: ((joinDictionary at: key) == newState). ^ newState ] { #category : 'joining' } PEGFsaAbstractDeterminizator >> joinTransition: t1 with: t2 [ | newDestination newTransition | self assert: t1 isCharacterTransition. self assert: t2 isCharacterTransition. newDestination := self joinState: t1 destination with: t2 destination. newTransition := PEGFsaCharacterTransition new. newTransition destination: newDestination. newTransition characterSet: (t1 intersection: t2). newTransition priority: (t1 priority max: t2 priority). ^ newTransition ] { #category : 'accessing - keys' } PEGFsaAbstractDeterminizator >> keyFor: state [ ^ joinDictionary keyAtIdentityValue: state ifAbsent: [ Set with: state ] ] { #category : 'accessing - keys' } PEGFsaAbstractDeterminizator >> keyFor: state and: anotherState [ | key anotherKey | key := self keyFor: state. anotherKey := self keyFor: anotherState. ^ self joinKey: key with: anotherKey ]