author | Jan Vrany <jan.vrany@fit.cvut.cz> |
Tue, 14 Oct 2014 23:16:37 +0100 | |
changeset 389 | 009c2e13973c |
parent 382 | 1825151d6455 |
permissions | -rw-r--r-- |
262 | 1 |
"{ Package: 'stx:goodies/petitparser/analyzer' }"! |
2 |
||
3 |
!PPActionParser methodsFor:'*petitanalyzer-matching'! |
|
4 |
||
5 |
match: aParser inContext: aDictionary seen: anIdentitySet |
|
6 |
^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self block = aParser block ] |
|
7 |
! ! |
|
8 |
||
9 |
!PPDelegateParser methodsFor:'*petitanalyzer-transforming'! |
|
10 |
||
11 |
replace: aParser with: anotherParser |
|
12 |
super replace: aParser with: anotherParser. |
|
13 |
parser == aParser ifTrue: [ parser := anotherParser ] |
|
14 |
! ! |
|
15 |
||
16 |
!PPEpsilonParser methodsFor:'*petitanalyzer-testing'! |
|
17 |
||
18 |
isNullable |
|
19 |
^ true |
|
20 |
! ! |
|
21 |
||
22 |
!PPFailingParser methodsFor:'*petitanalyzer-matching'! |
|
23 |
||
24 |
match: aParser inContext: aDictionary seen: anIdentitySet |
|
25 |
^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self message = aParser message ] |
|
26 |
! ! |
|
27 |
||
28 |
!PPLimitedRepeatingParser methodsFor:'*petitanalyzer-transforming'! |
|
29 |
||
378
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
30 |
replace: aParser with: anotherParser |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
31 |
super replace: aParser with: anotherParser. |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
32 |
limit == aParser ifTrue: [ limit := anotherParser ] |
262 | 33 |
! ! |
34 |
||
35 |
!PPListParser methodsFor:'*petitanalyzer-matching'! |
|
36 |
||
37 |
copyInContext: aDictionary seen: aSeenDictionary |
|
38 |
| copy copies | |
|
39 |
aSeenDictionary at: self ifPresent: [ :value | ^ value ]. |
|
40 |
copy := aSeenDictionary at: self put: self copy. |
|
41 |
copies := OrderedCollection new. |
|
42 |
parsers do: [ :each | |
|
43 |
| result | |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
44 |
result := each |
262 | 45 |
copyInContext: aDictionary |
46 |
seen: aSeenDictionary. |
|
47 |
result isCollection |
|
48 |
ifTrue: [ copies addAll: result ] |
|
49 |
ifFalse: [ copies add: result ] ]. |
|
50 |
^ copy |
|
51 |
setParsers: copies; |
|
52 |
yourself |
|
53 |
! ! |
|
54 |
||
55 |
!PPListParser methodsFor:'*petitanalyzer-transforming'! |
|
56 |
||
57 |
replace: aParser with: anotherParser |
|
58 |
super replace: aParser with: anotherParser. |
|
59 |
parsers keysAndValuesDo: [ :index :parser | |
|
60 |
parser == aParser |
|
61 |
ifTrue: [ parsers at: index put: anotherParser ] ] |
|
62 |
! ! |
|
63 |
||
64 |
!PPLiteralParser methodsFor:'*petitanalyzer-matching'! |
|
65 |
||
66 |
match: aParser inContext: aDictionary seen: anIdentitySet |
|
67 |
^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self literal = aParser literal and: [ self message = aParser message ] ] |
|
68 |
! ! |
|
69 |
||
378
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
70 |
!PPNotParser methodsFor:'*petitanalyzer-private'! |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
71 |
|
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
72 |
firstSets: aFirstDictionary into: aSet |
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
73 |
|
378
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
74 |
! ! |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
75 |
|
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
76 |
!PPNotParser methodsFor:'*petitanalyzer-testing'! |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
77 |
|
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
78 |
isFirstSetTerminal |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
79 |
^ true |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
80 |
! ! |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
81 |
|
262 | 82 |
!PPOptionalParser methodsFor:'*petitanalyzer-testing'! |
83 |
||
84 |
isNullable |
|
85 |
^ true |
|
86 |
! ! |
|
87 |
||
88 |
!PPParser methodsFor:'*petitanalyzer-named'! |
|
89 |
||
90 |
allNamedParsers |
|
91 |
"Answer all the named parse nodes of the receiver." |
|
92 |
||
93 |
| result | |
|
94 |
result := OrderedCollection new. |
|
95 |
self allNamedParsersDo: [ :parser | result addLast: parser ]. |
|
96 |
^ result |
|
97 |
! ! |
|
98 |
||
99 |
!PPParser methodsFor:'*petitanalyzer-named'! |
|
100 |
||
101 |
allNamedParsersDo: aBlock |
|
102 |
"Iterate over all the named parse nodes of the receiver." |
|
103 |
||
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
104 |
self allParsersDo: [ :each | |
262 | 105 |
each name notNil |
106 |
ifTrue: [ aBlock value: each ] ] |
|
107 |
! ! |
|
108 |
||
109 |
!PPParser methodsFor:'*petitanalyzer-matching'! |
|
110 |
||
111 |
copyInContext: aDictionary |
|
112 |
^ self copyInContext: aDictionary seen: IdentityDictionary new |
|
113 |
! ! |
|
114 |
||
115 |
!PPParser methodsFor:'*petitanalyzer-matching'! |
|
116 |
||
117 |
copyInContext: aDictionary seen: aSeenDictionary |
|
118 |
| copy | |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
119 |
aSeenDictionary |
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
120 |
at: self |
262 | 121 |
ifPresent: [ :value | ^ value ]. |
122 |
copy := aSeenDictionary |
|
123 |
at: self |
|
124 |
put: self copy. |
|
125 |
copy children do: [ :each | |
|
126 |
copy |
|
127 |
replace: each |
|
128 |
with: (each copyInContext: aDictionary seen: aSeenDictionary) ]. |
|
129 |
^ copy |
|
130 |
! ! |
|
131 |
||
132 |
!PPParser methodsFor:'*petitanalyzer-querying'! |
|
133 |
||
134 |
cycleSet |
|
135 |
"Answer a set of all nodes that are within one or more cycles of left-recursion. This is generally not a problem if at least one of the nodes is memoized, but it might make the grammar very inefficient and should be avoided if possible." |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
136 |
|
262 | 137 |
| cycles | |
138 |
cycles := IdentitySet new. |
|
139 |
self cycleSet: OrderedCollection new firstSets: self firstSets into: cycles. |
|
140 |
^ cycles |
|
141 |
! ! |
|
142 |
||
143 |
!PPParser methodsFor:'*petitanalyzer-private'! |
|
144 |
||
145 |
cycleSet: aDictionary |
|
146 |
"PRIVATE: Answer the children that could be part of a cycle-set with the receiver, subclasses might restrict the number of children returned. aDictionary is pre-calcualted first-sets." |
|
147 |
||
148 |
^ self children |
|
149 |
! ! |
|
150 |
||
151 |
!PPParser methodsFor:'*petitanalyzer-private'! |
|
152 |
||
153 |
cycleSet: aStack firstSets: aDictionary into: aSet |
|
154 |
"PRIVATE: Try to find a cycle, where aStack contains the previously visited parsers. The method returns quickly when the receiver is a terminal, terminals cannot be part of a cycle. If aStack already contains the receiver, then we are in a cycle. In this case we don't process the children further and add the nodes to aSet." |
|
155 |
||
156 |
| index | |
|
157 |
self isTerminal |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
158 |
ifTrue: [ ^ self ]. |
262 | 159 |
(index := aStack indexOf: self) > 0 |
160 |
ifTrue: [ ^ aSet addAll: (aStack copyFrom: index to: aStack size) ]. |
|
161 |
aStack addLast: self. |
|
162 |
(self cycleSet: aDictionary) |
|
163 |
do: [ :each | each cycleSet: aStack firstSets: aDictionary into: aSet ]. |
|
164 |
aStack removeLast |
|
165 |
! ! |
|
166 |
||
167 |
!PPParser methodsFor:'*petitanalyzer-querying'! |
|
168 |
||
169 |
firstSet |
|
170 |
"Answer the first-set of the receiver. Note, this implementation is inefficient when called on different receivers of the same grammar, instead use #firstSets to calculate the first-sets at once." |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
171 |
|
262 | 172 |
^ self firstSets at: self |
173 |
! ! |
|
174 |
||
175 |
!PPParser methodsFor:'*petitanalyzer-querying'! |
|
176 |
||
177 |
firstSets |
|
178 |
"Answer a dictionary with all the parsers reachable from the receiver as key and their first-set as value. The first-set of a parser is the list of terminal parsers that begin the parser derivable from that parser." |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
179 |
|
262 | 180 |
| firstSets | |
181 |
firstSets := IdentityDictionary new. |
|
182 |
self allParsersDo: [ :each | |
|
378
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
183 |
firstSets at: each put: (each isFirstSetTerminal |
262 | 184 |
ifTrue: [ IdentitySet with: each ] |
185 |
ifFalse: [ IdentitySet new ]). |
|
186 |
each isNullable |
|
187 |
ifTrue: [ (firstSets at: each) add: PPSentinel instance ] ]. |
|
188 |
[ | changed tally | |
|
189 |
changed := false. |
|
190 |
firstSets keysAndValuesDo: [ :parser :first | |
|
191 |
tally := first size. |
|
192 |
parser firstSets: firstSets into: first. |
|
193 |
changed := changed or: [ tally ~= first size ] ]. |
|
194 |
changed ] whileTrue. |
|
195 |
^ firstSets |
|
196 |
! ! |
|
197 |
||
198 |
!PPParser methodsFor:'*petitanalyzer-private'! |
|
199 |
||
200 |
firstSets: aFirstDictionary into: aSet |
|
201 |
"PRIVATE: Try to add additional elements to the first-set aSet of the receiver, use the incomplete aFirstDictionary." |
|
202 |
||
203 |
self children do: [ :parser | aSet addAll: (aFirstDictionary at: parser) ] |
|
204 |
! ! |
|
205 |
||
206 |
!PPParser methodsFor:'*petitanalyzer-querying'! |
|
207 |
||
208 |
followSet |
|
209 |
"Answer the follow-set of the receiver starting at the receiver. Note, this implementation is inefficient when called on different receivers of the same grammar, instead use #followSets to calculate the follow-sets at once." |
|
210 |
||
211 |
^ self followSets at: self |
|
212 |
! ! |
|
213 |
||
214 |
!PPParser methodsFor:'*petitanalyzer-querying'! |
|
215 |
||
216 |
followSets |
|
217 |
"Answer a dictionary with all the parsers reachable from the receiver as key and their follow-set as value. The follow-set of a parser is the list of terminal parsers that can appear immediately to the right of that parser." |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
218 |
|
262 | 219 |
| current previous continue firstSets followSets | |
220 |
current := previous := 0. |
|
221 |
firstSets := self firstSets. |
|
222 |
followSets := IdentityDictionary new. |
|
223 |
self allParsersDo: [ :each | followSets at: each put: IdentitySet new ]. |
|
224 |
(followSets at: self) add: PPSentinel instance. |
|
225 |
[ followSets keysAndValuesDo: [ :parser :follow | |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
226 |
parser |
262 | 227 |
followSets: followSets |
228 |
firstSets: firstSets |
|
229 |
into: follow ]. |
|
230 |
current := followSets |
|
231 |
inject: 0 |
|
232 |
into: [ :result :each | result + each size ]. |
|
233 |
continue := previous < current. |
|
234 |
previous := current. |
|
235 |
continue ] whileTrue. |
|
236 |
^ followSets |
|
237 |
! ! |
|
238 |
||
239 |
!PPParser methodsFor:'*petitanalyzer-private'! |
|
240 |
||
241 |
followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet |
|
242 |
"PRIVATE: Try to add additional elements to the follow-set aSet of the receiver, use the incomplete aFollowDictionary and the complete aFirstDictionary." |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
243 |
|
262 | 244 |
self children do: [ :parser | (aFollowDictionary at: parser) addAll: aSet ] |
245 |
! ! |
|
246 |
||
247 |
!PPParser methodsFor:'*petitanalyzer-named'! |
|
248 |
||
249 |
innerChildren |
|
250 |
"Answer the inner children of the receiver." |
|
251 |
||
252 |
| result | |
|
253 |
result := OrderedCollection new. |
|
254 |
self innerChildrenDo: [ :parser | result addLast: parser ]. |
|
255 |
^ result |
|
256 |
! ! |
|
257 |
||
258 |
!PPParser methodsFor:'*petitanalyzer-named'! |
|
259 |
||
260 |
innerChildrenDo: aBlock |
|
261 |
"Iterate over the inner children of the receiver." |
|
262 |
||
263 |
self innerChildrenDo: aBlock seen: IdentitySet new |
|
264 |
! ! |
|
265 |
||
266 |
!PPParser methodsFor:'*petitanalyzer-named'! |
|
267 |
||
268 |
innerChildrenDo: aBlock seen: aSet |
|
269 |
"Iterate over the inner children of the receiver." |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
270 |
|
262 | 271 |
self children do: [ :each | |
272 |
(aSet includes: each) |
|
273 |
ifTrue: [ ^ self ]. |
|
274 |
aSet add: each. |
|
275 |
each name isNil ifTrue: [ |
|
276 |
aBlock value: each. |
|
277 |
each innerChildrenDo: aBlock seen: aSet ] ] |
|
278 |
! ! |
|
279 |
||
280 |
!PPParser methodsFor:'*petitanalyzer-testing'! |
|
281 |
||
378
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
282 |
isFirstSetTerminal |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
283 |
"Answer true if the receiver is a terminal or leaf parser, that means it does not delegate to any other parser." |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
284 |
|
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
285 |
^ self children isEmpty |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
286 |
! ! |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
287 |
|
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
288 |
!PPParser methodsFor:'*petitanalyzer-testing'! |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
289 |
|
262 | 290 |
isNullable |
291 |
"Answer true if the receiver is a nullable parser, e.g. it can successfully parse nothing." |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
292 |
|
262 | 293 |
^ false |
294 |
! ! |
|
295 |
||
296 |
!PPParser methodsFor:'*petitanalyzer-testing'! |
|
297 |
||
298 |
isTerminal |
|
299 |
"Answer true if the receiver is a terminal or leaf parser, that means it does not delegate to any other parser." |
|
300 |
||
301 |
^ self children isEmpty |
|
302 |
! ! |
|
303 |
||
304 |
!PPParser methodsFor:'*petitanalyzer-matching'! |
|
305 |
||
306 |
match: aParser inContext: aDictionary |
|
307 |
^ self match: aParser inContext: aDictionary seen: IdentitySet new |
|
308 |
! ! |
|
309 |
||
310 |
!PPParser methodsFor:'*petitanalyzer-matching'! |
|
311 |
||
312 |
match: aParser inContext: aDictionary seen: anIdentitySet |
|
313 |
"This is the default implementation to match two parsers. This code can properly handle recursion. This is code is supposed to be overridden in subclasses that add new state." |
|
314 |
||
315 |
(self == aParser or: [ anIdentitySet includes: self ]) |
|
316 |
ifTrue: [ ^ true ]. |
|
317 |
anIdentitySet add: self. |
|
318 |
^ self class = aParser class and: [ self matchList: self children against: aParser children inContext: aDictionary seen: anIdentitySet ] |
|
319 |
! ! |
|
320 |
||
321 |
!PPParser methodsFor:'*petitanalyzer-matching'! |
|
322 |
||
323 |
matchList: matchList against: parserList inContext: aDictionary seen: aSet |
|
324 |
^ self matchList: matchList index: 1 against: parserList index: 1 inContext: aDictionary seen: aSet |
|
325 |
! ! |
|
326 |
||
327 |
!PPParser methodsFor:'*petitanalyzer-matching'! |
|
328 |
||
329 |
matchList: matchList index: matchIndex against: parserList index: parserIndex inContext: aDictionary seen: aSet |
|
330 |
| parser currentIndex currentDictionary currentSeen parsers | |
|
331 |
matchList size < matchIndex |
|
332 |
ifTrue: [ ^ parserList size < parserIndex ]. |
|
333 |
parser := matchList at: matchIndex. |
|
334 |
parser class = PPListPattern ifTrue: [ |
|
335 |
currentIndex := parserIndex - 1. |
|
336 |
[ currentDictionary := aDictionary copy. |
|
337 |
currentSeen := aSet copy. |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
338 |
parserList size < currentIndex or: [ |
262 | 339 |
parsers := parserList copyFrom: parserIndex to: currentIndex. |
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
340 |
(currentDictionary at: parser ifAbsentPut: [ parsers ]) = parsers and: [ |
262 | 341 |
(self |
342 |
matchList: matchList |
|
343 |
index: matchIndex + 1 |
|
344 |
against: parserList |
|
345 |
index: currentIndex + 1 |
|
346 |
inContext: currentDictionary |
|
347 |
seen: currentSeen) |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
348 |
ifTrue: [ |
262 | 349 |
currentDictionary keysAndValuesDo: [ :key :value | aDictionary at: key put: value ]. |
350 |
^ true ]. |
|
351 |
false ] ] ] whileFalse: [ currentIndex := currentIndex + 1 ]. |
|
352 |
^ false ]. |
|
353 |
parserList size < parserIndex |
|
354 |
ifTrue: [ ^ false ]. |
|
355 |
(parser match: (parserList at: parserIndex) inContext: aDictionary seen: aSet) |
|
356 |
ifFalse: [ ^ false ]. |
|
357 |
^ self |
|
358 |
matchList: matchList |
|
359 |
index: matchIndex + 1 |
|
360 |
against: parserList |
|
361 |
index: parserIndex + 1 |
|
362 |
inContext: aDictionary |
|
363 |
seen: aSet |
|
364 |
! ! |
|
365 |
||
366 |
!PPParser methodsFor:'*petitanalyzer-named'! |
|
367 |
||
368 |
namedChildren |
|
369 |
"Answer the named children of the receiver." |
|
370 |
||
371 |
| result | |
|
372 |
result := OrderedCollection new. |
|
373 |
self namedChildrenDo: [ :parser | result addLast: parser ]. |
|
374 |
^ result |
|
375 |
! ! |
|
376 |
||
377 |
!PPParser methodsFor:'*petitanalyzer-named'! |
|
378 |
||
379 |
namedChildrenDo: aBlock |
|
380 |
"Iterate over the named children of the receiver." |
|
381 |
||
382 |
self namedChildrenDo: aBlock seen: IdentitySet new |
|
383 |
! ! |
|
384 |
||
385 |
!PPParser methodsFor:'*petitanalyzer-named'! |
|
386 |
||
387 |
namedChildrenDo: aBlock seen: aSet |
|
388 |
"Iterate over the named children of the receiver." |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
389 |
|
262 | 390 |
self children do: [ :each | |
391 |
(aSet includes: each) |
|
392 |
ifTrue: [ ^ self ]. |
|
393 |
aSet add: each. |
|
394 |
each name isNil |
|
395 |
ifTrue: [ each namedChildrenDo: aBlock seen: aSet ] |
|
396 |
ifFalse: [ aBlock value: each ] ] |
|
397 |
! ! |
|
398 |
||
399 |
!PPParser methodsFor:'*petitanalyzer-transforming'! |
|
400 |
||
401 |
replace: aParser with: anotherParser |
|
402 |
"Replace the references of the receiver pointing to aParser with anotherParser." |
|
403 |
! ! |
|
404 |
||
405 |
!PPParser methodsFor:'*petitanalyzer-transforming'! |
|
406 |
||
407 |
transform: aBlock |
|
408 |
"Answer a copy of all parsers reachable from the receiver transformed using aBlock." |
|
409 |
||
410 |
| mapping root | |
|
411 |
mapping := IdentityDictionary new. |
|
412 |
self allParsersDo: [ :each | |
|
413 |
mapping |
|
414 |
at: each |
|
415 |
put: (aBlock value: each copy) ]. |
|
416 |
root := mapping at: self. |
|
417 |
[ | changed | |
|
418 |
changed := false. |
|
419 |
root allParsersDo: [ :each | |
|
420 |
each children do: [ :old | |
|
421 |
mapping at: old ifPresent: [ :new | |
|
422 |
each replace: old with: new. |
|
423 |
changed := true ] ] ]. |
|
424 |
changed ] whileTrue. |
|
425 |
^ root |
|
426 |
! ! |
|
427 |
||
428 |
!PPPluggableParser methodsFor:'*petitanalyzer-matching'! |
|
429 |
||
430 |
match: aParser inContext: aDictionary seen: anIdentitySet |
|
431 |
^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self block = aParser block ] |
|
432 |
! ! |
|
433 |
||
434 |
!PPPredicateParser methodsFor:'*petitanalyzer-matching'! |
|
435 |
||
436 |
match: aParser inContext: aDictionary seen: anIdentitySet |
|
437 |
^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self block = aParser block and: [ self message = aParser message ] ] |
|
438 |
! ! |
|
439 |
||
440 |
!PPPredicateSequenceParser methodsFor:'*petitanalyzer-matching'! |
|
441 |
||
442 |
match: aParser inContext: aDictionary seen: anIdentitySet |
|
443 |
^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self size = aParser size ] |
|
444 |
! ! |
|
445 |
||
378
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
446 |
!PPRepeatingParser methodsFor:'*petitanalyzer-private'! |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
447 |
|
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
448 |
followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
449 |
| firstSet | |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
450 |
super followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet. |
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
451 |
|
378
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
452 |
firstSet := aFirstDictionary at: self. |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
453 |
self children do: [:p | (aFollowDictionary at: p) addAll: (firstSet reject: [:each | each isNullable]) ] |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
454 |
! ! |
53d66ecfeb1b
Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
376
diff
changeset
|
455 |
|
262 | 456 |
!PPRepeatingParser methodsFor:'*petitanalyzer-testing'! |
457 |
||
458 |
isNullable |
|
459 |
^ min = 0 |
|
460 |
! ! |
|
461 |
||
462 |
!PPRepeatingParser methodsFor:'*petitanalyzer-matching'! |
|
463 |
||
464 |
match: aParser inContext: aDictionary seen: anIdentitySet |
|
465 |
^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self min = aParser min and: [ self max = aParser max ] ] |
|
466 |
! ! |
|
467 |
||
468 |
!PPSequenceParser methodsFor:'*petitanalyzer-private'! |
|
469 |
||
470 |
cycleSet: aDictionary |
|
471 |
| firstSet | |
|
472 |
1 to: parsers size do: [ :index | |
|
473 |
firstSet := aDictionary at: (parsers at: index). |
|
474 |
(firstSet anySatisfy: [ :each | each isNullable ]) |
|
475 |
ifFalse: [ ^ parsers copyFrom: 1 to: index ] ]. |
|
476 |
^ parsers |
|
477 |
! ! |
|
478 |
||
479 |
!PPSequenceParser methodsFor:'*petitanalyzer-private'! |
|
480 |
||
481 |
firstSets: aFirstDictionary into: aSet |
|
482 |
| nullable | |
|
483 |
parsers do: [ :parser | |
|
484 |
nullable := false. |
|
485 |
(aFirstDictionary at: parser) do: [ :each | |
|
486 |
each isNullable |
|
487 |
ifTrue: [ nullable := true ] |
|
488 |
ifFalse: [ aSet add: each ] ]. |
|
489 |
nullable |
|
490 |
ifFalse: [ ^ self ] ]. |
|
491 |
aSet add: PPSentinel instance |
|
492 |
! ! |
|
493 |
||
494 |
!PPSequenceParser methodsFor:'*petitanalyzer-private'! |
|
495 |
||
496 |
followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet |
|
497 |
parsers keysAndValuesDo: [ :index :parser | |
|
498 |
| followSet firstSet | |
|
499 |
followSet := aFollowDictionary at: parser. |
|
500 |
index = parsers size |
|
501 |
ifTrue: [ followSet addAll: aSet ] |
|
502 |
ifFalse: [ |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
503 |
(self class withAll: (parsers |
262 | 504 |
copyFrom: index + 1 to: parsers size)) |
505 |
firstSets: aFirstDictionary |
|
506 |
into: (firstSet := IdentitySet new). |
|
507 |
(firstSet anySatisfy: [ :each | each isNullable ]) |
|
508 |
ifTrue: [ followSet addAll: aSet ]. |
|
382
1825151d6455
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
381
diff
changeset
|
509 |
followSet addAll: (firstSet |
262 | 510 |
reject: [ :each | each isNullable ]) ] ] |
511 |
! ! |
|
512 |
||
513 |
!PPTokenParser methodsFor:'*petitanalyzer-matching'! |
|
514 |
||
515 |
match: aParser inContext: aDictionary seen: anIdentitySet |
|
516 |
^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self tokenClass = aParser tokenClass ] |
|
517 |
! ! |
|
518 |
||
519 |
!stx_goodies_petitparser_analyzer class methodsFor:'documentation'! |
|
520 |
||
376
a2656b27cace
Added monticelloName to package definition to ease export to .mcz
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
284
diff
changeset
|
521 |
extensionsVersion_HG |
a2656b27cace
Added monticelloName to package definition to ease export to .mcz
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
284
diff
changeset
|
522 |
|
a2656b27cace
Added monticelloName to package definition to ease export to .mcz
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
284
diff
changeset
|
523 |
^ '$Changeset: <not expanded> $' |
262 | 524 |
! ! |