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