|
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 |