|
1 "{ Package: 'stx:goodies/petitparser' }" |
|
2 |
|
3 Object subclass:#PPContext |
|
4 instanceVariableNames:'stream root properties globals' |
|
5 classVariableNames:'' |
|
6 poolDictionaries:'' |
|
7 category:'PetitParser-Core' |
|
8 ! |
|
9 |
|
10 !PPContext class methodsFor:'as yet unclassified'! |
|
11 |
|
12 on: aPPParser stream: aStream |
|
13 ^ self basicNew |
|
14 initialize; |
|
15 root: aPPParser; |
|
16 stream: aStream asPetitStream; |
|
17 yourself |
|
18 ! ! |
|
19 |
|
20 !PPContext methodsFor:'accessing-globals'! |
|
21 |
|
22 globalAt: aKey |
|
23 "Answer the global property value associated with aKey." |
|
24 |
|
25 ^ self globalAt: aKey ifAbsent: [ self error: 'Property not found' ] |
|
26 ! |
|
27 |
|
28 globalAt: aKey ifAbsent: aBlock |
|
29 "Answer the global property value associated with aKey or, if aKey isn't found, answer the result of evaluating aBlock." |
|
30 |
|
31 ^ globals isNil |
|
32 ifTrue: [ aBlock value ] |
|
33 ifFalse: [ globals at: aKey ifAbsent: aBlock ] |
|
34 ! |
|
35 |
|
36 globalAt: aKey ifAbsentPut: aBlock |
|
37 "Answer the global property associated with aKey or, if aKey isn't found store the result of evaluating aBlock as new value." |
|
38 |
|
39 ^ self globalAt: aKey ifAbsent: [ self globalAt: aKey put: aBlock value ] |
|
40 ! |
|
41 |
|
42 globalAt: aKey put: anObject |
|
43 "Set the global property at aKey to be anObject. If aKey is not found, create a new entry for aKey and set is value to anObject. Answer anObject." |
|
44 |
|
45 ^ (globals ifNil: [ globals := Dictionary new: 1 ]) |
|
46 at: aKey put: anObject |
|
47 ! |
|
48 |
|
49 hasGlobal: aKey |
|
50 "Test if the global property aKey is present." |
|
51 |
|
52 ^ globals notNil and: [ globals includesKey: aKey ] |
|
53 ! |
|
54 |
|
55 removeGlobal: aKey |
|
56 "Remove the property with aKey. Answer the property or raise an error if aKey isn't found." |
|
57 |
|
58 ^ self removeGlobal: aKey ifAbsent: [ self error: 'Property not found' ] |
|
59 ! |
|
60 |
|
61 removeGlobal: aKey ifAbsent: aBlock |
|
62 "Remove the global property with aKey. Answer the value or, if aKey isn't found, answer the result of evaluating aBlock." |
|
63 |
|
64 | answer | |
|
65 globals isNil ifTrue: [ ^ aBlock value ]. |
|
66 answer := globals removeKey: aKey ifAbsent: aBlock. |
|
67 globals isEmpty ifTrue: [ globals := nil ]. |
|
68 ^ answer |
|
69 ! ! |
|
70 |
|
71 !PPContext methodsFor:'accessing-properties'! |
|
72 |
|
73 hasProperty: aKey |
|
74 "Test if the property aKey is present." |
|
75 |
|
76 ^ properties notNil and: [ properties includesKey: aKey ] |
|
77 ! |
|
78 |
|
79 propertyAt: aKey |
|
80 "Answer the property value associated with aKey." |
|
81 |
|
82 ^ self propertyAt: aKey ifAbsent: [ self error: 'Property not found' ] |
|
83 ! |
|
84 |
|
85 propertyAt: aKey ifAbsent: aBlock |
|
86 "Answer the property value associated with aKey or, if aKey isn't found, answer the result of evaluating aBlock." |
|
87 |
|
88 ^ properties isNil |
|
89 ifTrue: [ aBlock value ] |
|
90 ifFalse: [ properties at: aKey ifAbsent: aBlock ] |
|
91 ! |
|
92 |
|
93 propertyAt: aKey ifAbsentPut: aBlock |
|
94 "Answer the property associated with aKey or, if aKey isn't found store the result of evaluating aBlock as new value." |
|
95 |
|
96 ^ self propertyAt: aKey ifAbsent: [ self propertyAt: aKey put: aBlock value ] |
|
97 ! |
|
98 |
|
99 propertyAt: aKey put: anObject |
|
100 "Set the property at aKey to be anObject. If aKey is not found, create a new entry for aKey and set is value to anObject. Answer anObject." |
|
101 |
|
102 ^ (properties ifNil: [ properties := Dictionary new: 1 ]) |
|
103 at: aKey put: anObject |
|
104 ! |
|
105 |
|
106 removeProperty: aKey |
|
107 "Remove the property with aKey. Answer the property or raise an error if aKey isn't found." |
|
108 |
|
109 ^ self removeProperty: aKey ifAbsent: [ self error: 'Property not found' ] |
|
110 ! |
|
111 |
|
112 removeProperty: aKey ifAbsent: aBlock |
|
113 "Remove the property with aKey. Answer the value or, if aKey isn't found, answer the result of evaluating aBlock." |
|
114 |
|
115 | answer | |
|
116 properties isNil ifTrue: [ ^ aBlock value ]. |
|
117 answer := properties removeKey: aKey ifAbsent: aBlock. |
|
118 properties isEmpty ifTrue: [ properties := nil ]. |
|
119 ^ answer |
|
120 ! ! |
|
121 |
|
122 !PPContext methodsFor:'acessing'! |
|
123 |
|
124 root |
|
125 ^ root |
|
126 ! |
|
127 |
|
128 stream |
|
129 ^ stream |
|
130 ! |
|
131 |
|
132 stream: aStream |
|
133 stream := aStream. |
|
134 ! ! |
|
135 |
|
136 !PPContext methodsFor:'failures'! |
|
137 |
|
138 furthestFailure |
|
139 " the furthest failure encountered while parsing the input stream " |
|
140 |
|
141 ^ self globalAt: #furthestFailure ifAbsent: [ nil ] |
|
142 ! |
|
143 |
|
144 noteFailure: aPPFailure |
|
145 "record the furthest failure encountered while parsing the input stream " |
|
146 |
|
147 | furthestFailure | |
|
148 furthestFailure := self furthestFailure. |
|
149 ( furthestFailure isNil or: [ aPPFailure position > furthestFailure position ]) |
|
150 ifTrue: [ self globalAt: #furthestFailure put: aPPFailure ]. |
|
151 ! ! |
|
152 |
|
153 !PPContext methodsFor:'initialization'! |
|
154 |
|
155 initialize |
|
156 stream := nil. |
|
157 ! |
|
158 |
|
159 initializeFor: parser |
|
160 parser == root ifTrue: [ ^ self ]. |
|
161 |
|
162 root := parser. |
|
163 root allParsersDo: [ :p | |
|
164 p updateContext: self |
|
165 ] |
|
166 ! ! |
|
167 |
|
168 !PPContext methodsFor:'memoization'! |
|
169 |
|
170 remember |
|
171 | memento | |
|
172 memento := PPContextMemento new |
|
173 stream: stream; |
|
174 position: stream position; |
|
175 yourself. |
|
176 |
|
177 self rememberProperties: memento. |
|
178 ^ memento |
|
179 ! |
|
180 |
|
181 rememberProperties: aPPContextMemento |
|
182 properties ifNil: [ ^ self ]. |
|
183 |
|
184 properties keysAndValuesDo: [ :key :value | |
|
185 aPPContextMemento propertyAt: key put: value |
|
186 ]. |
|
187 ! |
|
188 |
|
189 restore: aPPContextMemento |
|
190 aPPContextMemento stream == stream ifFalse: [ self error: 'Oops!!' ]. |
|
191 |
|
192 stream position: aPPContextMemento position. |
|
193 self restoreProperties: aPPContextMemento. |
|
194 ! |
|
195 |
|
196 restoreProperties: aPPContextMemento |
|
197 aPPContextMemento stream == stream ifFalse: [ self error: 'Oops!!' ]. |
|
198 |
|
199 aPPContextMemento keysAndValuesDo: [ :key :value | |
|
200 self propertyAt: key put: value |
|
201 ]. |
|
202 ! ! |
|
203 |
|
204 !PPContext methodsFor:'stream mimicry'! |
|
205 |
|
206 atEnd |
|
207 ^ stream atEnd |
|
208 ! |
|
209 |
|
210 back |
|
211 ^ stream back |
|
212 ! |
|
213 |
|
214 collection |
|
215 ^ stream collection |
|
216 ! |
|
217 |
|
218 contents |
|
219 ^ stream contents |
|
220 ! |
|
221 |
|
222 isStartOfLine |
|
223 ^ stream isStartOfLine |
|
224 ! |
|
225 |
|
226 next |
|
227 ^ stream next |
|
228 ! |
|
229 |
|
230 next: anInteger |
|
231 ^ stream next: anInteger |
|
232 ! |
|
233 |
|
234 peek |
|
235 ^ stream peek |
|
236 ! |
|
237 |
|
238 peekTwice |
|
239 ^ stream peekTwice |
|
240 ! |
|
241 |
|
242 position |
|
243 ^ stream position |
|
244 ! |
|
245 |
|
246 position: anInteger |
|
247 ^ stream position: anInteger |
|
248 ! |
|
249 |
|
250 skip: anInteger |
|
251 ^ stream skip: anInteger |
|
252 ! |
|
253 |
|
254 uncheckedPeek |
|
255 ^ stream uncheckedPeek |
|
256 ! |
|
257 |
|
258 upTo: anObject |
|
259 ^ stream upTo: anObject |
|
260 ! |
|
261 |
|
262 upToAll: whatever |
|
263 ^ stream upToAll: whatever |
|
264 ! |
|
265 |
|
266 upToAnyOf: whatever |
|
267 ^ stream upToAnyOf: whatever |
|
268 ! ! |
|
269 |