52 |
64 |
53 !PEGFsaInterpret methodsFor:'running'! |
65 !PEGFsaInterpret methodsFor:'running'! |
54 |
66 |
55 interpret |
67 interpret |
56 | states newStates character run | |
68 | states newStates character run | |
57 maxPriority := SmallInteger minVal. |
|
58 newStates := IdentitySet with: fsa startState. |
69 newStates := IdentitySet with: fsa startState. |
59 retvals := IdentityDictionary new. |
70 retvals := IdentityDictionary new. |
60 |
71 |
61 self recordNewState: fsa startState position: 0. |
72 self recordNewState: fsa startState position: 0. |
62 |
73 |
63 self reportStart. |
74 self reportStart. |
64 self reportFsa: fsa. |
75 self reportFsa: fsa. |
65 |
76 |
66 run := stream atEnd not. |
77 run := "stream atEnd not" true. |
67 |
78 |
68 [run] whileTrue: [ |
79 [run] whileTrue: [ |
69 states := newStates. |
80 states := newStates. |
70 newStates := IdentitySet new. |
81 newStates := IdentitySet new. |
71 character := stream peek. |
82 character := stream peek codePoint. |
72 |
83 |
73 self reportStates: states. |
84 self reportStates: states. |
74 |
85 |
75 states do: [ :state | |
86 states do: [ :state | |
76 self expand: state on: character into: newStates. |
87 self expand: state on: character into: newStates. |
77 ]. |
88 ]. |
78 |
89 |
79 newStates isEmpty ifFalse: [ stream next ]. |
90 newStates isEmpty ifFalse: [ stream next ]. |
80 run := stream atEnd not and: [ newStates isEmpty not ]. |
91 run := "stream atEnd not and: [ "newStates isEmpty not" ]". |
81 ]. |
92 ]. |
82 |
93 ^ self return: states |
83 ^ self return: newStates |
|
84 ! |
94 ! |
85 |
95 |
86 interpret: anFsa on: aStream |
96 interpret: anFsa on: aStream |
87 fsa := anFsa. |
97 fsa := anFsa. |
88 stream := aStream. |
98 stream := aStream. |
102 ^ transitionsTaken anyOne priority <= t priority. |
112 ^ transitionsTaken anyOne priority <= t priority. |
103 " "]." |
113 " "]." |
104 ^ true |
114 ^ true |
105 ! |
115 ! |
106 |
116 |
107 expand: state on: character into: newStates "transitionsTaken: transitionsTaken" |
117 expand: state on: codePoint into: newStates |
108 | transitions transitionsTaken | |
118 state transitions do: [ :t | |
|
119 t isEpsilon ifTrue: [ |
|
120 (t destination isFinal) ifTrue: [ |
|
121 newStates add: t destination. |
|
122 self recordNewState: t destination position: stream position. |
|
123 ]. |
109 |
124 |
110 transitionsTaken := OrderedCollection new. |
125 "Descent into the next state" |
111 transitions := self sortedTransitionsFor: state. |
126 self expand: t destination |
112 transitions do: [ :t | |
127 on: codePoint |
113 (self allowsTransition: t from: state transitionsTaken: transitionsTaken) ifTrue: [ |
128 into: newStates. |
114 t isEpsilon ifTrue: [ |
129 ] ifFalse: [ |
115 (t destination isFinal) ifTrue: [ |
130 (t acceptsCodePoint: codePoint) ifTrue: [ |
116 newStates add: t destination. |
131 newStates add: t destination. |
117 self recordNewState: t destination position: stream position. |
132 self recordNewState: t destination. |
118 ]. |
133 ] |
119 |
134 ] |
120 "Descent into the next state" |
|
121 self expand: t destination |
|
122 on: character |
|
123 into: newStates. |
|
124 |
|
125 newStates isEmpty ifFalse: [ |
|
126 transitionsTaken add: t. |
|
127 ]. |
|
128 |
|
129 ] ifFalse: [ |
|
130 (t accepts: character) ifTrue: [ |
|
131 transitionsTaken add: t. |
|
132 newStates add: t destination. |
|
133 self recordNewState: t destination. |
|
134 ] |
|
135 ] |
|
136 ] |
|
137 ] |
135 ] |
138 ! |
136 ! |
139 |
137 |
140 recordNewState: state |
138 recordNewState: state |
141 ^ self recordNewState: state position: stream position + 1 |
139 ^ self recordNewState: state position: stream position + 1 |
142 ! |
140 ! |
143 |
141 |
144 recordNewState: state position: position |
142 recordNewState: state position: position |
145 (state isFinal) ifFalse: [ ^ self ]. |
143 | currentRecord | |
146 (maxPriority > state priority) ifTrue: [ ^ true ]. |
144 (state isFinal) ifFalse: [ |
147 |
145 ^ self |
148 self assert: state hasPriority description: 'final state must have priority'. |
|
149 (maxPriority < state priority) ifTrue: [ |
|
150 retvals := IdentityDictionary new. |
|
151 maxPriority := state priority. |
|
152 ]. |
146 ]. |
153 |
147 |
|
148 (state isFinal) ifFalse: [ self error: 'should not happen' ]. |
|
149 self assert: state hasPriority description: 'final state must have priority'. |
154 |
150 |
155 state retvalAsCollection do: [ :r | |
151 state retvalsAndInfosDo: [ :retval :info | |
156 retvals at: r put: position |
152 currentRecord := self recordFor: retval. |
|
153 info isFsaFailure ifTrue: [ |
|
154 "JK: hack, nil refers to failure!! :( Refactor!!" |
|
155 currentRecord position: nil |
|
156 ] ifFalse: [ |
|
157 currentRecord position: position |
|
158 ] |
157 ]. |
159 ]. |
158 ! |
160 ! |
159 |
161 |
160 return: states |
162 return: states |
161 | priority priorities | |
163 | return | |
162 priorities := (states select: #hasPriority thenCollect: #priority). |
164 return := IdentityDictionary new. |
163 priorities isEmpty ifTrue: [ |
165 retvals keysAndValuesRemove: [ :key :record | record position isNil ]. |
164 ^ retvals keysAndValuesRemove: [ :key :value | key class == PEGFsaFailure ] |
166 |
|
167 retvals keysAndValuesDo: [ :key :value | |
|
168 return at: key put: value position |
165 ]. |
169 ]. |
166 |
170 ^ return |
167 priority := priorities max. |
|
168 |
|
169 (maxPriority < priority) ifTrue: [ ^ IdentityDictionary new ]. |
|
170 ^ retvals keysAndValuesRemove: [ :key :value | key class == PEGFsaFailure ] |
|
171 ! |
171 ! |
172 |
172 |
173 sortedTransitionsFor: state |
173 sortedTransitionsFor: state |
|
174 self error: 'deprecated!!'. |
174 ^ (fsa transitionsFor: state) asOrderedCollection |
175 ^ (fsa transitionsFor: state) asOrderedCollection |
175 "Dear future me, enjoy this:" |
176 "Dear future me, enjoy this:" |
176 " sort: [ :e1 :e2 | (e1 isEpsilon not and: [e2 isEpsilon]) not ])" |
177 " sort: [ :e1 :e2 | (e1 isEpsilon not and: [e2 isEpsilon]) not ])" |
177 sort: [ :e1 :e2 | e1 priority > e2 priority ] |
178 sort: [ :e1 :e2 | e1 priority > e2 priority ] |
178 |
179 |