compiler/PEGFsaStateInfo.st
changeset 515 b5316ef15274
child 534 a949c4fe44df
equal deleted inserted replaced
502:1e45d3c96ec5 515:b5316ef15274
       
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
       
     2 
       
     3 "{ NameSpace: Smalltalk }"
       
     4 
       
     5 Object subclass:#PEGFsaStateInfo
       
     6 	instanceVariableNames:'priority final failure'
       
     7 	classVariableNames:''
       
     8 	poolDictionaries:''
       
     9 	category:'PetitCompiler-FSA'
       
    10 !
       
    11 
       
    12 !PEGFsaStateInfo methodsFor:'accessing'!
       
    13 
       
    14 failure
       
    15     ^ failure
       
    16 !
       
    17 
       
    18 failure: anObject
       
    19     failure := anObject
       
    20 !
       
    21 
       
    22 final
       
    23     ^ final
       
    24 !
       
    25 
       
    26 final: anObject
       
    27     final := anObject
       
    28 !
       
    29 
       
    30 priority
       
    31     ^ priority
       
    32 !
       
    33 
       
    34 priority: anObject
       
    35     priority := anObject
       
    36 ! !
       
    37 
       
    38 !PEGFsaStateInfo methodsFor:'comparing'!
       
    39 
       
    40 = anotherInfo
       
    41     (self == anotherInfo) ifTrue: [ ^ true ].
       
    42     (self class == anotherInfo class) ifFalse: [ ^ false ].
       
    43     
       
    44     (priority == anotherInfo priority) ifFalse: [ ^ false ].
       
    45 
       
    46     (self isFinal == anotherInfo isFinal) ifFalse: [ ^ false ].
       
    47 
       
    48     ^ true
       
    49 !
       
    50 
       
    51 equals: anotherInfo
       
    52     self error: 'deprecated'.
       
    53     (self == anotherInfo) ifTrue: [ ^ true ].
       
    54     (self class == anotherInfo class) ifFalse: [ ^ false ].
       
    55 
       
    56     "	
       
    57         I suppose I don't if someone does not have the priority set.
       
    58         Please note that equals is used for minimization, so I try to
       
    59         be as liberal as possible to get as small automaton as possible.
       
    60     "
       
    61     (self hasPriority and: [anotherInfo hasPriority]) ifTrue: [ 	
       
    62         (priority == anotherInfo priority) ifFalse: [ ^ false ].
       
    63     ].
       
    64 
       
    65     (self isFinal == anotherInfo isFinal) ifFalse: [ ^ false ].
       
    66 
       
    67     ^ true
       
    68 ! !
       
    69 
       
    70 !PEGFsaStateInfo methodsFor:'modifications - determinization'!
       
    71 
       
    72 join: info into: newInfo
       
    73     self error: 'deprecated'.
       
    74     "
       
    75         The diff between JOIN and Merge:
       
    76         - join is used while determinizing the FSA
       
    77         - merge is used when removing epsilons
       
    78     "
       
    79 
       
    80     (self hasEqualPriorityTo: info) ifTrue: [ 
       
    81         newInfo final: (self isFinal or: [ info isFinal ]).
       
    82  		newInfo priority: self priority.	
       
    83         ^ self
       
    84     ].
       
    85     
       
    86     (self hasHigherPriorityThan: info) ifTrue: [ 
       
    87  		newInfo priority: self priority.	
       
    88         newInfo final: self isFinal.
       
    89         ^ self
       
    90     ].
       
    91 
       
    92     newInfo priority: info priority.
       
    93     newInfo final: info isFinal.
       
    94 ! !
       
    95 
       
    96 !PEGFsaStateInfo methodsFor:'printing'!
       
    97 
       
    98 printOn: aStream
       
    99     priority isNil ifFalse: [ 
       
   100         priority printOn: aStream.
       
   101         aStream nextPutAll: ', '	
       
   102     ].
       
   103 
       
   104     self isFinal ifTrue: [ 
       
   105         aStream nextPutAll: 'FINAL'.
       
   106         aStream nextPutAll: ', '	
       
   107     ].
       
   108 
       
   109     self isFsaFailure ifTrue: [ 
       
   110         aStream nextPutAll: 'FAILURE'
       
   111     ].
       
   112 ! !
       
   113 
       
   114 !PEGFsaStateInfo methodsFor:'testing'!
       
   115 
       
   116 hasEqualPriorityTo: stateInfo
       
   117     "nil - nil"
       
   118     (self hasPriority not and: [stateInfo hasPriority not]) ifTrue: [ ^ true ].
       
   119     
       
   120     "nil - priority"
       
   121     (self hasPriority) ifFalse: [ ^ false ].
       
   122     
       
   123     "priority - nil"
       
   124     stateInfo hasPriority ifFalse: [ ^ false ].
       
   125     
       
   126     "priority - priority"
       
   127     ^ self priority = stateInfo priority 
       
   128 !
       
   129 
       
   130 hasHigherPriorityThan: stateInfo
       
   131     "nil - nil"
       
   132     (self hasPriority not and: [stateInfo hasPriority not]) ifTrue: [ ^ true ].
       
   133     
       
   134     "nil - priority"
       
   135     (self hasPriority) ifFalse: [ ^ false ].
       
   136     
       
   137     "priority - nil"
       
   138     stateInfo hasPriority ifFalse: [ ^ true ].
       
   139     
       
   140     "priority - priority"
       
   141     ^ self priority > stateInfo priority 
       
   142 !
       
   143 
       
   144 hasPriority
       
   145     ^ self priority isNil not
       
   146 !
       
   147 
       
   148 isBlank
       
   149     ^ self hasPriority not and: [ self isFinal not ]
       
   150 !
       
   151 
       
   152 isFinal
       
   153     final isNil ifTrue: [ ^ false ].
       
   154     ^ final
       
   155 !
       
   156 
       
   157 isFsaFailure
       
   158     failure isNil ifTrue: [ ^ false ].
       
   159     ^ failure
       
   160 ! !
       
   161 
       
   162 !PEGFsaStateInfo methodsFor:'transformation'!
       
   163 
       
   164 merge: info into: newInfo
       
   165     "
       
   166         The diff between JOIN and Merge:
       
   167         - join is used while determinizing the FSA
       
   168         - merge is used when removing epsilons
       
   169     "
       
   170 
       
   171     "final - final"
       
   172     (self isFinal and: [info isFinal]) ifTrue: [ 
       
   173         newInfo final: true.
       
   174         (self hasHigherPriorityThan: info) ifTrue: [  
       
   175             newInfo priority: self priority.
       
   176         ] ifFalse: [  
       
   177             newInfo priority: info priority.
       
   178         ].
       
   179         "
       
   180             This has its reason: when moving from failure to non-failure
       
   181             using the epsilon, just keep the latter:
       
   182         "
       
   183         newInfo failure: info isFsaFailure.
       
   184         ^ self
       
   185  	].
       
   186 
       
   187     "final - non final"
       
   188     (self isFinal) ifTrue: [ 
       
   189         newInfo final: true.
       
   190         newInfo priority: self priority.
       
   191         newInfo failure: self isFsaFailure.
       
   192         ^ self
       
   193     ].
       
   194 
       
   195     "non final - final"
       
   196     (info isFinal) ifTrue: [ 
       
   197         newInfo final: true.
       
   198         newInfo priority: info priority.
       
   199         newInfo failure: info isFsaFailure.
       
   200         ^ self
       
   201     ].
       
   202     
       
   203     "non final - non final"
       
   204  	newInfo priority: self priority.	
       
   205     (self hasHigherPriorityThan: info) ifTrue: [  
       
   206         newInfo priority: self priority.
       
   207     ] ifFalse: [  
       
   208         newInfo priority: info priority.
       
   209     ].
       
   210     newInfo failure: info isFsaFailure.
       
   211 ! !
       
   212