compiler/PEGFsaTransition.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Mon, 17 Aug 2015 12:13:16 +0100
changeset 515 b5316ef15274
parent 502 1e45d3c96ec5
child 516 3b81c9e53352
child 524 f6f68d32de73
permissions -rw-r--r--
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:#PEGFsaTransition
	instanceVariableNames:'destination priority characterSet'
	classVariableNames:''
	poolDictionaries:''
	category:'PetitCompiler-FSA'
!

!PEGFsaTransition class methodsFor:'instance creation'!

new
    "return an initialized instance"

    ^ self basicNew initialize.
! !

!PEGFsaTransition methodsFor:'accessing'!

characterSet
    ^ characterSet
!

characterSet: anObject
    characterSet := anObject
!

destination
    ^ destination
!

destination: anObject
    destination := anObject
!

priority
    ^ priority
!

priority: anObject
    priority := anObject
! !

!PEGFsaTransition methodsFor:'comparing'!

= anotherTransition
    "
    Please note the identity comparison on destination
    If you use equality instead of identy, you will get infinite loop.

    So much for comparison by now :)	
    "
    (self == anotherTransition) ifTrue: [ ^ true ].
    (self class == anotherTransition class) ifFalse: [ ^ false ].

    (destination == anotherTransition destination) ifFalse: [ ^ false ].
    (priority == anotherTransition priority) ifFalse: [ ^ false ].
    
    ^ true
!

canBeIsomorphicTo: anotherTransition
    (self class == anotherTransition class) ifFalse: [ ^ false ].
    (priority == anotherTransition priority) ifFalse: [ ^ false ].
    
    ^ true
!

equals: anotherTransition
    "this method is used for minimization of the FSA"
    
    (self == anotherTransition) ifTrue: [ ^ true ].
    (self class == anotherTransition class) ifFalse: [ ^ false ].

    (destination == anotherTransition destination) ifFalse: [ ^ false ].

    "JK: If character set and destination are the same, priority does not really matter"
    ^ true
!

hash
    ^ destination hash bitXor: priority hash
! !

!PEGFsaTransition methodsFor:'copying'!

postCopy
    super postCopy.
    characterSet := characterSet copy.
! !

!PEGFsaTransition methodsFor:'gt'!

gtName
    | gtName |
    gtName := self characterSetAsString.
    priority < 0 ifTrue: [ gtName := gtName, ',', priority asString ].
    ^ gtName
! !

!PEGFsaTransition methodsFor:'initialization'!

initialize
    super initialize.
    priority := 0.
! !

!PEGFsaTransition methodsFor:'modifications'!

addCharacter: character
    characterSet at: character codePoint put: true
!

decreasePriority
    self decreasePriorityBy: 1
!

decreasePriorityBy: value
    priority := priority - value
! !

!PEGFsaTransition methodsFor:'set operations'!

complement: transition
    | complement |
    complement := Array new: 255.
    
    1 to: 255 do: [ :index |
        complement
            at: index 
            put: ((self characterSet at: index) and: [(transition characterSet at: index) not])
    ].

    ^ complement
!

disjunction: transition
    | disjunction |
    disjunction := Array new: 255.
    
    1 to: 255 do: [ :index |
        disjunction
            at: index 
            put: ((self characterSet at: index) xor: [transition characterSet at: index])
    ].

    ^ disjunction
!

intersection: transition
    | intersection |
    intersection := Array new: 255.
    
    1 to: 255 do: [ :index |
        intersection
            at: index 
            put: ((self characterSet at: index) and: [transition characterSet at: index])
    ].

    ^ intersection
!

union: transition
    | union |
    union := Array new: 255.
    
    1 to: 255 do: [ :index |
        union
            at: index 
            put: ((self characterSet at: index) or: [transition characterSet at: index])
    ].

    ^ union
! !

!PEGFsaTransition methodsFor:'testing'!

accepts: character
    ^ characterSet at: character codePoint
!

isCharacterTransition
    ^ false
!

isEpsilon
    ^ self isEpsilonTransition
!

isEpsilonTransition
    ^ false
!

isPredicateTransition
    ^ false
!

overlapsWith: transition
    ^ (self intersection: transition) anySatisfy: [ :bool | bool ]
! !

!PEGFsaTransition methodsFor:'transformation'!

join: transition
    ^ self join: transition joinDictionary: Dictionary new.
!

join: transition joinDictionary: dictionary
    | newDestination newTransition |
"	pair := PEGFsaPair with: self with: transition.
    (dictionary includesKey: pair) ifTrue: [ ^ dictionary at: pair ].
    dictionary at: pair put: nil.
"	
    newDestination := self destination join: transition destination joinDictionary: dictionary.
    newDestination isNil ifTrue: [ self error: 'What a cycle!! I wonder, how does this happened!!' ].
    
    newTransition := PEGFsaTransition new.
    newTransition destination: newDestination.
    newTransition characterSet: (self intersection: transition).
    newTransition priority: (self priority min: transition priority).
    
"	^ dictionary at: pair put: newTransition"
    ^ newTransition 
!

mergeWith: transition
    | union |
    self assert: destination = transition destination.
    
    union := self union: transition.
    self characterSet: union
! !