|
1 "{ Package: 'stx:goodies/petitparser/compiler/benchmarks' }" |
|
2 |
|
3 Object subclass:#PPCBenchmarkResources |
|
4 instanceVariableNames:'' |
|
5 classVariableNames:'javaCache' |
|
6 poolDictionaries:'' |
|
7 category:'PetitCompiler-Benchmarks' |
|
8 ! |
|
9 |
|
10 !PPCBenchmarkResources methodsFor:'as yet unclassified'! |
|
11 |
|
12 changesSized: size |
|
13 | string changes | |
|
14 changes := PharoFilesOpener default changesFileOrNil contents. |
|
15 string := changes copyFrom: 1 to: size. |
|
16 ^ string |
|
17 |
|
18 ! |
|
19 |
|
20 javaInDirectory: directory |
|
21 | files | |
|
22 files := self readDirectory: directory. |
|
23 files := self files: files withExtension: 'java'. |
|
24 |
|
25 ^ files collect: [ :f | (FileStream fileNamed: f) contents ] |
|
26 ! |
|
27 |
|
28 javaLangClass |
|
29 ! |
|
30 |
|
31 javaLangMath |
|
32 ^ '/* |
|
33 * @(#)Math.java 1.69 04/06/14 |
|
34 * |
|
35 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. |
|
36 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. |
|
37 */ |
|
38 |
|
39 package java.lang; |
|
40 import java.util.Random; |
|
41 |
|
42 |
|
43 /** |
|
44 * The class <code>Math</code> contains methods for performing basic |
|
45 * numeric operations such as the elementary exponential, logarithm, |
|
46 * square root, and trigonometric functions. |
|
47 * |
|
48 * <p>Unlike some of the numeric methods of class |
|
49 * <code>StrictMath</code>, all implementations of the equivalent |
|
50 * functions of class <code>Math</code> are not defined to return the |
|
51 * bit-for-bit same results. This relaxation permits |
|
52 * better-performing implementations where strict reproducibility is |
|
53 * not required. |
|
54 * |
|
55 * <p>By default many of the <code>Math</code> methods simply call |
|
56 * the equivalent method in <code>StrictMath</code> for their |
|
57 * implementation. Code generators are encouraged to use |
|
58 * platform-specific native libraries or microprocessor instructions, |
|
59 * where available, to provide higher-performance implementations of |
|
60 * <code>Math</code> methods. Such higher-performance |
|
61 * implementations still must conform to the specification for |
|
62 * <code>Math</code>. |
|
63 * |
|
64 * <p>The quality of implementation specifications concern two |
|
65 * properties, accuracy of the returned result and monotonicity of the |
|
66 * method. Accuracy of the floating-point <code>Math</code> methods |
|
67 * is measured in terms of <i>ulps</i>, units in the last place. For |
|
68 * a given floating-point format, an ulp of a specific real number |
|
69 * value is the distance between the two floating-point values |
|
70 * bracketing that numerical value. When discussing the accuracy of a |
|
71 * method as a whole rather than at a specific argument, the number of |
|
72 * ulps cited is for the worst-case error at any argument. If a |
|
73 * method always has an error less than 0.5 ulps, the method always |
|
74 * returns the floating-point number nearest the exact result; such a |
|
75 * method is <i>correctly rounded</i>. A correctly rounded method is |
|
76 * generally the best a floating-point approximation can be; however, |
|
77 * it is impractical for many floating-point methods to be correctly |
|
78 * rounded. Instead, for the <code>Math</code> class, a larger error |
|
79 * bound of 1 or 2 ulps is allowed for certain methods. Informally, |
|
80 * with a 1 ulp error bound, when the exact result is a representable |
|
81 * number, the exact result should be returned as the computed result; |
|
82 * otherwise, either of the two floating-point values which bracket |
|
83 * the exact result may be returned. For exact results large in |
|
84 * magnitude, one of the endpoints of the bracket may be infinite. |
|
85 * Besides accuracy at individual arguments, maintaining proper |
|
86 * relations between the method at different arguments is also |
|
87 * important. Therefore, most methods with more than 0.5 ulp errors |
|
88 * are required to be <i>semi-monotonic</i>: whenever the mathematical |
|
89 * function is non-decreasing, so is the floating-point approximation, |
|
90 * likewise, whenever the mathematical function is non-increasing, so |
|
91 * is the floating-point approximation. Not all approximations that |
|
92 * have 1 ulp accuracy will automatically meet the monotonicity |
|
93 * requirements. |
|
94 * |
|
95 * @author unascribed |
|
96 * @author Joseph D. Darcy |
|
97 * @version 1.69, 06/14/04 |
|
98 * @since JDK1.0 |
|
99 */ |
|
100 |
|
101 public final class Math { |
|
102 |
|
103 /** |
|
104 * Don''t let anyone instantiate this class. |
|
105 */ |
|
106 private Math() {} |
|
107 |
|
108 /** |
|
109 * The <code>double</code> value that is closer than any other to |
|
110 * <i>e</i>, the base of the natural logarithms. |
|
111 */ |
|
112 public static final double E = 2.7182818284590452354; |
|
113 |
|
114 /** |
|
115 * The <code>double</code> value that is closer than any other to |
|
116 * <i>pi</i>, the ratio of the circumference of a circle to its |
|
117 * diameter. |
|
118 */ |
|
119 public static final double PI = 3.14159265358979323846; |
|
120 |
|
121 /** |
|
122 * Returns the trigonometric sine of an angle. Special cases: |
|
123 * <ul><li>If the argument is NaN or an infinity, then the |
|
124 * result is NaN. |
|
125 * <li>If the argument is zero, then the result is a zero with the |
|
126 * same sign as the argument.</ul> |
|
127 * |
|
128 * <p>The computed result must be within 1 ulp of the exact result. |
|
129 * Results must be semi-monotonic. |
|
130 * |
|
131 * @param a an angle, in radians. |
|
132 * @return the sine of the argument. |
|
133 */ |
|
134 public static double sin(double a) { |
|
135 return StrictMath.sin(a); // default impl. delegates to StrictMath |
|
136 } |
|
137 |
|
138 /** |
|
139 * Returns the trigonometric cosine of an angle. Special cases: |
|
140 * <ul><li>If the argument is NaN or an infinity, then the |
|
141 * result is NaN.</ul> |
|
142 * |
|
143 * <p>The computed result must be within 1 ulp of the exact result. |
|
144 * Results must be semi-monotonic. |
|
145 * |
|
146 * @param a an angle, in radians. |
|
147 * @return the cosine of the argument. |
|
148 */ |
|
149 public static double cos(double a) { |
|
150 return StrictMath.cos(a); // default impl. delegates to StrictMath |
|
151 } |
|
152 |
|
153 /** |
|
154 * Returns the trigonometric tangent of an angle. Special cases: |
|
155 * <ul><li>If the argument is NaN or an infinity, then the result |
|
156 * is NaN. |
|
157 * <li>If the argument is zero, then the result is a zero with the |
|
158 * same sign as the argument.</ul> |
|
159 * |
|
160 * <p>The computed result must be within 1 ulp of the exact result. |
|
161 * Results must be semi-monotonic. |
|
162 * |
|
163 * @param a an angle, in radians. |
|
164 * @return the tangent of the argument. |
|
165 */ |
|
166 public static double tan(double a) { |
|
167 return StrictMath.tan(a); // default impl. delegates to StrictMath |
|
168 } |
|
169 |
|
170 /** |
|
171 * Returns the arc sine of an angle, in the range of -<i>pi</i>/2 through |
|
172 * <i>pi</i>/2. Special cases: |
|
173 * <ul><li>If the argument is NaN or its absolute value is greater |
|
174 * than 1, then the result is NaN. |
|
175 * <li>If the argument is zero, then the result is a zero with the |
|
176 * same sign as the argument.</ul> |
|
177 * |
|
178 * <p>The computed result must be within 1 ulp of the exact result. |
|
179 * Results must be semi-monotonic. |
|
180 * |
|
181 * @param a the value whose arc sine is to be returned. |
|
182 * @return the arc sine of the argument. |
|
183 */ |
|
184 public static double asin(double a) { |
|
185 return StrictMath.asin(a); // default impl. delegates to StrictMath |
|
186 } |
|
187 |
|
188 /** |
|
189 * Returns the arc cosine of an angle, in the range of 0.0 through |
|
190 * <i>pi</i>. Special case: |
|
191 * <ul><li>If the argument is NaN or its absolute value is greater |
|
192 * than 1, then the result is NaN.</ul> |
|
193 * |
|
194 * <p>The computed result must be within 1 ulp of the exact result. |
|
195 * Results must be semi-monotonic. |
|
196 * |
|
197 * @param a the value whose arc cosine is to be returned. |
|
198 * @return the arc cosine of the argument. |
|
199 */ |
|
200 public static double acos(double a) { |
|
201 return StrictMath.acos(a); // default impl. delegates to StrictMath |
|
202 } |
|
203 |
|
204 /** |
|
205 * Returns the arc tangent of an angle, in the range of -<i>pi</i>/2 |
|
206 * through <i>pi</i>/2. Special cases: |
|
207 * <ul><li>If the argument is NaN, then the result is NaN. |
|
208 * <li>If the argument is zero, then the result is a zero with the |
|
209 * same sign as the argument.</ul> |
|
210 * |
|
211 * <p>The computed result must be within 1 ulp of the exact result. |
|
212 * Results must be semi-monotonic. |
|
213 * |
|
214 * @param a the value whose arc tangent is to be returned. |
|
215 * @return the arc tangent of the argument. |
|
216 */ |
|
217 public static double atan(double a) { |
|
218 return StrictMath.atan(a); // default impl. delegates to StrictMath |
|
219 } |
|
220 |
|
221 /** |
|
222 * Converts an angle measured in degrees to an approximately |
|
223 * equivalent angle measured in radians. The conversion from |
|
224 * degrees to radians is generally inexact. |
|
225 * |
|
226 * @param angdeg an angle, in degrees |
|
227 * @return the measurement of the angle <code>angdeg</code> |
|
228 * in radians. |
|
229 * @since 1.2 |
|
230 */ |
|
231 public static double toRadians(double angdeg) { |
|
232 return angdeg / 180.0 * PI; |
|
233 } |
|
234 |
|
235 /** |
|
236 * Converts an angle measured in radians to an approximately |
|
237 * equivalent angle measured in degrees. The conversion from |
|
238 * radians to degrees is generally inexact; users should |
|
239 * <i>not</i> expect <code>cos(toRadians(90.0))</code> to exactly |
|
240 * equal <code>0.0</code>. |
|
241 * |
|
242 * @param angrad an angle, in radians |
|
243 * @return the measurement of the angle <code>angrad</code> |
|
244 * in degrees. |
|
245 * @since 1.2 |
|
246 */ |
|
247 public static double toDegrees(double angrad) { |
|
248 return angrad * 180.0 / PI; |
|
249 } |
|
250 |
|
251 /** |
|
252 * Returns Euler''s number <i>e</i> raised to the power of a |
|
253 * <code>double</code> value. Special cases: |
|
254 * <ul><li>If the argument is NaN, the result is NaN. |
|
255 * <li>If the argument is positive infinity, then the result is |
|
256 * positive infinity. |
|
257 * <li>If the argument is negative infinity, then the result is |
|
258 * positive zero.</ul> |
|
259 * |
|
260 * <p>The computed result must be within 1 ulp of the exact result. |
|
261 * Results must be semi-monotonic. |
|
262 * |
|
263 * @param a the exponent to raise <i>e</i> to. |
|
264 * @return the value <i>e</i><sup><code>a</code></sup>, |
|
265 * where <i>e</i> is the base of the natural logarithms. |
|
266 */ |
|
267 public static double exp(double a) { |
|
268 return StrictMath.exp(a); // default impl. delegates to StrictMath |
|
269 } |
|
270 |
|
271 /** |
|
272 * Returns the natural logarithm (base <i>e</i>) of a <code>double</code> |
|
273 * value. Special cases: |
|
274 * <ul><li>If the argument is NaN or less than zero, then the result |
|
275 * is NaN. |
|
276 * <li>If the argument is positive infinity, then the result is |
|
277 * positive infinity. |
|
278 * <li>If the argument is positive zero or negative zero, then the |
|
279 * result is negative infinity.</ul> |
|
280 * |
|
281 * <p>The computed result must be within 1 ulp of the exact result. |
|
282 * Results must be semi-monotonic. |
|
283 * |
|
284 * @param a a value |
|
285 * @return the value ln <code>a</code>, the natural logarithm of |
|
286 * <code>a</code>. |
|
287 */ |
|
288 public static double log(double a) { |
|
289 return StrictMath.log(a); // default impl. delegates to StrictMath |
|
290 } |
|
291 |
|
292 /** |
|
293 * Returns the base 10 logarithm of a <code>double</code> value. |
|
294 * Special cases: |
|
295 * |
|
296 * <ul><li>If the argument is NaN or less than zero, then the result |
|
297 * is NaN. |
|
298 * <li>If the argument is positive infinity, then the result is |
|
299 * positive infinity. |
|
300 * <li>If the argument is positive zero or negative zero, then the |
|
301 * result is negative infinity. |
|
302 * <li> If the argument is equal to 10<sup><i>n</i></sup> for |
|
303 * integer <i>n</i>, then the result is <i>n</i>. |
|
304 * </ul> |
|
305 * |
|
306 * <p>The computed result must be within 1 ulp of the exact result. |
|
307 * Results must be semi-monotonic. |
|
308 * |
|
309 * @param a a value |
|
310 * @return the base 10 logarithm of <code>a</code>. |
|
311 * @since 1.5 |
|
312 */ |
|
313 public static double log10(double a) { |
|
314 return StrictMath.log10(a); // default impl. delegates to StrictMath |
|
315 } |
|
316 |
|
317 /** |
|
318 * Returns the correctly rounded positive square root of a |
|
319 * <code>double</code> value. |
|
320 * Special cases: |
|
321 * <ul><li>If the argument is NaN or less than zero, then the result |
|
322 * is NaN. |
|
323 * <li>If the argument is positive infinity, then the result is positive |
|
324 * infinity. |
|
325 * <li>If the argument is positive zero or negative zero, then the |
|
326 * result is the same as the argument.</ul> |
|
327 * Otherwise, the result is the <code>double</code> value closest to |
|
328 * the true mathematical square root of the argument value. |
|
329 * |
|
330 * @param a a value. |
|
331 * @return the positive square root of <code>a</code>. |
|
332 * If the argument is NaN or less than zero, the result is NaN. |
|
333 */ |
|
334 public static double sqrt(double a) { |
|
335 return StrictMath.sqrt(a); // default impl. delegates to StrictMath |
|
336 // Note that hardware sqrt instructions |
|
337 // frequently can be directly used by JITs |
|
338 // and should be much faster than doing |
|
339 // Math.sqrt in software. |
|
340 } |
|
341 |
|
342 |
|
343 /** |
|
344 * Returns the cube root of a <code>double</code> value. For |
|
345 * positive finite <code>x</code>, <code>cbrt(-x) == |
|
346 * -cbrt(x)</code>; that is, the cube root of a negative value is |
|
347 * the negative of the cube root of that value''s magnitude. |
|
348 * |
|
349 * Special cases: |
|
350 * |
|
351 * <ul> |
|
352 * |
|
353 * <li>If the argument is NaN, then the result is NaN. |
|
354 * |
|
355 * <li>If the argument is infinite, then the result is an infinity |
|
356 * with the same sign as the argument. |
|
357 * |
|
358 * <li>If the argument is zero, then the result is a zero with the |
|
359 * same sign as the argument. |
|
360 * |
|
361 * </ul> |
|
362 * |
|
363 * <p>The computed result must be within 1 ulp of the exact result. |
|
364 * |
|
365 * @param a a value. |
|
366 * @return the cube root of <code>a</code>. |
|
367 * @since 1.5 |
|
368 */ |
|
369 public static double cbrt(double a) { |
|
370 return StrictMath.cbrt(a); |
|
371 } |
|
372 |
|
373 /** |
|
374 * Computes the remainder operation on two arguments as prescribed |
|
375 * by the IEEE 754 standard. |
|
376 * The remainder value is mathematically equal to |
|
377 * <code>f1 - f2</code> × <i>n</i>, |
|
378 * where <i>n</i> is the mathematical integer closest to the exact |
|
379 * mathematical value of the quotient <code>f1/f2</code>, and if two |
|
380 * mathematical integers are equally close to <code>f1/f2</code>, |
|
381 * then <i>n</i> is the integer that is even. If the remainder is |
|
382 * zero, its sign is the same as the sign of the first argument. |
|
383 * Special cases: |
|
384 * <ul><li>If either argument is NaN, or the first argument is infinite, |
|
385 * or the second argument is positive zero or negative zero, then the |
|
386 * result is NaN. |
|
387 * <li>If the first argument is finite and the second argument is |
|
388 * infinite, then the result is the same as the first argument.</ul> |
|
389 * |
|
390 * @param f1 the dividend. |
|
391 * @param f2 the divisor. |
|
392 * @return the remainder when <code>f1</code> is divided by |
|
393 * <code>f2</code>. |
|
394 */ |
|
395 public static double IEEEremainder(double f1, double f2) { |
|
396 return StrictMath.IEEEremainder(f1, f2); // delegate to StrictMath |
|
397 } |
|
398 |
|
399 /** |
|
400 * Returns the smallest (closest to negative infinity) |
|
401 * <code>double</code> value that is greater than or equal to the |
|
402 * argument and is equal to a mathematical integer. Special cases: |
|
403 * <ul><li>If the argument value is already equal to a |
|
404 * mathematical integer, then the result is the same as the |
|
405 * argument. <li>If the argument is NaN or an infinity or |
|
406 * positive zero or negative zero, then the result is the same as |
|
407 * the argument. <li>If the argument value is less than zero but |
|
408 * greater than -1.0, then the result is negative zero.</ul> Note |
|
409 * that the value of <code>Math.ceil(x)</code> is exactly the |
|
410 * value of <code>-Math.floor(-x)</code>. |
|
411 * |
|
412 * |
|
413 * @param a a value. |
|
414 * @return the smallest (closest to negative infinity) |
|
415 * floating-point value that is greater than or equal to |
|
416 * the argument and is equal to a mathematical integer. |
|
417 */ |
|
418 public static double ceil(double a) { |
|
419 return StrictMath.ceil(a); // default impl. delegates to StrictMath |
|
420 } |
|
421 |
|
422 /** |
|
423 * Returns the largest (closest to positive infinity) |
|
424 * <code>double</code> value that is less than or equal to the |
|
425 * argument and is equal to a mathematical integer. Special cases: |
|
426 * <ul><li>If the argument value is already equal to a |
|
427 * mathematical integer, then the result is the same as the |
|
428 * argument. <li>If the argument is NaN or an infinity or |
|
429 * positive zero or negative zero, then the result is the same as |
|
430 * the argument.</ul> |
|
431 * |
|
432 * @param a a value. |
|
433 * @return the largest (closest to positive infinity) |
|
434 * floating-point value that less than or equal to the argument |
|
435 * and is equal to a mathematical integer. |
|
436 */ |
|
437 public static double floor(double a) { |
|
438 return StrictMath.floor(a); // default impl. delegates to StrictMath |
|
439 } |
|
440 |
|
441 /** |
|
442 * Returns the <code>double</code> value that is closest in value |
|
443 * to the argument and is equal to a mathematical integer. If two |
|
444 * <code>double</code> values that are mathematical integers are |
|
445 * equally close, the result is the integer value that is |
|
446 * even. Special cases: |
|
447 * <ul><li>If the argument value is already equal to a mathematical |
|
448 * integer, then the result is the same as the argument. |
|
449 * <li>If the argument is NaN or an infinity or positive zero or negative |
|
450 * zero, then the result is the same as the argument.</ul> |
|
451 * |
|
452 * @param a a <code>double</code> value. |
|
453 * @return the closest floating-point value to <code>a</code> that is |
|
454 * equal to a mathematical integer. |
|
455 */ |
|
456 public static double rint(double a) { |
|
457 return StrictMath.rint(a); // default impl. delegates to StrictMath |
|
458 } |
|
459 |
|
460 /** |
|
461 * Converts rectangular coordinates (<code>x</code>, <code>y</code>) |
|
462 * to polar (r, <i>theta</i>). |
|
463 * This method computes the phase <i>theta</i> by computing an arc tangent |
|
464 * of <code>y/x</code> in the range of -<i>pi</i> to <i>pi</i>. Special |
|
465 * cases: |
|
466 * <ul><li>If either argument is NaN, then the result is NaN. |
|
467 * <li>If the first argument is positive zero and the second argument |
|
468 * is positive, or the first argument is positive and finite and the |
|
469 * second argument is positive infinity, then the result is positive |
|
470 * zero. |
|
471 * <li>If the first argument is negative zero and the second argument |
|
472 * is positive, or the first argument is negative and finite and the |
|
473 * second argument is positive infinity, then the result is negative zero. |
|
474 * <li>If the first argument is positive zero and the second argument |
|
475 * is negative, or the first argument is positive and finite and the |
|
476 * second argument is negative infinity, then the result is the |
|
477 * <code>double</code> value closest to <i>pi</i>. |
|
478 * <li>If the first argument is negative zero and the second argument |
|
479 * is negative, or the first argument is negative and finite and the |
|
480 * second argument is negative infinity, then the result is the |
|
481 * <code>double</code> value closest to -<i>pi</i>. |
|
482 * <li>If the first argument is positive and the second argument is |
|
483 * positive zero or negative zero, or the first argument is positive |
|
484 * infinity and the second argument is finite, then the result is the |
|
485 * <code>double</code> value closest to <i>pi</i>/2. |
|
486 * <li>If the first argument is negative and the second argument is |
|
487 * positive zero or negative zero, or the first argument is negative |
|
488 * infinity and the second argument is finite, then the result is the |
|
489 * <code>double</code> value closest to -<i>pi</i>/2. |
|
490 * <li>If both arguments are positive infinity, then the result is the |
|
491 * <code>double</code> value closest to <i>pi</i>/4. |
|
492 * <li>If the first argument is positive infinity and the second argument |
|
493 * is negative infinity, then the result is the <code>double</code> |
|
494 * value closest to 3*<i>pi</i>/4. |
|
495 * <li>If the first argument is negative infinity and the second argument |
|
496 * is positive infinity, then the result is the <code>double</code> value |
|
497 * closest to -<i>pi</i>/4. |
|
498 * <li>If both arguments are negative infinity, then the result is the |
|
499 * <code>double</code> value closest to -3*<i>pi</i>/4.</ul> |
|
500 * |
|
501 * <p>The computed result must be within 2 ulps of the exact result. |
|
502 * Results must be semi-monotonic. |
|
503 * |
|
504 * @param y the ordinate coordinate |
|
505 * @param x the abscissa coordinate |
|
506 * @return the <i>theta</i> component of the point |
|
507 * (<i>r</i>, <i>theta</i>) |
|
508 * in polar coordinates that corresponds to the point |
|
509 * (<i>x</i>, <i>y</i>) in Cartesian coordinates. |
|
510 */ |
|
511 public static double atan2(double y, double x) { |
|
512 return StrictMath.atan2(y, x); // default impl. delegates to StrictMath |
|
513 } |
|
514 |
|
515 /** |
|
516 * Returns the value of the first argument raised to the power of the |
|
517 * second argument. Special cases: |
|
518 * |
|
519 * <ul><li>If the second argument is positive or negative zero, then the |
|
520 * result is 1.0. |
|
521 * <li>If the second argument is 1.0, then the result is the same as the |
|
522 * first argument. |
|
523 * <li>If the second argument is NaN, then the result is NaN. |
|
524 * <li>If the first argument is NaN and the second argument is nonzero, |
|
525 * then the result is NaN. |
|
526 * |
|
527 * <li>If |
|
528 * <ul> |
|
529 * <li>the absolute value of the first argument is greater than 1 |
|
530 * and the second argument is positive infinity, or |
|
531 * <li>the absolute value of the first argument is less than 1 and |
|
532 * the second argument is negative infinity, |
|
533 * </ul> |
|
534 * then the result is positive infinity. |
|
535 * |
|
536 * <li>If |
|
537 * <ul> |
|
538 * <li>the absolute value of the first argument is greater than 1 and |
|
539 * the second argument is negative infinity, or |
|
540 * <li>the absolute value of the |
|
541 * first argument is less than 1 and the second argument is positive |
|
542 * infinity, |
|
543 * </ul> |
|
544 * then the result is positive zero. |
|
545 * |
|
546 * <li>If the absolute value of the first argument equals 1 and the |
|
547 * second argument is infinite, then the result is NaN. |
|
548 * |
|
549 * <li>If |
|
550 * <ul> |
|
551 * <li>the first argument is positive zero and the second argument |
|
552 * is greater than zero, or |
|
553 * <li>the first argument is positive infinity and the second |
|
554 * argument is less than zero, |
|
555 * </ul> |
|
556 * then the result is positive zero. |
|
557 * |
|
558 * <li>If |
|
559 * <ul> |
|
560 * <li>the first argument is positive zero and the second argument |
|
561 * is less than zero, or |
|
562 * <li>the first argument is positive infinity and the second |
|
563 * argument is greater than zero, |
|
564 * </ul> |
|
565 * then the result is positive infinity. |
|
566 * |
|
567 * <li>If |
|
568 * <ul> |
|
569 * <li>the first argument is negative zero and the second argument |
|
570 * is greater than zero but not a finite odd integer, or |
|
571 * <li>the first argument is negative infinity and the second |
|
572 * argument is less than zero but not a finite odd integer, |
|
573 * </ul> |
|
574 * then the result is positive zero. |
|
575 * |
|
576 * <li>If |
|
577 * <ul> |
|
578 * <li>the first argument is negative zero and the second argument |
|
579 * is a positive finite odd integer, or |
|
580 * <li>the first argument is negative infinity and the second |
|
581 * argument is a negative finite odd integer, |
|
582 * </ul> |
|
583 * then the result is negative zero. |
|
584 * |
|
585 * <li>If |
|
586 * <ul> |
|
587 * <li>the first argument is negative zero and the second argument |
|
588 * is less than zero but not a finite odd integer, or |
|
589 * <li>the first argument is negative infinity and the second |
|
590 * argument is greater than zero but not a finite odd integer, |
|
591 * </ul> |
|
592 * then the result is positive infinity. |
|
593 * |
|
594 * <li>If |
|
595 * <ul> |
|
596 * <li>the first argument is negative zero and the second argument |
|
597 * is a negative finite odd integer, or |
|
598 * <li>the first argument is negative infinity and the second |
|
599 * argument is a positive finite odd integer, |
|
600 * </ul> |
|
601 * then the result is negative infinity. |
|
602 * |
|
603 * <li>If the first argument is finite and less than zero |
|
604 * <ul> |
|
605 * <li> if the second argument is a finite even integer, the |
|
606 * result is equal to the result of raising the absolute value of |
|
607 * the first argument to the power of the second argument |
|
608 * |
|
609 * <li>if the second argument is a finite odd integer, the result |
|
610 * is equal to the negative of the result of raising the absolute |
|
611 * value of the first argument to the power of the second |
|
612 * argument |
|
613 * |
|
614 * <li>if the second argument is finite and not an integer, then |
|
615 * the result is NaN. |
|
616 * </ul> |
|
617 * |
|
618 * <li>If both arguments are integers, then the result is exactly equal |
|
619 * to the mathematical result of raising the first argument to the power |
|
620 * of the second argument if that result can in fact be represented |
|
621 * exactly as a <code>double</code> value.</ul> |
|
622 * |
|
623 * <p>(In the foregoing descriptions, a floating-point value is |
|
624 * considered to be an integer if and only if it is finite and a |
|
625 * fixed point of the method {@link #ceil <tt>ceil</tt>} or, |
|
626 * equivalently, a fixed point of the method {@link #floor |
|
627 * <tt>floor</tt>}. A value is a fixed point of a one-argument |
|
628 * method if and only if the result of applying the method to the |
|
629 * value is equal to the value.) |
|
630 * |
|
631 * <p>The computed result must be within 1 ulp of the exact result. |
|
632 * Results must be semi-monotonic. |
|
633 * |
|
634 * @param a the base. |
|
635 * @param b the exponent. |
|
636 * @return the value <code>a<sup>b</sup></code>. |
|
637 */ |
|
638 public static double pow(double a, double b) { |
|
639 return StrictMath.pow(a, b); // default impl. delegates to StrictMath |
|
640 } |
|
641 |
|
642 /** |
|
643 * Returns the closest <code>int</code> to the argument. The |
|
644 * result is rounded to an integer by adding 1/2, taking the |
|
645 * floor of the result, and casting the result to type <code>int</code>. |
|
646 * In other words, the result is equal to the value of the expression: |
|
647 * <p><pre>(int)Math.floor(a + 0.5f)</pre> |
|
648 * <p> |
|
649 * Special cases: |
|
650 * <ul><li>If the argument is NaN, the result is 0. |
|
651 * <li>If the argument is negative infinity or any value less than or |
|
652 * equal to the value of <code>Integer.MIN_VALUE</code>, the result is |
|
653 * equal to the value of <code>Integer.MIN_VALUE</code>. |
|
654 * <li>If the argument is positive infinity or any value greater than or |
|
655 * equal to the value of <code>Integer.MAX_VALUE</code>, the result is |
|
656 * equal to the value of <code>Integer.MAX_VALUE</code>.</ul> |
|
657 * |
|
658 * @param a a floating-point value to be rounded to an integer. |
|
659 * @return the value of the argument rounded to the nearest |
|
660 * <code>int</code> value. |
|
661 * @see java.lang.Integer#MAX_VALUE |
|
662 * @see java.lang.Integer#MIN_VALUE |
|
663 */ |
|
664 public static int round(float a) { |
|
665 return (int)floor(a + 0.5f); |
|
666 } |
|
667 |
|
668 /** |
|
669 * Returns the closest <code>long</code> to the argument. The result |
|
670 * is rounded to an integer by adding 1/2, taking the floor of the |
|
671 * result, and casting the result to type <code>long</code>. In other |
|
672 * words, the result is equal to the value of the expression: |
|
673 * <p><pre>(long)Math.floor(a + 0.5d)</pre> |
|
674 * <p> |
|
675 * Special cases: |
|
676 * <ul><li>If the argument is NaN, the result is 0. |
|
677 * <li>If the argument is negative infinity or any value less than or |
|
678 * equal to the value of <code>Long.MIN_VALUE</code>, the result is |
|
679 * equal to the value of <code>Long.MIN_VALUE</code>. |
|
680 * <li>If the argument is positive infinity or any value greater than or |
|
681 * equal to the value of <code>Long.MAX_VALUE</code>, the result is |
|
682 * equal to the value of <code>Long.MAX_VALUE</code>.</ul> |
|
683 * |
|
684 * @param a a floating-point value to be rounded to a |
|
685 * <code>long</code>. |
|
686 * @return the value of the argument rounded to the nearest |
|
687 * <code>long</code> value. |
|
688 * @see java.lang.Long#MAX_VALUE |
|
689 * @see java.lang.Long#MIN_VALUE |
|
690 */ |
|
691 public static long round(double a) { |
|
692 return (long)floor(a + 0.5d); |
|
693 } |
|
694 |
|
695 private static Random randomNumberGenerator; |
|
696 |
|
697 private static synchronized void initRNG() { |
|
698 if (randomNumberGenerator == null) |
|
699 randomNumberGenerator = new Random(); |
|
700 } |
|
701 |
|
702 /** |
|
703 * Returns a <code>double</code> value with a positive sign, greater |
|
704 * than or equal to <code>0.0</code> and less than <code>1.0</code>. |
|
705 * Returned values are chosen pseudorandomly with (approximately) |
|
706 * uniform distribution from that range. |
|
707 * |
|
708 * <p>When this method is first called, it creates a single new |
|
709 * pseudorandom-number generator, exactly as if by the expression |
|
710 * <blockquote><pre>new java.util.Random</pre></blockquote> This |
|
711 * new pseudorandom-number generator is used thereafter for all |
|
712 * calls to this method and is used nowhere else. |
|
713 * |
|
714 * <p>This method is properly synchronized to allow correct use by |
|
715 * more than one thread. However, if many threads need to generate |
|
716 * pseudorandom numbers at a great rate, it may reduce contention |
|
717 * for each thread to have its own pseudorandom-number generator. |
|
718 * |
|
719 * @return a pseudorandom <code>double</code> greater than or equal |
|
720 * to <code>0.0</code> and less than <code>1.0</code>. |
|
721 * @see java.util.Random#nextDouble() |
|
722 */ |
|
723 public static double random() { |
|
724 if (randomNumberGenerator == null) initRNG(); |
|
725 return randomNumberGenerator.nextDouble(); |
|
726 } |
|
727 |
|
728 /** |
|
729 * Returns the absolute value of an <code>int</code> value. |
|
730 * If the argument is not negative, the argument is returned. |
|
731 * If the argument is negative, the negation of the argument is returned. |
|
732 * |
|
733 * <p>Note that if the argument is equal to the value of |
|
734 * <code>Integer.MIN_VALUE</code>, the most negative representable |
|
735 * <code>int</code> value, the result is that same value, which is |
|
736 * negative. |
|
737 * |
|
738 * @param a the argument whose absolute value is to be determined |
|
739 * @return the absolute value of the argument. |
|
740 * @see java.lang.Integer#MIN_VALUE |
|
741 */ |
|
742 public static int abs(int a) { |
|
743 return (a < 0) ? -a : a; |
|
744 } |
|
745 |
|
746 /** |
|
747 * Returns the absolute value of a <code>long</code> value. |
|
748 * If the argument is not negative, the argument is returned. |
|
749 * If the argument is negative, the negation of the argument is returned. |
|
750 * |
|
751 * <p>Note that if the argument is equal to the value of |
|
752 * <code>Long.MIN_VALUE</code>, the most negative representable |
|
753 * <code>long</code> value, the result is that same value, which |
|
754 * is negative. |
|
755 * |
|
756 * @param a the argument whose absolute value is to be determined |
|
757 * @return the absolute value of the argument. |
|
758 * @see java.lang.Long#MIN_VALUE |
|
759 */ |
|
760 public static long abs(long a) { |
|
761 return (a < 0) ? -a : a; |
|
762 } |
|
763 |
|
764 /** |
|
765 * Returns the absolute value of a <code>float</code> value. |
|
766 * If the argument is not negative, the argument is returned. |
|
767 * If the argument is negative, the negation of the argument is returned. |
|
768 * Special cases: |
|
769 * <ul><li>If the argument is positive zero or negative zero, the |
|
770 * result is positive zero. |
|
771 * <li>If the argument is infinite, the result is positive infinity. |
|
772 * <li>If the argument is NaN, the result is NaN.</ul> |
|
773 * In other words, the result is the same as the value of the expression: |
|
774 * <p><pre>Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))</pre> |
|
775 * |
|
776 * @param a the argument whose absolute value is to be determined |
|
777 * @return the absolute value of the argument. |
|
778 */ |
|
779 public static float abs(float a) { |
|
780 return (a <= 0.0F) ? 0.0F - a : a; |
|
781 } |
|
782 |
|
783 /** |
|
784 * Returns the absolute value of a <code>double</code> value. |
|
785 * If the argument is not negative, the argument is returned. |
|
786 * If the argument is negative, the negation of the argument is returned. |
|
787 * Special cases: |
|
788 * <ul><li>If the argument is positive zero or negative zero, the result |
|
789 * is positive zero. |
|
790 * <li>If the argument is infinite, the result is positive infinity. |
|
791 * <li>If the argument is NaN, the result is NaN.</ul> |
|
792 * In other words, the result is the same as the value of the expression: |
|
793 * <p><code>Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)</code> |
|
794 * |
|
795 * @param a the argument whose absolute value is to be determined |
|
796 * @return the absolute value of the argument. |
|
797 */ |
|
798 public static double abs(double a) { |
|
799 return (a <= 0.0D) ? 0.0D - a : a; |
|
800 } |
|
801 |
|
802 /** |
|
803 * Returns the greater of two <code>int</code> values. That is, the |
|
804 * result is the argument closer to the value of |
|
805 * <code>Integer.MAX_VALUE</code>. If the arguments have the same value, |
|
806 * the result is that same value. |
|
807 * |
|
808 * @param a an argument. |
|
809 * @param b another argument. |
|
810 * @return the larger of <code>a</code> and <code>b</code>. |
|
811 * @see java.lang.Long#MAX_VALUE |
|
812 */ |
|
813 public static int max(int a, int b) { |
|
814 return (a >= b) ? a : b; |
|
815 } |
|
816 |
|
817 /** |
|
818 * Returns the greater of two <code>long</code> values. That is, the |
|
819 * result is the argument closer to the value of |
|
820 * <code>Long.MAX_VALUE</code>. If the arguments have the same value, |
|
821 * the result is that same value. |
|
822 * |
|
823 * @param a an argument. |
|
824 * @param b another argument. |
|
825 * @return the larger of <code>a</code> and <code>b</code>. |
|
826 * @see java.lang.Long#MAX_VALUE |
|
827 */ |
|
828 public static long max(long a, long b) { |
|
829 return (a >= b) ? a : b; |
|
830 } |
|
831 |
|
832 private static long negativeZeroFloatBits = Float.floatToIntBits(-0.0f); |
|
833 private static long negativeZeroDoubleBits = Double.doubleToLongBits(-0.0d); |
|
834 |
|
835 /** |
|
836 * Returns the greater of two <code>float</code> values. That is, |
|
837 * the result is the argument closer to positive infinity. If the |
|
838 * arguments have the same value, the result is that same |
|
839 * value. If either value is NaN, then the result is NaN. Unlike |
|
840 * the numerical comparison operators, this method considers |
|
841 * negative zero to be strictly smaller than positive zero. If one |
|
842 * argument is positive zero and the other negative zero, the |
|
843 * result is positive zero. |
|
844 * |
|
845 * @param a an argument. |
|
846 * @param b another argument. |
|
847 * @return the larger of <code>a</code> and <code>b</code>. |
|
848 */ |
|
849 public static float max(float a, float b) { |
|
850 if (a !!= a) return a; // a is NaN |
|
851 if ((a == 0.0f) && (b == 0.0f) |
|
852 && (Float.floatToIntBits(a) == negativeZeroFloatBits)) { |
|
853 return b; |
|
854 } |
|
855 return (a >= b) ? a : b; |
|
856 } |
|
857 |
|
858 /** |
|
859 * Returns the greater of two <code>double</code> values. That |
|
860 * is, the result is the argument closer to positive infinity. If |
|
861 * the arguments have the same value, the result is that same |
|
862 * value. If either value is NaN, then the result is NaN. Unlike |
|
863 * the numerical comparison operators, this method considers |
|
864 * negative zero to be strictly smaller than positive zero. If one |
|
865 * argument is positive zero and the other negative zero, the |
|
866 * result is positive zero. |
|
867 * |
|
868 * @param a an argument. |
|
869 * @param b another argument. |
|
870 * @return the larger of <code>a</code> and <code>b</code>. |
|
871 */ |
|
872 public static double max(double a, double b) { |
|
873 if (a !!= a) return a; // a is NaN |
|
874 if ((a == 0.0d) && (b == 0.0d) |
|
875 && (Double.doubleToLongBits(a) == negativeZeroDoubleBits)) { |
|
876 return b; |
|
877 } |
|
878 return (a >= b) ? a : b; |
|
879 } |
|
880 |
|
881 /** |
|
882 * Returns the smaller of two <code>int</code> values. That is, |
|
883 * the result the argument closer to the value of |
|
884 * <code>Integer.MIN_VALUE</code>. If the arguments have the same |
|
885 * value, the result is that same value. |
|
886 * |
|
887 * @param a an argument. |
|
888 * @param b another argument. |
|
889 * @return the smaller of <code>a</code> and <code>b</code>. |
|
890 * @see java.lang.Long#MIN_VALUE |
|
891 */ |
|
892 public static int min(int a, int b) { |
|
893 return (a <= b) ? a : b; |
|
894 } |
|
895 |
|
896 /** |
|
897 * Returns the smaller of two <code>long</code> values. That is, |
|
898 * the result is the argument closer to the value of |
|
899 * <code>Long.MIN_VALUE</code>. If the arguments have the same |
|
900 * value, the result is that same value. |
|
901 * |
|
902 * @param a an argument. |
|
903 * @param b another argument. |
|
904 * @return the smaller of <code>a</code> and <code>b</code>. |
|
905 * @see java.lang.Long#MIN_VALUE |
|
906 */ |
|
907 public static long min(long a, long b) { |
|
908 return (a <= b) ? a : b; |
|
909 } |
|
910 |
|
911 /** |
|
912 * Returns the smaller of two <code>float</code> values. That is, |
|
913 * the result is the value closer to negative infinity. If the |
|
914 * arguments have the same value, the result is that same |
|
915 * value. If either value is NaN, then the result is NaN. Unlike |
|
916 * the numerical comparison operators, this method considers |
|
917 * negative zero to be strictly smaller than positive zero. If |
|
918 * one argument is positive zero and the other is negative zero, |
|
919 * the result is negative zero. |
|
920 * |
|
921 * @param a an argument. |
|
922 * @param b another argument. |
|
923 * @return the smaller of <code>a</code> and <code>b.</code> |
|
924 */ |
|
925 public static float min(float a, float b) { |
|
926 if (a !!= a) return a; // a is NaN |
|
927 if ((a == 0.0f) && (b == 0.0f) |
|
928 && (Float.floatToIntBits(b) == negativeZeroFloatBits)) { |
|
929 return b; |
|
930 } |
|
931 return (a <= b) ? a : b; |
|
932 } |
|
933 |
|
934 /** |
|
935 * Returns the smaller of two <code>double</code> values. That |
|
936 * is, the result is the value closer to negative infinity. If the |
|
937 * arguments have the same value, the result is that same |
|
938 * value. If either value is NaN, then the result is NaN. Unlike |
|
939 * the numerical comparison operators, this method considers |
|
940 * negative zero to be strictly smaller than positive zero. If one |
|
941 * argument is positive zero and the other is negative zero, the |
|
942 * result is negative zero. |
|
943 * |
|
944 * @param a an argument. |
|
945 * @param b another argument. |
|
946 * @return the smaller of <code>a</code> and <code>b</code>. |
|
947 */ |
|
948 public static double min(double a, double b) { |
|
949 if (a !!= a) return a; // a is NaN |
|
950 if ((a == 0.0d) && (b == 0.0d) |
|
951 && (Double.doubleToLongBits(b) == negativeZeroDoubleBits)) { |
|
952 return b; |
|
953 } |
|
954 return (a <= b) ? a : b; |
|
955 } |
|
956 |
|
957 /** |
|
958 * Returns the size of an ulp of the argument. An ulp of a |
|
959 * <code>double</code> value is the positive distance between this |
|
960 * floating-point value and the <code>double</code> value next |
|
961 * larger in magnitude. Note that for non-NaN <i>x</i>, |
|
962 * <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>. |
|
963 * |
|
964 * <p>Special Cases: |
|
965 * <ul> |
|
966 * <li> If the argument is NaN, then the result is NaN. |
|
967 * <li> If the argument is positive or negative infinity, then the |
|
968 * result is positive infinity. |
|
969 * <li> If the argument is positive or negative zero, then the result is |
|
970 * <code>Double.MIN_VALUE</code>. |
|
971 * <li> If the argument is ±<code>Double.MAX_VALUE</code>, then |
|
972 * the result is equal to 2<sup>971</sup>. |
|
973 * </ul> |
|
974 * |
|
975 * @param d the floating-point value whose ulp is to be returned |
|
976 * @return the size of an ulp of the argument |
|
977 * @author Joseph D. Darcy |
|
978 * @since 1.5 |
|
979 */ |
|
980 public static double ulp(double d) { |
|
981 return sun.misc.FpUtils.ulp(d); |
|
982 } |
|
983 |
|
984 /** |
|
985 * Returns the size of an ulp of the argument. An ulp of a |
|
986 * <code>float</code> value is the positive distance between this |
|
987 * floating-point value and the <code>float</code> value next |
|
988 * larger in magnitude. Note that for non-NaN <i>x</i>, |
|
989 * <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>. |
|
990 * |
|
991 * <p>Special Cases: |
|
992 * <ul> |
|
993 * <li> If the argument is NaN, then the result is NaN. |
|
994 * <li> If the argument is positive or negative infinity, then the |
|
995 * result is positive infinity. |
|
996 * <li> If the argument is positive or negative zero, then the result is |
|
997 * <code>Float.MIN_VALUE</code>. |
|
998 * <li> If the argument is ±<code>Float.MAX_VALUE</code>, then |
|
999 * the result is equal to 2<sup>104</sup>. |
|
1000 * </ul> |
|
1001 * |
|
1002 * @param f the floating-point value whose ulp is to be returned |
|
1003 * @return the size of an ulp of the argument |
|
1004 * @author Joseph D. Darcy |
|
1005 * @since 1.5 |
|
1006 */ |
|
1007 public static float ulp(float f) { |
|
1008 return sun.misc.FpUtils.ulp(f); |
|
1009 } |
|
1010 |
|
1011 /** |
|
1012 * Returns the signum function of the argument; zero if the argument |
|
1013 * is zero, 1.0 if the argument is greater than zero, -1.0 if the |
|
1014 * argument is less than zero. |
|
1015 * |
|
1016 * <p>Special Cases: |
|
1017 * <ul> |
|
1018 * <li> If the argument is NaN, then the result is NaN. |
|
1019 * <li> If the argument is positive zero or negative zero, then the |
|
1020 * result is the same as the argument. |
|
1021 * </ul> |
|
1022 * |
|
1023 * @param d the floating-point value whose signum is to be returned |
|
1024 * @return the signum function of the argument |
|
1025 * @author Joseph D. Darcy |
|
1026 * @since 1.5 |
|
1027 */ |
|
1028 public static double signum(double d) { |
|
1029 return sun.misc.FpUtils.signum(d); |
|
1030 } |
|
1031 |
|
1032 /** |
|
1033 * Returns the signum function of the argument; zero if the argument |
|
1034 * is zero, 1.0f if the argument is greater than zero, -1.0f if the |
|
1035 * argument is less than zero. |
|
1036 * |
|
1037 * <p>Special Cases: |
|
1038 * <ul> |
|
1039 * <li> If the argument is NaN, then the result is NaN. |
|
1040 * <li> If the argument is positive zero or negative zero, then the |
|
1041 * result is the same as the argument. |
|
1042 * </ul> |
|
1043 * |
|
1044 * @param f the floating-point value whose signum is to be returned |
|
1045 * @return the signum function of the argument |
|
1046 * @author Joseph D. Darcy |
|
1047 * @since 1.5 |
|
1048 */ |
|
1049 public static float signum(float f) { |
|
1050 return sun.misc.FpUtils.signum(f); |
|
1051 } |
|
1052 |
|
1053 /** |
|
1054 * Returns the hyperbolic sine of a <code>double</code> value. |
|
1055 * The hyperbolic sine of <i>x</i> is defined to be |
|
1056 * (<i>e<sup>x</sup> - e<sup>-x</sup></i>)/2 |
|
1057 * where <i>e</i> is {@linkplain Math#E Euler''s number}. |
|
1058 * |
|
1059 * <p>Special cases: |
|
1060 * <ul> |
|
1061 * |
|
1062 * <li>If the argument is NaN, then the result is NaN. |
|
1063 * |
|
1064 * <li>If the argument is infinite, then the result is an infinity |
|
1065 * with the same sign as the argument. |
|
1066 * |
|
1067 * <li>If the argument is zero, then the result is a zero with the |
|
1068 * same sign as the argument. |
|
1069 * |
|
1070 * </ul> |
|
1071 * |
|
1072 * <p>The computed result must be within 2.5 ulps of the exact result. |
|
1073 * |
|
1074 * @param x The number whose hyperbolic sine is to be returned. |
|
1075 * @return The hyperbolic sine of <code>x</code>. |
|
1076 * @since 1.5 |
|
1077 */ |
|
1078 public static double sinh(double x) { |
|
1079 return StrictMath.sinh(x); |
|
1080 } |
|
1081 |
|
1082 /** |
|
1083 * Returns the hyperbolic cosine of a <code>double</code> value. |
|
1084 * The hyperbolic cosine of <i>x</i> is defined to be |
|
1085 * (<i>e<sup>x</sup> + e<sup>-x</sup></i>)/2 |
|
1086 * where <i>e</i> is {@linkplain Math#E Euler''s number}. |
|
1087 * |
|
1088 * <p>Special cases: |
|
1089 * <ul> |
|
1090 * |
|
1091 * <li>If the argument is NaN, then the result is NaN. |
|
1092 * |
|
1093 * <li>If the argument is infinite, then the result is positive |
|
1094 * infinity. |
|
1095 * |
|
1096 * <li>If the argument is zero, then the result is <code>1.0</code>. |
|
1097 * |
|
1098 * </ul> |
|
1099 * |
|
1100 * <p>The computed result must be within 2.5 ulps of the exact result. |
|
1101 * |
|
1102 * @param x The number whose hyperbolic cosine is to be returned. |
|
1103 * @return The hyperbolic cosine of <code>x</code>. |
|
1104 * @since 1.5 |
|
1105 */ |
|
1106 public static double cosh(double x) { |
|
1107 return StrictMath.cosh(x); |
|
1108 } |
|
1109 |
|
1110 /** |
|
1111 * Returns the hyperbolic tangent of a <code>double</code> value. |
|
1112 * The hyperbolic tangent of <i>x</i> is defined to be |
|
1113 * (<i>e<sup>x</sup> - e<sup>-x</sup></i>)/(<i>e<sup>x</sup> + e<sup>-x</sup></i>), |
|
1114 * in other words, {@linkplain Math#sinh |
|
1115 * sinh(<i>x</i>)}/{@linkplain Math#cosh cosh(<i>x</i>)}. Note |
|
1116 * that the absolute value of the exact tanh is always less than |
|
1117 * 1. |
|
1118 * |
|
1119 * <p>Special cases: |
|
1120 * <ul> |
|
1121 * |
|
1122 * <li>If the argument is NaN, then the result is NaN. |
|
1123 * |
|
1124 * <li>If the argument is zero, then the result is a zero with the |
|
1125 * same sign as the argument. |
|
1126 * |
|
1127 * <li>If the argument is positive infinity, then the result is |
|
1128 * <code>+1.0</code>. |
|
1129 * |
|
1130 * <li>If the argument is negative infinity, then the result is |
|
1131 * <code>-1.0</code>. |
|
1132 * |
|
1133 * </ul> |
|
1134 * |
|
1135 * <p>The computed result must be within 2.5 ulps of the exact result. |
|
1136 * The result of <code>tanh</code> for any finite input must have |
|
1137 * an absolute value less than or equal to 1. Note that once the |
|
1138 * exact result of tanh is within 1/2 of an ulp of the limit value |
|
1139 * of ±1, correctly signed ±<code>1.0</code> should |
|
1140 * be returned. |
|
1141 * |
|
1142 * @param x The number whose hyperbolic tangent is to be returned. |
|
1143 * @return The hyperbolic tangent of <code>x</code>. |
|
1144 * @since 1.5 |
|
1145 */ |
|
1146 public static double tanh(double x) { |
|
1147 return StrictMath.tanh(x); |
|
1148 } |
|
1149 |
|
1150 /** |
|
1151 * Returns sqrt(<i>x</i><sup>2</sup> +<i>y</i><sup>2</sup>) |
|
1152 * without intermediate overflow or underflow. |
|
1153 * |
|
1154 * <p>Special cases: |
|
1155 * <ul> |
|
1156 * |
|
1157 * <li> If either argument is infinite, then the result |
|
1158 * is positive infinity. |
|
1159 * |
|
1160 * <li> If either argument is NaN and neither argument is infinite, |
|
1161 * then the result is NaN. |
|
1162 * |
|
1163 * </ul> |
|
1164 * |
|
1165 * <p>The computed result must be within 1 ulp of the exact |
|
1166 * result. If one parameter is held constant, the results must be |
|
1167 * semi-monotonic in the other parameter. |
|
1168 * |
|
1169 * @param x a value |
|
1170 * @param y a value |
|
1171 * @return sqrt(<i>x</i><sup>2</sup> +<i>y</i><sup>2</sup>) |
|
1172 * without intermediate overflow or underflow |
|
1173 * @since 1.5 |
|
1174 */ |
|
1175 public static double hypot(double x, double y) { |
|
1176 return StrictMath.hypot(x, y); |
|
1177 } |
|
1178 |
|
1179 /** |
|
1180 * Returns <i>e</i><sup>x</sup> -1. Note that for values of |
|
1181 * <i>x</i> near 0, the exact sum of |
|
1182 * <code>expm1(x)</code> + 1 is much closer to the true |
|
1183 * result of <i>e</i><sup>x</sup> than <code>exp(x)</code>. |
|
1184 * |
|
1185 * <p>Special cases: |
|
1186 * <ul> |
|
1187 * <li>If the argument is NaN, the result is NaN. |
|
1188 * |
|
1189 * <li>If the argument is positive infinity, then the result is |
|
1190 * positive infinity. |
|
1191 * |
|
1192 * <li>If the argument is negative infinity, then the result is |
|
1193 * -1.0. |
|
1194 * |
|
1195 * <li>If the argument is zero, then the result is a zero with the |
|
1196 * same sign as the argument. |
|
1197 * |
|
1198 * </ul> |
|
1199 * |
|
1200 * <p>The computed result must be within 1 ulp of the exact result. |
|
1201 * Results must be semi-monotonic. The result of |
|
1202 * <code>expm1</code> for any finite input must be greater than or |
|
1203 * equal to <code>-1.0</code>. Note that once the exact result of |
|
1204 * <i>e</i><sup><code>x</code></sup> - 1 is within 1/2 |
|
1205 * ulp of the limit value -1, <code>-1.0</code> should be |
|
1206 * returned. |
|
1207 * |
|
1208 * @param x the exponent to raise <i>e</i> to in the computation of |
|
1209 * <i>e</i><sup><code>x</code></sup> -1. |
|
1210 * @return the value <i>e</i><sup><code>x</code></sup> - 1. |
|
1211 */ |
|
1212 public static double expm1(double x) { |
|
1213 return StrictMath.expm1(x); |
|
1214 } |
|
1215 |
|
1216 /** |
|
1217 * Returns the natural logarithm of the sum of the argument and 1. |
|
1218 * Note that for small values <code>x</code>, the result of |
|
1219 * <code>log1p(x)</code> is much closer to the true result of ln(1 |
|
1220 * + <code>x</code>) than the floating-point evaluation of |
|
1221 * <code>log(1.0+x)</code>. |
|
1222 * |
|
1223 * <p>Special cases: |
|
1224 * |
|
1225 * <ul> |
|
1226 * |
|
1227 * <li>If the argument is NaN or less than -1, then the result is |
|
1228 * NaN. |
|
1229 * |
|
1230 * <li>If the argument is positive infinity, then the result is |
|
1231 * positive infinity. |
|
1232 * |
|
1233 * <li>If the argument is negative one, then the result is |
|
1234 * negative infinity. |
|
1235 * |
|
1236 * <li>If the argument is zero, then the result is a zero with the |
|
1237 * same sign as the argument. |
|
1238 * |
|
1239 * </ul> |
|
1240 * |
|
1241 * <p>The computed result must be within 1 ulp of the exact result. |
|
1242 * Results must be semi-monotonic. |
|
1243 * |
|
1244 * @param x a value |
|
1245 * @return the value ln(<code>x</code> + 1), the natural |
|
1246 * log of <code>x</code> + 1 |
|
1247 */ |
|
1248 public static double log1p(double x) { |
|
1249 return StrictMath.log1p(x); |
|
1250 } |
|
1251 } |
|
1252 ' |
|
1253 ! |
|
1254 |
|
1255 javaSourcesBig |
|
1256 ^ self workingJavaInDirectory: '../java-src/java/util' |
|
1257 ! |
|
1258 |
|
1259 petitParserPackage |
|
1260 ^ ' |
|
1261 Object subclass: #PPCharSetPredicate |
|
1262 instanceVariableNames: ''block classification'' |
|
1263 classVariableNames: '''' |
|
1264 poolDictionaries: '''' |
|
1265 category: ''PetitParser-Tools''!! |
|
1266 !!PPCharSetPredicate commentStamp: ''<historical>'' prior: 0!! |
|
1267 !! |
|
1268 |
|
1269 |
|
1270 !!PPCharSetPredicate methodsFor: ''initialization'' stamp: ''lr 8/30/2010 12:19''!! |
|
1271 initializeOn: aBlock |
|
1272 block := aBlock. |
|
1273 classification := Array new: 255. |
|
1274 1 to: classification size do: [ :index | |
|
1275 classification at: index put: (block |
|
1276 value: (Character value: index)) ]!! !! |
|
1277 |
|
1278 |
|
1279 !!PPCharSetPredicate methodsFor: ''evaluating'' stamp: ''lr 8/30/2010 12:19''!! |
|
1280 value: aCharacter |
|
1281 | index | |
|
1282 index := aCharacter asInteger. |
|
1283 index == 0 |
|
1284 ifTrue: [ ^ block value: aCharacter ]. |
|
1285 index > 255 |
|
1286 ifTrue: [ ^ block value: aCharacter ]. |
|
1287 ^ classification at: index!! !! |
|
1288 |
|
1289 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
1290 |
|
1291 PPCharSetPredicate class |
|
1292 instanceVariableNames: ''''!! |
|
1293 !!PPCharSetPredicate class commentStamp: ''<historical>'' prior: 0!! |
|
1294 !! |
|
1295 |
|
1296 |
|
1297 !!PPCharSetPredicate class methodsFor: ''instance creation'' stamp: ''lr 8/25/2010 11:05''!! |
|
1298 on: aBlock |
|
1299 ^ self basicNew initializeOn: aBlock!! !! |
|
1300 |
|
1301 |
|
1302 PPDelegateParser subclass: #PPExpressionParser |
|
1303 instanceVariableNames: ''operators'' |
|
1304 classVariableNames: '''' |
|
1305 poolDictionaries: '''' |
|
1306 category: ''PetitParser-Tools''!! |
|
1307 !!PPExpressionParser commentStamp: ''<historical>'' prior: 0!! |
|
1308 A PPExpressionParser is a parser to conveniently define an expression grammar with prefix, postfix, and left- and right-associative infix operators. |
|
1309 |
|
1310 The following code initializes a parser for arithmetic expressions. First we instantiate an expression parser, a simple parser for expressions in parenthesis and a simple parser for integer numbers. |
|
1311 |
|
1312 expression := PPExpressionParser new. |
|
1313 parens := $( asParser token trim , expression , $) asParser token trim |
|
1314 ==> [ :nodes | nodes second ]. |
|
1315 integer := #digit asParser plus token trim |
|
1316 ==> [ :token | token value asInteger ]. |
|
1317 |
|
1318 Then we define on what term the expression grammar is built on: |
|
1319 |
|
1320 expression term: parens / integer. |
|
1321 |
|
1322 Finally we define the operator-groups in descending precedence. Note, that the action blocks receive both, the terms and the parsed operator in the order they appear in the parsed input. |
|
1323 |
|
1324 expression |
|
1325 group: [ :g | |
|
1326 g prefix: $- asParser token trim do: [ :op :a | a negated ] ]; |
|
1327 group: [ :g | |
|
1328 g postfix: ''++'' asParser token trim do: [ :a :op | a + 1 ]. |
|
1329 g postfix: ''--'' asParser token trim do: [ :a :op | a - 1 ] ]; |
|
1330 group: [ :g | |
|
1331 g right: $^ asParser token trim do: [ :a :op :b | a raisedTo: b ] ]; |
|
1332 group: [ :g | |
|
1333 g left: $* asParser token trim do: [ :a :op :b | a * b ]. |
|
1334 g left: $/ asParser token trim do: [ :a :op :b | a / b ] ]; |
|
1335 group: [ :g | |
|
1336 g left: $+ asParser token trim do: [ :a :op :b | a + b ]. |
|
1337 g left: $- asParser token trim do: [ :a :op :b | a - b ] ]. |
|
1338 |
|
1339 After evaluating the above code the ''expression'' is an efficient parser that evaluates examples like: |
|
1340 |
|
1341 expression parse: ''-8++''. |
|
1342 expression parse: ''1+2*3''. |
|
1343 expression parse: ''1*2+3''. |
|
1344 expression parse: ''(1+2)*3''. |
|
1345 expression parse: ''8/4/2''. |
|
1346 expression parse: ''8/(4/2)''. |
|
1347 expression parse: ''2^2^3''. |
|
1348 expression parse: ''(2^2)^3''. |
|
1349 |
|
1350 Instance Variables: |
|
1351 operators <Dictionary> The operators defined in the current group.!! |
|
1352 |
|
1353 |
|
1354 !!PPExpressionParser methodsFor: ''private'' stamp: ''FirstnameLastname 11/26/2009 20:48''!! |
|
1355 build: aParser right: aChoiceParser |
|
1356 ^ (aParser separatedBy: aChoiceParser) foldRight: [ :a :op :b | op first value: a value: op second value: b ]!! !! |
|
1357 |
|
1358 !!PPExpressionParser methodsFor: ''private'' stamp: ''FirstnameLastname 11/26/2009 20:48''!! |
|
1359 build: aParser left: aChoiceParser |
|
1360 ^ (aParser separatedBy: aChoiceParser) foldLeft: [ :a :op :b | op first value: a value: op second value: b ]!! !! |
|
1361 |
|
1362 !!PPExpressionParser methodsFor: ''private'' stamp: ''lr 12/4/2009 17:38''!! |
|
1363 build: aParser postfix: aChoiceParser |
|
1364 ^ aParser , aChoiceParser star map: [ :term :ops | ops inject: term into: [ :result :operator | operator first value: result value: operator second ] ]!! !! |
|
1365 |
|
1366 !!PPExpressionParser methodsFor: ''private'' stamp: ''FirstnameLastname 11/26/2009 21:15''!! |
|
1367 buildOn: aParser |
|
1368 ^ self buildSelectors inject: aParser into: [ :term :selector | |
|
1369 | list | |
|
1370 list := operators at: selector ifAbsent: [ #() ]. |
|
1371 list isEmpty |
|
1372 ifTrue: [ term ] |
|
1373 ifFalse: [ |
|
1374 self |
|
1375 perform: selector with: term |
|
1376 with: (list size = 1 |
|
1377 ifTrue: [ list first first ==> [ :operator | Array with: list first second with: operator ] ] |
|
1378 ifFalse: [ |
|
1379 list |
|
1380 inject: PPChoiceParser new |
|
1381 into: [ :choice :each | choice / (each first ==> [ :operator | Array with: each second with: operator ]) ] ]) ] ]!! !! |
|
1382 |
|
1383 !!PPExpressionParser methodsFor: ''private'' stamp: ''lr 12/4/2009 17:39''!! |
|
1384 build: aParser prefix: aChoiceParser |
|
1385 ^ aChoiceParser star , aParser map: [ :ops :term | ops reversed inject: term into: [ :result :operator | operator first value: operator second value: result ] ]!! !! |
|
1386 |
|
1387 !!PPExpressionParser methodsFor: ''private'' stamp: ''FirstnameLastname 11/26/2009 20:48''!! |
|
1388 buildSelectors |
|
1389 ^ #(build:prefix: build:postfix: build:right: build:left:)!! !! |
|
1390 |
|
1391 !!PPExpressionParser methodsFor: ''private'' stamp: ''lr 2/7/2010 23:23''!! |
|
1392 operator: aSymbol parser: aParser do: aBlock |
|
1393 parser isNil |
|
1394 ifTrue: [ ^ self error: ''You did not specify a term when creating the receiver.'' ]. |
|
1395 operators isNil |
|
1396 ifTrue: [ ^ self error: ''Use #group: to define precedence groups in descending order.'' ]. |
|
1397 (operators at: aSymbol ifAbsentPut: [ OrderedCollection new ]) |
|
1398 addLast: (Array with: aParser asParser with: aBlock)!! !! |
|
1399 |
|
1400 |
|
1401 !!PPExpressionParser methodsFor: ''specifying'' stamp: ''FirstnameLastname 11/26/2009 21:26''!! |
|
1402 term: aParser |
|
1403 "Defines the initial term aParser of the receiver." |
|
1404 |
|
1405 parser isNil |
|
1406 ifTrue: [ parser := aParser ] |
|
1407 ifFalse: [ self error: ''Unable to redefine the term.'' ]!! !! |
|
1408 |
|
1409 !!PPExpressionParser methodsFor: ''specifying'' stamp: ''FirstnameLastname 11/26/2009 20:49''!! |
|
1410 postfix: aParser do: aTwoArgumentBlock |
|
1411 "Define a postfix operator aParser. Evaluate aTwoArgumentBlock with the term and the operator." |
|
1412 |
|
1413 self operator: #build:postfix: parser: aParser do: aTwoArgumentBlock!! !! |
|
1414 |
|
1415 !!PPExpressionParser methodsFor: ''specifying'' stamp: ''FirstnameLastname 11/26/2009 20:49''!! |
|
1416 left: aParser do: aThreeArgumentBlock |
|
1417 "Define an operator aParser that is left-associative. Evaluate aThreeArgumentBlock with the first term, the operator, and the second term." |
|
1418 |
|
1419 self operator: #build:left: parser: aParser do: aThreeArgumentBlock!! !! |
|
1420 |
|
1421 !!PPExpressionParser methodsFor: ''specifying'' stamp: ''FirstnameLastname 11/26/2009 20:49''!! |
|
1422 prefix: aParser do: aTwoArgumentBlock |
|
1423 "Define a prefix operator aParser. Evaluate aTwoArgumentBlock with the operator and the term." |
|
1424 |
|
1425 self operator: #build:prefix: parser: aParser do: aTwoArgumentBlock!! !! |
|
1426 |
|
1427 !!PPExpressionParser methodsFor: ''specifying'' stamp: ''FirstnameLastname 11/26/2009 20:49''!! |
|
1428 right: aParser do: aThreeArgumentBlock |
|
1429 "Define an operator aParser that is right-associative. Evaluate aThreeArgumentBlock with the first term, the operator, and the second term." |
|
1430 |
|
1431 self operator: #build:right: parser: aParser do: aThreeArgumentBlock!! !! |
|
1432 |
|
1433 !!PPExpressionParser methodsFor: ''specifying'' stamp: ''lr 2/7/2010 23:20''!! |
|
1434 group: aOneArgumentBlock |
|
1435 "Defines a priority group by evaluating aOneArgumentBlock." |
|
1436 |
|
1437 operators := Dictionary new. |
|
1438 parser := [ |
|
1439 aOneArgumentBlock value: self. |
|
1440 self buildOn: parser ] |
|
1441 ensure: [ operators := nil ]!! !! |
|
1442 |
|
1443 |
|
1444 PPDelegateParser subclass: #PPCompositeParser |
|
1445 instanceVariableNames: ''dependencies'' |
|
1446 classVariableNames: '''' |
|
1447 poolDictionaries: '''' |
|
1448 category: ''PetitParser-Tools''!! |
|
1449 !!PPCompositeParser commentStamp: ''lr 12/4/2009 18:38'' prior: 0!! |
|
1450 A PPCompositeParser is composed parser built from various primitive parsers. |
|
1451 |
|
1452 Every production in the receiver is specified as a method that returns its parser. Note that every production requires an instance variable of the same name, otherwise the production is not cached and cannot be used in recursive grammars. Productions should refer to each other by reading the respective inst-var. Note: these inst-vars are typically not written, as the assignment happens in the initialize method using reflection. |
|
1453 |
|
1454 The start production is defined in the method start. It is aliased to the inst-var parser defined in the superclass of PPCompositeParser.!! |
|
1455 |
|
1456 |
|
1457 !!PPCompositeParser methodsFor: ''querying'' stamp: ''lr 6/4/2010 13:37''!! |
|
1458 productionAt: aSymbol ifAbsent: aBlock |
|
1459 "Answer the production named aSymbol, if there is no such production answer the result of evaluating aBlock." |
|
1460 |
|
1461 (self class ignoredNames includes: aSymbol asString) |
|
1462 ifTrue: [ ^ aBlock value ]. |
|
1463 (self class startSymbol = aSymbol) |
|
1464 ifTrue: [ ^ parser ]. |
|
1465 ^ self instVarAt: (self class allInstVarNames |
|
1466 indexOf: aSymbol asString |
|
1467 ifAbsent: [ ^ aBlock value ])!! !! |
|
1468 |
|
1469 !!PPCompositeParser methodsFor: ''querying'' stamp: ''lr 5/8/2011 15:45''!! |
|
1470 productionNames |
|
1471 "Answer a dictionary of slot indexes and production names." |
|
1472 |
|
1473 | productionNames ignoredNames | |
|
1474 productionNames := Dictionary new. |
|
1475 ignoredNames := self class ignoredNames |
|
1476 collect: [ :each | each asSymbol ]. |
|
1477 self class allInstVarNames keysAndValuesDo: [ :key :value | |
|
1478 (ignoredNames includes: value asSymbol) |
|
1479 ifFalse: [ productionNames at: key put: value asSymbol ] ]. |
|
1480 ^ productionNames!! !! |
|
1481 |
|
1482 !!PPCompositeParser methodsFor: ''querying'' stamp: ''lr 3/16/2013 21:41''!! |
|
1483 dependencyAt: aClass |
|
1484 "Answer the dependent parser aClass. Throws an error if this parser class is not declared in the method #dependencies on the class-side of the receiver." |
|
1485 |
|
1486 ^ dependencies at: aClass ifAbsent: [ self error: ''Undeclared dependency in '' , self class name , '' to '' , aClass name ]!! !! |
|
1487 |
|
1488 !!PPCompositeParser methodsFor: ''querying'' stamp: ''lr 12/4/2009 18:39''!! |
|
1489 productionAt: aSymbol |
|
1490 "Answer the production named aSymbol." |
|
1491 |
|
1492 ^ self productionAt: aSymbol ifAbsent: [ nil ]!! !! |
|
1493 |
|
1494 |
|
1495 !!PPCompositeParser methodsFor: ''initialization'' stamp: ''lr 3/16/2013 17:15''!! |
|
1496 initializeStartingAt: aSymbol dependencies: aDictionary |
|
1497 self initialize. |
|
1498 parser := PPDelegateParser named: aSymbol. |
|
1499 self productionNames keysAndValuesDo: [ :key :value | |
|
1500 self instVarAt: key put: (PPDelegateParser named: value) ]. |
|
1501 dependencies := aDictionary!! !! |
|
1502 |
|
1503 |
|
1504 !!PPCompositeParser methodsFor: ''accessing'' stamp: ''lr 5/16/2008 17:32''!! |
|
1505 start |
|
1506 "Answer the production to start this parser with." |
|
1507 |
|
1508 self subclassResponsibility!! !! |
|
1509 |
|
1510 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
1511 |
|
1512 PPCompositeParser class |
|
1513 instanceVariableNames: ''''!! |
|
1514 !!PPCompositeParser class commentStamp: ''<historical>'' prior: 0!! |
|
1515 !! |
|
1516 |
|
1517 |
|
1518 !!PPCompositeParser class methodsFor: ''accessing'' stamp: ''lr 1/29/2010 11:35''!! |
|
1519 ignoredNames |
|
1520 "Answer a collection of instance-variables that should not be automatically initialized with productions, but that are used internal to the composite parser." |
|
1521 |
|
1522 ^ PPCompositeParser allInstVarNames!! !! |
|
1523 |
|
1524 !!PPCompositeParser class methodsFor: ''accessing'' stamp: ''lr 12/7/2009 08:20''!! |
|
1525 startSymbol |
|
1526 "Answer the method that represents the default start symbol." |
|
1527 |
|
1528 ^ #start!! !! |
|
1529 |
|
1530 !!PPCompositeParser class methodsFor: ''accessing'' stamp: ''lr 3/16/2013 21:42''!! |
|
1531 dependencies |
|
1532 "Answer a collection of PPCompositeParser classes that this parser directly dependends on. Override this method in subclasses to declare dependent parsers. The default implementation does not depend on other PPCompositeParser." |
|
1533 |
|
1534 ^ #()!! !! |
|
1535 |
|
1536 |
|
1537 !!PPCompositeParser class methodsFor: ''*petitgui-debug'' stamp: ''JanKurs 12/19/2013 15:40''!! |
|
1538 debug: anObject startingAt: aSymbol onError: aBlock |
|
1539 ^ (self newStartingAt: aSymbol) debug: anObject onError: aBlock!! !! |
|
1540 |
|
1541 !!PPCompositeParser class methodsFor: ''*petitgui-debug'' stamp: ''JanKurs 12/19/2013 15:39''!! |
|
1542 debug: anObject startingAt: aSymbol |
|
1543 ^ (self newStartingAt: aSymbol) debug: anObject!! !! |
|
1544 |
|
1545 !!PPCompositeParser class methodsFor: ''*petitgui-debug'' stamp: ''JanKurs 12/19/2013 15:40''!! |
|
1546 debug: anObject onError: aBlock |
|
1547 ^ self debug: anObject startingAt: self startSymbol onError: aBlock!! !! |
|
1548 |
|
1549 !!PPCompositeParser class methodsFor: ''*petitgui-debug'' stamp: ''JanKurs 12/19/2013 15:39''!! |
|
1550 debug: anObject |
|
1551 ^ self debug: anObject startingAt: self startSymbol!! !! |
|
1552 |
|
1553 |
|
1554 !!PPCompositeParser class methodsFor: ''instance creation'' stamp: ''lr 3/16/2013 21:21''!! |
|
1555 newStartingAt: aSymbol |
|
1556 "Answer a new parser starting at aSymbol. The code makes sure to resolve all dependent parsers correctly." |
|
1557 |
|
1558 | parsers remaining | |
|
1559 parsers := IdentityDictionary new. |
|
1560 remaining := OrderedCollection with: self. |
|
1561 [ remaining isEmpty ] whileFalse: [ |
|
1562 | dependency | |
|
1563 dependency := remaining removeLast. |
|
1564 (parsers includesKey: dependency) ifFalse: [ |
|
1565 parsers at: dependency put: dependency basicNew. |
|
1566 remaining addAll: dependency dependencies ] ]. |
|
1567 parsers keysAndValuesDo: [ :class :parser | |
|
1568 | dependencies | |
|
1569 dependencies := IdentityDictionary new. |
|
1570 class dependencies |
|
1571 do: [ :dependency | dependencies at: dependency put: (parsers at: dependency) ]. |
|
1572 parser |
|
1573 initializeStartingAt: (class == self |
|
1574 ifTrue: [ aSymbol ] |
|
1575 ifFalse: [ class startSymbol ]) |
|
1576 dependencies: dependencies ]. |
|
1577 parsers keysAndValuesDo: [ :class :parser | |
|
1578 parser setParser: (parser perform: parser children first name). |
|
1579 parser productionNames keysAndValuesDo: [ :key :value | |
|
1580 (parser instVarAt: key) setParser: (parser perform: value) ] ]. |
|
1581 ^ parsers at: self!! !! |
|
1582 |
|
1583 !!PPCompositeParser class methodsFor: ''instance creation'' stamp: ''lr 12/7/2009 08:24''!! |
|
1584 new |
|
1585 "Answer a new parser starting at the default start symbol." |
|
1586 |
|
1587 ^ self newStartingAt: self startSymbol!! !! |
|
1588 |
|
1589 |
|
1590 !!PPCompositeParser class methodsFor: ''parsing'' stamp: ''lr 2/7/2010 21:02''!! |
|
1591 parse: anObject onError: aBlock |
|
1592 ^ self parse: anObject startingAt: self startSymbol onError: aBlock!! !! |
|
1593 |
|
1594 !!PPCompositeParser class methodsFor: ''parsing'' stamp: ''lr 2/7/2010 21:02''!! |
|
1595 parse: anObject startingAt: aSymbol onError: aBlock |
|
1596 ^ (self newStartingAt: aSymbol) parse: anObject onError: aBlock!! !! |
|
1597 |
|
1598 !!PPCompositeParser class methodsFor: ''parsing'' stamp: ''lr 2/7/2010 20:57''!! |
|
1599 parse: anObject startingAt: aSymbol |
|
1600 ^ (self newStartingAt: aSymbol) parse: anObject!! !! |
|
1601 |
|
1602 !!PPCompositeParser class methodsFor: ''parsing'' stamp: ''lr 2/7/2010 20:57''!! |
|
1603 parse: anObject |
|
1604 ^ self parse: anObject startingAt: self startSymbol!! !! |
|
1605 |
|
1606 |
|
1607 PPParser subclass: #PPUnresolvedParser |
|
1608 instanceVariableNames: '''' |
|
1609 classVariableNames: '''' |
|
1610 poolDictionaries: '''' |
|
1611 category: ''PetitParser-Tools''!! |
|
1612 !!PPUnresolvedParser commentStamp: ''lr 11/28/2009 18:50'' prior: 0!! |
|
1613 This is a temporary placeholder or forward reference to a parser that has not been defined yet. If everything goes well it will eventually be replaced with the real parser instance.!! |
|
1614 |
|
1615 |
|
1616 !!PPUnresolvedParser methodsFor: ''parsing'' stamp: ''lr 2/7/2010 20:51''!! |
|
1617 parseOn: aStream |
|
1618 self error: self printString , '' need to be resolved before execution.''!! !! |
|
1619 |
|
1620 |
|
1621 !!PPUnresolvedParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/13/2009 14:15''!! |
|
1622 displayColor |
|
1623 ^ Color red!! !! |
|
1624 |
|
1625 |
|
1626 !!PPUnresolvedParser methodsFor: ''testing'' stamp: ''lr 10/27/2008 11:29''!! |
|
1627 isUnresolved |
|
1628 ^ true!! !! |
|
1629 Object subclass: #PPParser |
|
1630 instanceVariableNames: ''properties'' |
|
1631 classVariableNames: '''' |
|
1632 poolDictionaries: '''' |
|
1633 category: ''PetitParser-Parsers''!! |
|
1634 !!PPParser commentStamp: ''<historical>'' prior: 0!! |
|
1635 An abstract parser for all parsers in PetitParser. Subclasses implement #parseOn: to perform the actual recursive-descent parsing. All parsers support a variety of methods to perform an actual parse, see the methods in the #parsing protocol. Parsers are combined with a series of operators that can be found in the #operations protocol. |
|
1636 |
|
1637 Instance Variables: |
|
1638 properties <Dictionary> Stores additional state in the parser object.!! |
|
1639 |
|
1640 |
|
1641 !!PPParser methodsFor: ''*petitjava-operations'' stamp: ''sback 9/2/2010 23:01''!! |
|
1642 javaToken |
|
1643 ^ PPJavaTokenParser on: self!! !! |
|
1644 |
|
1645 |
|
1646 !!PPParser methodsFor: ''*petitgui'' stamp: ''TudorGirba 12/18/2013 06:41''!! |
|
1647 gtInspectorParserInspectorIn: composite |
|
1648 <gtInspectorPresentationOrder: 30> |
|
1649 composite custom: ( |
|
1650 PPVerticalParserInspector new |
|
1651 title: ''Sampler''; |
|
1652 startOn: self)!! !! |
|
1653 |
|
1654 !!PPParser methodsFor: ''*petitgui'' stamp: ''AlexandreBergel 12/18/2013 16:40''!! |
|
1655 gtGraphViewIn: composite |
|
1656 <gtInspectorPresentationOrder: 50> |
|
1657 |
|
1658 composite roassal |
|
1659 title: ''Graph''; |
|
1660 painting: [ :view | |
|
1661 self visualizeStructureInGraphOn: view. |
|
1662 ].!! !! |
|
1663 |
|
1664 !!PPParser methodsFor: ''*petitgui'' stamp: ''TudorGirba 6/24/2013 23:44''!! |
|
1665 gtNamedTreeViewIn: composite |
|
1666 <gtInspectorPresentationOrder: 40> |
|
1667 |
|
1668 composite tree |
|
1669 title: ''Named Tree''; |
|
1670 children: [:n | n namedChildren ]; |
|
1671 format: [:n| n name ifNil: [ n asString ] ]; |
|
1672 shouldExpandToLevel: 3!! !! |
|
1673 |
|
1674 !!PPParser methodsFor: ''*petitgui'' stamp: ''TudorGirba 6/24/2013 23:44''!! |
|
1675 gtTreeViewIn: composite |
|
1676 <gtInspectorPresentationOrder: 40> |
|
1677 |
|
1678 composite tree |
|
1679 title: ''Tree''; |
|
1680 children: [:n | n children ]; |
|
1681 format: [:n| n name ifNil: [ n asString ] ifNotNil: [n name] ]; |
|
1682 shouldExpandToLevel: 6!! !! |
|
1683 |
|
1684 |
|
1685 !!PPParser methodsFor: ''*petitgui-morphic'' stamp: ''lr 1/30/2013 19:35''!! |
|
1686 morphicShapeDefault |
|
1687 ^ self newRowMorph |
|
1688 addMorphBack: (self newColumnMorph |
|
1689 addMorphBack: (self newSpacerMorph); |
|
1690 addMorphBack: (LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1) |
|
1691 makeForwardArrow; |
|
1692 yourself); |
|
1693 addMorphBack: (self newRowMorph |
|
1694 borderWidth: 1; |
|
1695 layoutInset: 3; |
|
1696 color: Color white; |
|
1697 addMorphBack: (StringMorph new |
|
1698 contents: self displayName; |
|
1699 color: self displayColor; |
|
1700 yourself); |
|
1701 yourself); |
|
1702 yourself!! !! |
|
1703 |
|
1704 !!PPParser methodsFor: ''*petitgui-morphic'' stamp: ''lr 11/18/2009 10:56''!! |
|
1705 morphicProduction |
|
1706 ^ self newRowMorph |
|
1707 layoutInset: 4; |
|
1708 addMorphBack: (self newRowMorph |
|
1709 layoutInset: 4; |
|
1710 addMorphBack: (StringMorph new |
|
1711 contents: self displayName; |
|
1712 emphasis: TextEmphasis bold emphasisCode; |
|
1713 yourself); |
|
1714 yourself); |
|
1715 addMorphBack: (self morphicShapeSeen: IdentitySet new depth: 0); |
|
1716 addMorphBack: (self newColumnMorph |
|
1717 addMorphBack: (self newSpacerMorph); |
|
1718 addMorphBack: (LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1) |
|
1719 makeForwardArrow; |
|
1720 yourself); |
|
1721 yourself!! !! |
|
1722 |
|
1723 !!PPParser methodsFor: ''*petitgui-morphic'' stamp: ''lr 11/13/2009 13:24''!! |
|
1724 morphicShapeSeen: aSet depth: anInteger |
|
1725 ^ self morphicShapeDefault!! !! |
|
1726 |
|
1727 !!PPParser methodsFor: ''*petitgui-morphic'' stamp: ''lr 11/13/2009 13:43''!! |
|
1728 morphicShapeSeen: aSet depth: anInteger do: aBlock |
|
1729 " avoid recursion " |
|
1730 (aSet includes: self) |
|
1731 ifTrue: [ ^ self morphicShapeDefault ]. |
|
1732 " display nice name when possible " |
|
1733 (anInteger > 0 and: [ self name notNil ]) |
|
1734 ifTrue: [ ^ self morphicShapeDefault ]. |
|
1735 " don''t do it too deep " |
|
1736 (anInteger > 10) |
|
1737 ifTrue: [ ^ self morphicShapeDefault ]. |
|
1738 aSet add: self. |
|
1739 ^ aBlock value: [ :parser | |
|
1740 parser |
|
1741 morphicShapeSeen: aSet |
|
1742 depth: anInteger + 1 ]!! !! |
|
1743 |
|
1744 |
|
1745 !!PPParser methodsFor: ''*petitanalyzer-transforming'' stamp: ''lr 10/30/2010 11:54''!! |
|
1746 transform: aBlock |
|
1747 "Answer a copy of all parsers reachable from the receiver transformed using aBlock." |
|
1748 |
|
1749 | mapping root | |
|
1750 mapping := IdentityDictionary new. |
|
1751 self allParsersDo: [ :each | |
|
1752 mapping |
|
1753 at: each |
|
1754 put: (aBlock value: each copy) ]. |
|
1755 root := mapping at: self. |
|
1756 [ | changed | |
|
1757 changed := false. |
|
1758 root allParsersDo: [ :each | |
|
1759 each children do: [ :old | |
|
1760 mapping at: old ifPresent: [ :new | |
|
1761 each replace: old with: new. |
|
1762 changed := true ] ] ]. |
|
1763 changed ] whileTrue. |
|
1764 ^ root!! !! |
|
1765 |
|
1766 !!PPParser methodsFor: ''*petitanalyzer-transforming'' stamp: ''lr 4/13/2010 09:38''!! |
|
1767 replace: aParser with: anotherParser |
|
1768 "Replace the references of the receiver pointing to aParser with anotherParser."!! !! |
|
1769 |
|
1770 |
|
1771 !!PPParser methodsFor: ''*petitanalyzer-named'' stamp: ''lr 11/23/2010 10:55''!! |
|
1772 namedChildrenDo: aBlock |
|
1773 "Iterate over the named children of the receiver." |
|
1774 |
|
1775 self namedChildrenDo: aBlock seen: IdentitySet new!! !! |
|
1776 |
|
1777 !!PPParser methodsFor: ''*petitanalyzer-named'' stamp: ''lr 11/23/2010 10:01''!! |
|
1778 allNamedParsers |
|
1779 "Answer all the named parse nodes of the receiver." |
|
1780 |
|
1781 | result | |
|
1782 result := OrderedCollection new. |
|
1783 self allNamedParsersDo: [ :parser | result addLast: parser ]. |
|
1784 ^ result!! !! |
|
1785 |
|
1786 !!PPParser methodsFor: ''*petitanalyzer-named'' stamp: ''lr 11/23/2010 10:55''!! |
|
1787 namedChildrenDo: aBlock seen: aSet |
|
1788 "Iterate over the named children of the receiver." |
|
1789 |
|
1790 self children do: [ :each | |
|
1791 (aSet includes: each) |
|
1792 ifTrue: [ ^ self ]. |
|
1793 aSet add: each. |
|
1794 each name isNil |
|
1795 ifTrue: [ each namedChildrenDo: aBlock seen: aSet ] |
|
1796 ifFalse: [ aBlock value: each ] ]!! !! |
|
1797 |
|
1798 !!PPParser methodsFor: ''*petitanalyzer-named'' stamp: ''lr 12/3/2010 16:45''!! |
|
1799 innerChildren |
|
1800 "Answer the inner children of the receiver." |
|
1801 |
|
1802 | result | |
|
1803 result := OrderedCollection new. |
|
1804 self innerChildrenDo: [ :parser | result addLast: parser ]. |
|
1805 ^ result!! !! |
|
1806 |
|
1807 !!PPParser methodsFor: ''*petitanalyzer-named'' stamp: ''lr 12/3/2010 16:51''!! |
|
1808 innerChildrenDo: aBlock seen: aSet |
|
1809 "Iterate over the inner children of the receiver." |
|
1810 |
|
1811 self children do: [ :each | |
|
1812 (aSet includes: each) |
|
1813 ifTrue: [ ^ self ]. |
|
1814 aSet add: each. |
|
1815 each name isNil ifTrue: [ |
|
1816 aBlock value: each. |
|
1817 each innerChildrenDo: aBlock seen: aSet ] ]!! !! |
|
1818 |
|
1819 !!PPParser methodsFor: ''*petitanalyzer-named'' stamp: ''lr 12/3/2010 16:48''!! |
|
1820 innerChildrenDo: aBlock |
|
1821 "Iterate over the inner children of the receiver." |
|
1822 |
|
1823 self innerChildrenDo: aBlock seen: IdentitySet new!! !! |
|
1824 |
|
1825 !!PPParser methodsFor: ''*petitanalyzer-named'' stamp: ''lr 11/23/2010 10:12''!! |
|
1826 allNamedParsersDo: aBlock |
|
1827 "Iterate over all the named parse nodes of the receiver." |
|
1828 |
|
1829 self allParsersDo: [ :each | |
|
1830 each name notNil |
|
1831 ifTrue: [ aBlock value: each ] ]!! !! |
|
1832 |
|
1833 !!PPParser methodsFor: ''*petitanalyzer-named'' stamp: ''lr 11/23/2010 10:55''!! |
|
1834 namedChildren |
|
1835 "Answer the named children of the receiver." |
|
1836 |
|
1837 | result | |
|
1838 result := OrderedCollection new. |
|
1839 self namedChildrenDo: [ :parser | result addLast: parser ]. |
|
1840 ^ result!! !! |
|
1841 |
|
1842 |
|
1843 !!PPParser methodsFor: ''operators-mapping'' stamp: ''lr 7/11/2011 11:03''!! |
|
1844 trimBlanks |
|
1845 "Answer a new parser that consumes blanks before and after the receiving parser." |
|
1846 |
|
1847 ^ self trim: #blank asParser!! !! |
|
1848 |
|
1849 !!PPParser methodsFor: ''operators-mapping'' stamp: ''lr 2/19/2010 07:42''!! |
|
1850 answer: anObject |
|
1851 "Answer a new parser that always returns anObject from a successful parse." |
|
1852 |
|
1853 ^ self ==> [ :nodes | anObject ]!! !! |
|
1854 |
|
1855 !!PPParser methodsFor: ''operators-mapping'' stamp: ''lr 7/11/2011 11:03''!! |
|
1856 trim: aParser |
|
1857 "Answer a new parser that consumes and ignores aParser repeatedly before and after the receiving parser." |
|
1858 |
|
1859 ^ PPTrimmingParser on: self trimmer: aParser!! !! |
|
1860 |
|
1861 !!PPParser methodsFor: ''operators-mapping'' stamp: ''lr 5/6/2011 20:28''!! |
|
1862 map: aBlock |
|
1863 "Answer a new parser that works on the receiving sequence an passes in each element as a block argument." |
|
1864 |
|
1865 ^ aBlock numArgs = 1 |
|
1866 ifTrue: [ self ==> aBlock ] |
|
1867 ifFalse: [ self error: aBlock numArgs asString , '' arguments expected.'' ] |
|
1868 !! !! |
|
1869 |
|
1870 !!PPParser methodsFor: ''operators-mapping'' stamp: ''lr 6/29/2010 14:25''!! |
|
1871 token |
|
1872 "Answer a new parser that transforms the input to a token." |
|
1873 |
|
1874 ^ PPTokenParser on: self!! !! |
|
1875 |
|
1876 !!PPParser methodsFor: ''operators-mapping'' stamp: ''lr 4/3/2011 14:59''!! |
|
1877 foldRight: aBlock |
|
1878 "Answer a new parser that that folds the result of the receiver from right-to-left into aBlock. The argument aBlock must take two or more arguments." |
|
1879 |
|
1880 | size args | |
|
1881 size := aBlock numArgs. |
|
1882 args := Array new: size. |
|
1883 ^ self ==> [ :nodes | |
|
1884 args at: size put: nodes last. |
|
1885 nodes size - size + 1 to: 1 by: 1 - size do: [ :index | |
|
1886 args |
|
1887 replaceFrom: 1 to: size - 1 with: nodes startingAt: index; |
|
1888 at: size put: (aBlock valueWithArguments: args) ]. |
|
1889 args at: size ]!! !! |
|
1890 |
|
1891 !!PPParser methodsFor: ''operators-mapping'' stamp: ''lr 7/11/2011 11:03''!! |
|
1892 trimSpaces |
|
1893 "Answer a new parser that consumes spaces before and after the receiving parser." |
|
1894 |
|
1895 ^ self trim: #space asParser!! !! |
|
1896 |
|
1897 !!PPParser methodsFor: ''operators-mapping'' stamp: ''lr 5/15/2008 16:08''!! |
|
1898 flatten |
|
1899 "Answer a new parser that flattens the underlying collection." |
|
1900 |
|
1901 ^ PPFlattenParser on: self!! !! |
|
1902 |
|
1903 !!PPParser methodsFor: ''operators-mapping'' stamp: ''lr 7/31/2010 12:06''!! |
|
1904 trim |
|
1905 "Answer a new parser that consumes spaces before and after the receiving parser." |
|
1906 |
|
1907 ^ self trimSpaces!! !! |
|
1908 |
|
1909 !!PPParser methodsFor: ''operators-mapping'' stamp: ''lr 6/12/2010 10:20''!! |
|
1910 >=> aBlock |
|
1911 "Answer a new parser that wraps the receiving parser with a two argument block. The first argument is the parsed stream, the second argument a continuation block on the delegate parser." |
|
1912 |
|
1913 ^ PPWrappingParser on: self block: aBlock!! !! |
|
1914 |
|
1915 !!PPParser methodsFor: ''operators-mapping'' stamp: ''lr 5/12/2010 20:32''!! |
|
1916 ==> aBlock |
|
1917 "Answer a new parser that performs aBlock as action handler on success." |
|
1918 |
|
1919 ^ PPActionParser on: self block: aBlock!! !! |
|
1920 |
|
1921 !!PPParser methodsFor: ''operators-mapping'' stamp: ''lr 4/3/2011 15:00''!! |
|
1922 foldLeft: aBlock |
|
1923 "Answer a new parser that that folds the result of the receiver from left-to-right into aBlock. The argument aBlock must take two or more arguments." |
|
1924 |
|
1925 | size args | |
|
1926 size := aBlock numArgs. |
|
1927 args := Array new: size. |
|
1928 ^ self ==> [ :nodes | |
|
1929 args at: 1 put: nodes first. |
|
1930 2 to: nodes size by: size - 1 do: [ :index | |
|
1931 args |
|
1932 replaceFrom: 2 to: size with: nodes startingAt: index; |
|
1933 at: 1 put: (aBlock valueWithArguments: args) ]. |
|
1934 args first ]!! !! |
|
1935 |
|
1936 !!PPParser methodsFor: ''operators-mapping'' stamp: ''lr 4/6/2010 19:26''!! |
|
1937 token: aTokenClass |
|
1938 "Answer a new parser that transforms the input to a token of class aTokenClass." |
|
1939 |
|
1940 ^ self token tokenClass: aTokenClass!! !! |
|
1941 |
|
1942 |
|
1943 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/3/2011 14:57''!! |
|
1944 max: anInteger lazy: aParser |
|
1945 "Answer a new parser that parses the receiver at most anInteger times until it reaches aParser. This is a lazy non-blind implementation. aParser is not consumed." |
|
1946 |
|
1947 ^ (self starLazy: aParser) setMax: anInteger!! !! |
|
1948 |
|
1949 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/2/2011 10:01''!! |
|
1950 starLazy: aParser |
|
1951 "Answer a new parser that parses the receiver zero or more times until it reaches aParser. This is a lazy non-blind implementation of the star operator. aParser is not consumed." |
|
1952 |
|
1953 ^ PPLazyRepeatingParser on: self limit: aParser!! !! |
|
1954 |
|
1955 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 9/15/2010 09:34''!! |
|
1956 times: anInteger |
|
1957 "Answer a new parser that parses the receiver exactly anInteger times." |
|
1958 |
|
1959 ^ self min: anInteger max: anInteger!! !! |
|
1960 |
|
1961 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/3/2011 14:56''!! |
|
1962 min: aMinInteger max: aMaxInteger greedy: aParser |
|
1963 "Answer a new parser that parses the receiver at least aMinInteger and at most aMaxInteger times until it reaches aParser. This is a greedy non-blind implementation. aParser is not consumed." |
|
1964 |
|
1965 ^ (self starGreedy: aParser) setMin: aMinInteger; setMax: aMaxInteger!! !! |
|
1966 |
|
1967 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/2/2011 10:02''!! |
|
1968 star |
|
1969 "Answer a new parser that parses the receiver zero or more times. This is a greedy and blind implementation that tries to consume as much input as possible and it does not consider what comes afterwards." |
|
1970 |
|
1971 ^ PPPossessiveRepeatingParser on: self!! !! |
|
1972 |
|
1973 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/1/2011 21:02''!! |
|
1974 min: anInteger |
|
1975 "Answer a new parser that parses the receiver at least anInteger times." |
|
1976 |
|
1977 ^ self star setMin: anInteger!! !! |
|
1978 |
|
1979 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/1/2011 21:03''!! |
|
1980 min: aMinInteger max: aMaxInteger |
|
1981 "Answer a new parser that parses the receiver at least aMinInteger and at most aMaxInteger times." |
|
1982 |
|
1983 ^ self star setMin: aMinInteger; setMax: aMaxInteger!! !! |
|
1984 |
|
1985 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/2/2011 10:01''!! |
|
1986 starGreedy: aParser |
|
1987 "Answer a new parser that parses the receiver zero or more times until it reaches aParser. This is a greedy non-blind implementation of the star operator. aParser is not consumed." |
|
1988 |
|
1989 ^ PPGreedyRepeatingParser on: self limit: aParser!! !! |
|
1990 |
|
1991 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/3/2011 14:57''!! |
|
1992 min: aMinInteger max: aMaxInteger lazy: aParser |
|
1993 "Answer a new parser that parses the receiver at least aMinInteger and at most aMaxInteger times until it reaches aParser. This is a greedy non-blind implementation. aParser is not consumed." |
|
1994 |
|
1995 ^ (self starLazy: aParser) setMin: aMinInteger; setMax: aMaxInteger!! !! |
|
1996 |
|
1997 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/3/2011 14:57''!! |
|
1998 min: anInteger lazy: aParser |
|
1999 "Answer a new parser that parses the receiver at least anInteger times until it reaches aParser. This is a lazy non-blind implementation. aParser is not consumed." |
|
2000 |
|
2001 ^ (self starLazy: aParser) setMin: anInteger!! !! |
|
2002 |
|
2003 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/3/2011 14:56''!! |
|
2004 max: anInteger greedy: aParser |
|
2005 "Answer a new parser that parses the receiver at most anInteger times until it reaches aParser. This is a greedy non-blind implementation. aParser is not consumed." |
|
2006 |
|
2007 ^ (self starGreedy: aParser) setMax: anInteger!! !! |
|
2008 |
|
2009 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/1/2011 21:03''!! |
|
2010 plus |
|
2011 "Answer a new parser that parses the receiver one or more times." |
|
2012 |
|
2013 ^ self star setMin: 1!! !! |
|
2014 |
|
2015 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/3/2011 14:56''!! |
|
2016 min: anInteger greedy: aParser |
|
2017 "Answer a new parser that parses the receiver at least anInteger times until it reaches aParser. This is a greedy non-blind implementation. aParser is not consumed." |
|
2018 |
|
2019 ^ (self starGreedy: aParser) setMin: anInteger!! !! |
|
2020 |
|
2021 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/1/2011 21:03''!! |
|
2022 max: anInteger |
|
2023 "Answer a new parser that parses the receiver at most anInteger times." |
|
2024 |
|
2025 ^ self star setMax: anInteger!! !! |
|
2026 |
|
2027 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/1/2011 21:04''!! |
|
2028 plusGreedy: aParser |
|
2029 "Answer a new parser that parses the receiver one or more times until it reaches aParser. This is a greedy non-blind implementation of the star operator. aParser is not consumed." |
|
2030 |
|
2031 ^ (self starGreedy: aParser) setMin: 1!! !! |
|
2032 |
|
2033 !!PPParser methodsFor: ''operators-repeating'' stamp: ''lr 4/1/2011 21:04''!! |
|
2034 plusLazy: aParser |
|
2035 "Answer a new parser that parses the receiver one or more times until it reaches aParser. This is a lazy non-blind implementation of the star operator. aParser is not consumed." |
|
2036 |
|
2037 ^ (self starLazy: aParser) setMin: 1!! !! |
|
2038 |
|
2039 |
|
2040 !!PPParser methodsFor: ''*petitsmalltalk-operations'' stamp: ''lr 6/29/2010 14:27''!! |
|
2041 smalltalkToken |
|
2042 ^ PPSmalltalkTokenParser on: self!! !! |
|
2043 |
|
2044 |
|
2045 !!PPParser methodsFor: ''*petitanalyzer-testing'' stamp: ''lr 5/22/2010 10:45''!! |
|
2046 isTerminal |
|
2047 "Answer true if the receiver is a terminal or leaf parser, that means it does not delegate to any other parser." |
|
2048 |
|
2049 ^ self children isEmpty!! !! |
|
2050 |
|
2051 !!PPParser methodsFor: ''*petitanalyzer-testing'' stamp: ''JanKurs 5/31/2013 11:49''!! |
|
2052 isFirstSetTerminal |
|
2053 "Answer true if the receiver is a terminal or leaf parser, that means it does not delegate to any other parser." |
|
2054 |
|
2055 ^ self children isEmpty!! !! |
|
2056 |
|
2057 !!PPParser methodsFor: ''*petitanalyzer-testing'' stamp: ''lr 11/12/2009 17:25''!! |
|
2058 isNullable |
|
2059 "Answer true if the receiver is a nullable parser, e.g. it can successfully parse nothing." |
|
2060 |
|
2061 ^ false!! !! |
|
2062 |
|
2063 |
|
2064 !!PPParser methodsFor: ''converting'' stamp: ''lr 11/29/2011 20:48''!! |
|
2065 asParser |
|
2066 "Answer the receiving parser." |
|
2067 |
|
2068 ^ self!! !! |
|
2069 |
|
2070 |
|
2071 !!PPParser methodsFor: ''printing'' stamp: ''lr 4/16/2010 16:36''!! |
|
2072 printNameOn: aStream |
|
2073 self name isNil |
|
2074 ifTrue: [ aStream print: self hash ] |
|
2075 ifFalse: [ aStream nextPutAll: self name ]!! !! |
|
2076 |
|
2077 !!PPParser methodsFor: ''printing'' stamp: ''lr 4/16/2010 16:36''!! |
|
2078 printOn: aStream |
|
2079 super printOn: aStream. |
|
2080 aStream nextPut: $(. |
|
2081 self printNameOn: aStream. |
|
2082 aStream nextPut: $)!! !! |
|
2083 |
|
2084 |
|
2085 !!PPParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/9/2009 14:37''!! |
|
2086 example |
|
2087 ^ String streamContents: [ :stream | self exampleOn: stream ] limitedTo: 1024!! !! |
|
2088 |
|
2089 !!PPParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/9/2009 14:20''!! |
|
2090 exampleOn: aStream!! !! |
|
2091 |
|
2092 !!PPParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 9/12/2011 18:34''!! |
|
2093 displayColor |
|
2094 ^ self isTerminal |
|
2095 ifTrue: [ Color r: 0.5 g: 0.0 b: 0.5 ] |
|
2096 ifFalse: [ Color blue ]!! !! |
|
2097 |
|
2098 !!PPParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/6/2009 18:31''!! |
|
2099 displayName |
|
2100 ^ self name isNil |
|
2101 ifFalse: [ self name asString ] |
|
2102 ifTrue: [ self class name asString ]!! !! |
|
2103 |
|
2104 !!PPParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/13/2009 14:11''!! |
|
2105 backgroundForDepth: anInteger |
|
2106 ^ Color gray: 1.0 - (anInteger / 20.0)!! !! |
|
2107 |
|
2108 |
|
2109 !!PPParser methodsFor: ''parsing'' stamp: ''lr 10/29/2010 17:05''!! |
|
2110 parse: anObject onError: aBlock |
|
2111 "Parse anObject with the receiving parser and answer the parse-result or answer the result of evaluating aBlock. Depending on the number of arguments of the block it is simply evaluated, evaluated with the failure object, or evaluated with the error message and position." |
|
2112 |
|
2113 | result | |
|
2114 result := self parse: anObject. |
|
2115 result isPetitFailure |
|
2116 ifFalse: [ ^ result ]. |
|
2117 aBlock numArgs = 0 |
|
2118 ifTrue: [ ^ aBlock value ]. |
|
2119 aBlock numArgs = 1 |
|
2120 ifTrue: [ ^ aBlock value: result ]. |
|
2121 ^ aBlock value: result message value: result position!! !! |
|
2122 |
|
2123 !!PPParser methodsFor: ''parsing'' stamp: ''lr 6/4/2011 18:12''!! |
|
2124 matchesIn: anObject |
|
2125 "Search anObject repeatedly for the matches of the receiver. Answered an OrderedCollection of the matched parse-trees." |
|
2126 |
|
2127 | result | |
|
2128 result := OrderedCollection new. |
|
2129 self |
|
2130 matchesIn: anObject |
|
2131 do: [ :each | result addLast: each ]. |
|
2132 ^ result!! !! |
|
2133 |
|
2134 !!PPParser methodsFor: ''parsing'' stamp: ''lr 8/16/2011 07:26''!! |
|
2135 matchesSkipIn: anObject |
|
2136 "Search anObject repeatedly for the matches of the receiver. Answer an OrderedCollection of the matched parse-trees. Skip over matches." |
|
2137 |
|
2138 | result | |
|
2139 result := OrderedCollection new. |
|
2140 self |
|
2141 matchesSkipIn: anObject |
|
2142 do: [ :each | result addLast: each ]. |
|
2143 ^ result!! !! |
|
2144 |
|
2145 !!PPParser methodsFor: ''parsing'' stamp: ''lr 2/25/2013 23:42''!! |
|
2146 matchingSkipRangesIn: anObject do: aBlock |
|
2147 "Search anObject repeatedly for the matches of the receiver. Skip over matches. Evaluate aBlock with the range of each match (index of first character to: index of last character)." |
|
2148 |
|
2149 self token |
|
2150 matchesSkipIn: anObject |
|
2151 do: [ :token | aBlock value: (token start to: token stop) ]!! !! |
|
2152 |
|
2153 !!PPParser methodsFor: ''parsing'' stamp: ''DamienCassou 10/29/2011 19:18''!! |
|
2154 matchingSkipRangesIn: anObject |
|
2155 "Search anObject repeatedly for the matches of the receiver. Skip over matches. Answer an OrderedCollection of ranges of each match (index of first character to: index of last character)." |
|
2156 |
|
2157 | result | |
|
2158 result := OrderedCollection new. |
|
2159 self |
|
2160 matchingSkipRangesIn: anObject |
|
2161 do: [ :value | result addLast: value ]. |
|
2162 ^ result!! !! |
|
2163 |
|
2164 !!PPParser methodsFor: ''parsing'' stamp: ''lr 6/4/2011 18:12''!! |
|
2165 matchingRangesIn: anObject |
|
2166 "Search anObject repeatedly for the matches of the receiver. Answer an OrderedCollection of ranges of each match (index of first character to: index of last character)." |
|
2167 |
|
2168 | result | |
|
2169 result := OrderedCollection new. |
|
2170 self |
|
2171 matchingRangesIn: anObject |
|
2172 do: [ :value | result addLast: value ]. |
|
2173 ^ result!! !! |
|
2174 |
|
2175 !!PPParser methodsFor: ''parsing'' stamp: ''lr 8/16/2011 07:26''!! |
|
2176 matchesSkipIn: anObject do: aBlock |
|
2177 "Search anObject repeatedly for the matches of the receiver. Evaluate aBlock for each match with the matched parse-tree as the argument. Skip over matches." |
|
2178 |
|
2179 (self ==> aBlock / #any asParser) star parse: anObject!! !! |
|
2180 |
|
2181 !!PPParser methodsFor: ''parsing'' stamp: ''lr 2/25/2013 23:41''!! |
|
2182 matchingRangesIn: anObject do: aBlock |
|
2183 "Search anObject repeatedly for the matches of the receiver. Evaluate aBlock with the range of each match (index of first character to: index of last character)." |
|
2184 |
|
2185 self token |
|
2186 matchesIn: anObject |
|
2187 do: [ :token | aBlock value: (token start to: token stop) ]!! !! |
|
2188 |
|
2189 !!PPParser methodsFor: ''parsing'' stamp: ''lr 2/8/2010 00:30''!! |
|
2190 matches: anObject |
|
2191 "Answer if anObject can be parsed by the receiver." |
|
2192 |
|
2193 ^ (self parse: anObject) isPetitFailure not!! !! |
|
2194 |
|
2195 !!PPParser methodsFor: ''parsing'' stamp: ''lr 3/1/2010 21:51''!! |
|
2196 matchesIn: anObject do: aBlock |
|
2197 "Search anObject repeatedly for the matches of the receiver. Evaluate aBlock for each match with the matched parse-tree as the argument. Make sure to always consume exactly one character with each step, to not miss any match." |
|
2198 |
|
2199 ((self and ==> aBlock , #any asParser) / #any asParser) star parse: anObject!! !! |
|
2200 |
|
2201 |
|
2202 !!PPParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 5/31/2010 18:37''!! |
|
2203 matchList: matchList index: matchIndex against: parserList index: parserIndex inContext: aDictionary seen: aSet |
|
2204 | parser currentIndex currentDictionary currentSeen parsers | |
|
2205 matchList size < matchIndex |
|
2206 ifTrue: [ ^ parserList size < parserIndex ]. |
|
2207 parser := matchList at: matchIndex. |
|
2208 parser class = PPListPattern ifTrue: [ |
|
2209 currentIndex := parserIndex - 1. |
|
2210 [ currentDictionary := aDictionary copy. |
|
2211 currentSeen := aSet copy. |
|
2212 parserList size < currentIndex or: [ |
|
2213 parsers := parserList copyFrom: parserIndex to: currentIndex. |
|
2214 (currentDictionary at: parser ifAbsentPut: [ parsers ]) = parsers and: [ |
|
2215 (self |
|
2216 matchList: matchList |
|
2217 index: matchIndex + 1 |
|
2218 against: parserList |
|
2219 index: currentIndex + 1 |
|
2220 inContext: currentDictionary |
|
2221 seen: currentSeen) |
|
2222 ifTrue: [ |
|
2223 currentDictionary keysAndValuesDo: [ :key :value | aDictionary at: key put: value ]. |
|
2224 ^ true ]. |
|
2225 false ] ] ] whileFalse: [ currentIndex := currentIndex + 1 ]. |
|
2226 ^ false ]. |
|
2227 parserList size < parserIndex |
|
2228 ifTrue: [ ^ false ]. |
|
2229 (parser match: (parserList at: parserIndex) inContext: aDictionary seen: aSet) |
|
2230 ifFalse: [ ^ false ]. |
|
2231 ^ self |
|
2232 matchList: matchList |
|
2233 index: matchIndex + 1 |
|
2234 against: parserList |
|
2235 index: parserIndex + 1 |
|
2236 inContext: aDictionary |
|
2237 seen: aSet!! !! |
|
2238 |
|
2239 !!PPParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 7/17/2011 11:53''!! |
|
2240 copyInContext: aDictionary seen: aSeenDictionary |
|
2241 | copy | |
|
2242 aSeenDictionary |
|
2243 at: self |
|
2244 ifPresent: [ :value | ^ value ]. |
|
2245 copy := aSeenDictionary |
|
2246 at: self |
|
2247 put: self copy. |
|
2248 copy children do: [ :each | |
|
2249 copy |
|
2250 replace: each |
|
2251 with: (each copyInContext: aDictionary seen: aSeenDictionary) ]. |
|
2252 ^ copy!! !! |
|
2253 |
|
2254 !!PPParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 4/30/2010 07:49''!! |
|
2255 copyInContext: aDictionary |
|
2256 ^ self copyInContext: aDictionary seen: IdentityDictionary new!! !! |
|
2257 |
|
2258 !!PPParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 4/29/2010 23:07''!! |
|
2259 matchList: matchList against: parserList inContext: aDictionary seen: aSet |
|
2260 ^ self matchList: matchList index: 1 against: parserList index: 1 inContext: aDictionary seen: aSet!! !! |
|
2261 |
|
2262 !!PPParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 6/18/2010 14:09''!! |
|
2263 match: aParser inContext: aDictionary seen: anIdentitySet |
|
2264 "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." |
|
2265 |
|
2266 (self == aParser or: [ anIdentitySet includes: self ]) |
|
2267 ifTrue: [ ^ true ]. |
|
2268 anIdentitySet add: self. |
|
2269 ^ self class = aParser class and: [ self matchList: self children against: aParser children inContext: aDictionary seen: anIdentitySet ]!! !! |
|
2270 |
|
2271 !!PPParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 4/29/2010 23:14''!! |
|
2272 match: aParser inContext: aDictionary |
|
2273 ^ self match: aParser inContext: aDictionary seen: IdentitySet new!! !! |
|
2274 |
|
2275 |
|
2276 !!PPParser methodsFor: ''testing'' stamp: ''lr 10/27/2008 11:28''!! |
|
2277 isUnresolved |
|
2278 ^ false!! !! |
|
2279 |
|
2280 !!PPParser methodsFor: ''testing'' stamp: ''lr 8/6/2010 16:44''!! |
|
2281 isPetitParser |
|
2282 ^ true!! !! |
|
2283 |
|
2284 |
|
2285 !!PPParser methodsFor: ''accessing-properties'' stamp: ''lr 4/19/2010 10:32''!! |
|
2286 propertyAt: aKey ifAbsentPut: aBlock |
|
2287 "Answer the property associated with aKey or, if aKey isn''t found store the result of evaluating aBlock as new value." |
|
2288 |
|
2289 ^ self propertyAt: aKey ifAbsent: [ self propertyAt: aKey put: aBlock value ]!! !! |
|
2290 |
|
2291 !!PPParser methodsFor: ''accessing-properties'' stamp: ''lr 4/19/2010 10:33''!! |
|
2292 removeProperty: aKey ifAbsent: aBlock |
|
2293 "Remove the property with aKey. Answer the value or, if aKey isn''t found, answer the result of evaluating aBlock." |
|
2294 |
|
2295 | answer | |
|
2296 properties isNil ifTrue: [ ^ aBlock value ]. |
|
2297 answer := properties removeKey: aKey ifAbsent: aBlock. |
|
2298 properties isEmpty ifTrue: [ properties := nil ]. |
|
2299 ^ answer!! !! |
|
2300 |
|
2301 !!PPParser methodsFor: ''accessing-properties'' stamp: ''lr 4/19/2010 10:32''!! |
|
2302 propertyAt: aKey |
|
2303 "Answer the property value associated with aKey." |
|
2304 |
|
2305 ^ self propertyAt: aKey ifAbsent: [ self error: ''Property not found'' ]!! !! |
|
2306 |
|
2307 !!PPParser methodsFor: ''accessing-properties'' stamp: ''lr 4/19/2010 10:32''!! |
|
2308 propertyAt: aKey ifAbsent: aBlock |
|
2309 "Answer the property value associated with aKey or, if aKey isn''t found, answer the result of evaluating aBlock." |
|
2310 |
|
2311 ^ properties isNil |
|
2312 ifTrue: [ aBlock value ] |
|
2313 ifFalse: [ properties at: aKey ifAbsent: aBlock ]!! !! |
|
2314 |
|
2315 !!PPParser methodsFor: ''accessing-properties'' stamp: ''lr 4/19/2010 10:33''!! |
|
2316 propertyAt: aKey put: anObject |
|
2317 "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." |
|
2318 |
|
2319 ^ (properties ifNil: [ properties := Dictionary new: 1 ]) |
|
2320 at: aKey put: anObject!! !! |
|
2321 |
|
2322 !!PPParser methodsFor: ''accessing-properties'' stamp: ''lr 4/19/2010 10:32''!! |
|
2323 hasProperty: aKey |
|
2324 "Test if the property aKey is present." |
|
2325 |
|
2326 ^ properties notNil and: [ properties includesKey: aKey ]!! !! |
|
2327 |
|
2328 !!PPParser methodsFor: ''accessing-properties'' stamp: ''lr 4/19/2010 10:33''!! |
|
2329 removeProperty: aKey |
|
2330 "Remove the property with aKey. Answer the property or raise an error if aKey isn''t found." |
|
2331 |
|
2332 ^ self removeProperty: aKey ifAbsent: [ self error: ''Property not found'' ]!! !! |
|
2333 |
|
2334 |
|
2335 !!PPParser methodsFor: ''*petitgui-mondrian'' stamp: ''AlexandreBergel 12/18/2013 16:41''!! |
|
2336 visualizationGraphType |
|
2337 ^ nil!! !! |
|
2338 |
|
2339 !!PPParser methodsFor: ''*petitgui-mondrian'' stamp: ''AlexandreBergel 12/18/2013 17:26''!! |
|
2340 visualizeStructureInGraphOn: view |
|
2341 view shape rectangle |
|
2342 borderWidth: 1; |
|
2343 if: [ :p | p name isNil ] fillColor: Color lightGray. |
|
2344 |
|
2345 view interaction |
|
2346 item: ''Explore'' action: #explore; |
|
2347 highlightWhenOver: [ :p | |
|
2348 self allParsers select: [ :ch | ch children includes: p ] |
|
2349 ] color: Color orange muchLighter; |
|
2350 highlightWhenOver: [ :p | |children| |
|
2351 children := p namedChildren. |
|
2352 ] color: Color orange muchDarker; |
|
2353 highlightWhenOver: [ :p | Array with: p ] color: Color orange; |
|
2354 popupText: [:p | p class name asString ]. |
|
2355 |
|
2356 view |
|
2357 nodes: self allParsers |
|
2358 forEach: [ :aParser | |labels| |
|
2359 labels := OrderedCollection new. |
|
2360 aParser name notNil ifTrue: [ labels add: aParser name ]. |
|
2361 aParser visualizationGraphType notNil ifTrue: [ labels add: aParser visualizationGraphType ]. |
|
2362 labels isEmpty ifFalse: [ |
|
2363 view shape label. |
|
2364 view interaction forwarder. |
|
2365 view nodes: labels asArray ]. |
|
2366 ]. |
|
2367 |
|
2368 view shape: (ROLine new add: (ROArrow new size: 4) offset: 0.1). |
|
2369 view edgesToAll: #children. |
|
2370 view treeLayout |
|
2371 layered; |
|
2372 on: ROLayoutEnd do: [ :evt | ROFocusView on: (view raw elementFromModel: self) ]. |
|
2373 |
|
2374 view zoomInButton. |
|
2375 view zoomOutButton.!! !! |
|
2376 |
|
2377 !!PPParser methodsFor: ''*petitgui-mondrian'' stamp: ''tg 8/25/2010 00:32''!! |
|
2378 namedParsersDo: aBlock |
|
2379 self namedParsersDo: aBlock seen: IdentitySet new!! !! |
|
2380 |
|
2381 !!PPParser methodsFor: ''*petitgui-mondrian'' stamp: ''VincentBlondeau 2/14/2014 17:06''!! |
|
2382 viewAllNamedParsersWithSelection: aCollectionOfNames previewing: aBlock on: view |
|
2383 view shape label |
|
2384 color: [ :each | |
|
2385 (aCollectionOfNames includes: each name) |
|
2386 ifFalse: [ Color black ] |
|
2387 ifTrue: [ Color red ] ]; |
|
2388 text: [ :each | each displayName ]. |
|
2389 view interaction popupText: aBlock. |
|
2390 view interaction item: ''Explore'' action: #explore. |
|
2391 view nodes: (self allParsers reject: [ :each | each name isEmptyOrNil ]). |
|
2392 view edges: (self allParsers reject: [ :each | each name isEmptyOrNil ]) from: #yourself toAll: #namedParsers. |
|
2393 view horizontalDominanceTreeLayout |
|
2394 verticalGap: 10; |
|
2395 layered!! !! |
|
2396 |
|
2397 !!PPParser methodsFor: ''*petitgui-mondrian'' stamp: ''AlexandreBergel 12/18/2013 17:21''!! |
|
2398 visualizeStructureInGraph |
|
2399 |
|
2400 " |
|
2401 PPSmalltalkParser new visualize |
|
2402 |
|
2403 |
|
2404 " |
|
2405 | view | |
|
2406 |
|
2407 view := ROMondrianViewBuilder new. |
|
2408 self visualizeStructureInGraphOn: view. |
|
2409 view open. |
|
2410 ^ view!! !! |
|
2411 |
|
2412 !!PPParser methodsFor: ''*petitgui-mondrian'' stamp: ''VincentBlondeau 2/14/2014 17:06''!! |
|
2413 viewAllNamedParsersOn: view |
|
2414 view shape |
|
2415 rectangleWithoutBorder; |
|
2416 withText: #displayName. |
|
2417 view nodes: (self allParsers reject: [ :each | each name isEmptyOrNil ]). |
|
2418 view edgesToAll: #namedParsers. |
|
2419 view horizontalDominanceTreeLayout layered!! !! |
|
2420 |
|
2421 !!PPParser methodsFor: ''*petitgui-mondrian'' stamp: ''TudorGirba 12/6/2011 07:43''!! |
|
2422 viewAllNamedParsersWithSelection: aCollectionOfNames on: view |
|
2423 self viewAllNamedParsersWithSelection: aCollectionOfNames previewing: [ :each | each name ] on: view!! !! |
|
2424 |
|
2425 !!PPParser methodsFor: ''*petitgui-mondrian'' stamp: ''TudorGirba 12/14/2011 12:40''!! |
|
2426 namedParsersDo: aBlock seen: aSet |
|
2427 self children do: [ :each | |
|
2428 (aSet includes: each) |
|
2429 ifFalse: [ |
|
2430 aSet add: each. |
|
2431 each name isEmptyOrNil |
|
2432 ifFalse: [ aBlock value: each ] |
|
2433 ifTrue: [ each namedParsersDo: aBlock seen: aSet ] ] ]!! !! |
|
2434 |
|
2435 !!PPParser methodsFor: ''*petitgui-mondrian'' stamp: ''TudorGirba 6/5/2013 23:01''!! |
|
2436 viewAllNamedParsers |
|
2437 | view | |
|
2438 view := ROMondrianViewBuilder new. |
|
2439 self viewAllNamedParsersOn: view. |
|
2440 ^ view open setLabel: ''All named parsers''!! !! |
|
2441 |
|
2442 !!PPParser methodsFor: ''*petitgui-mondrian'' stamp: ''tg 8/25/2010 00:31''!! |
|
2443 namedParsers |
|
2444 | result | |
|
2445 result := OrderedCollection new. |
|
2446 self namedParsersDo: [ :parser | result addLast: parser ]. |
|
2447 ^ result!! !! |
|
2448 |
|
2449 |
|
2450 !!PPParser methodsFor: ''*petitanalyzer-enumerating'' stamp: ''lr 4/13/2010 08:36''!! |
|
2451 allParsers |
|
2452 "Answer all the parse nodes of the receiver." |
|
2453 |
|
2454 | result | |
|
2455 result := OrderedCollection new. |
|
2456 self allParsersDo: [ :parser | result addLast: parser ]. |
|
2457 ^ result!! !! |
|
2458 |
|
2459 !!PPParser methodsFor: ''*petitanalyzer-enumerating'' stamp: ''lr 4/13/2010 08:36''!! |
|
2460 allParsersDo: aBlock |
|
2461 "Iterate over all the parse nodes of the receiver." |
|
2462 |
|
2463 self allParsersDo: aBlock seen: IdentitySet new!! !! |
|
2464 |
|
2465 !!PPParser methodsFor: ''*petitanalyzer-enumerating'' stamp: ''lr 4/13/2010 08:35''!! |
|
2466 allParsersDo: aBlock seen: aSet |
|
2467 "Iterate over all the parse nodes of the receiver, do not visit and follow the ones contained in aSet." |
|
2468 |
|
2469 (aSet includes: self) |
|
2470 ifTrue: [ ^ self ]. |
|
2471 aSet add: self. |
|
2472 aBlock value: self. |
|
2473 self children |
|
2474 do: [ :each | each allParsersDo: aBlock seen: aSet ]!! !! |
|
2475 |
|
2476 |
|
2477 !!PPParser methodsFor: ''operators-convenience'' stamp: ''lr 2/19/2010 07:56''!! |
|
2478 separatedBy: aParser |
|
2479 "Answer a new parser that parses the receiver one or more times, separated by aParser." |
|
2480 |
|
2481 ^ (PPSequenceParser with: self with: (PPSequenceParser with: aParser with: self) star) ==> [ :nodes | |
|
2482 | result | |
|
2483 result := Array new: 2 * nodes second size + 1. |
|
2484 result at: 1 put: nodes first. |
|
2485 nodes second |
|
2486 keysAndValuesDo: [ :index :pair | result replaceFrom: 2 * index to: 2 * index + 1 with: pair startingAt: 1 ]. |
|
2487 result ]!! !! |
|
2488 |
|
2489 !!PPParser methodsFor: ''operators-convenience'' stamp: ''lr 2/19/2010 07:42''!! |
|
2490 delimitedBy: aParser |
|
2491 "Answer a new parser that parses the receiver one or more times, separated and possibly ended by aParser." |
|
2492 |
|
2493 ^ (self separatedBy: aParser) , (aParser optional) ==> [ :node | |
|
2494 node second isNil |
|
2495 ifTrue: [ node first ] |
|
2496 ifFalse: [ node first copyWith: node second ] ]!! !! |
|
2497 |
|
2498 !!PPParser methodsFor: ''operators-convenience'' stamp: ''lr 2/25/2012 16:54''!! |
|
2499 withoutSeparators |
|
2500 "Filters out the separators from a parse result produced by one of the productions #delimitedBy: or #separatedBy:." |
|
2501 |
|
2502 ^ self ==> [ :items | |
|
2503 | result | |
|
2504 result := Array new: items size + 1 // 2. |
|
2505 1 to: result size do: [ :index | result at: index put: (items at: 2 * index - 1) ]. |
|
2506 result ]!! !! |
|
2507 |
|
2508 |
|
2509 !!PPParser methodsFor: ''copying'' stamp: ''lr 4/19/2010 10:33''!! |
|
2510 postCopy |
|
2511 super postCopy. |
|
2512 properties := properties copy!! !! |
|
2513 |
|
2514 |
|
2515 !!PPParser methodsFor: ''initialization'' stamp: ''lr 4/24/2008 10:33''!! |
|
2516 initialize!! !! |
|
2517 |
|
2518 |
|
2519 !!PPParser methodsFor: ''*petitgui-morphic-creational'' stamp: ''lr 11/17/2009 21:58''!! |
|
2520 newColumnMorph |
|
2521 ^ AlignmentMorph newColumn |
|
2522 cellPositioning: #topLeft; |
|
2523 color: Color transparent; |
|
2524 listCentering: #topLeft; |
|
2525 vResizing: #shrinkWrap; |
|
2526 hResizing: #shrinkWrap; |
|
2527 layoutInset: 0; |
|
2528 yourself!! !! |
|
2529 |
|
2530 !!PPParser methodsFor: ''*petitgui-morphic-creational'' stamp: ''lr 11/17/2009 21:57''!! |
|
2531 newRowMorph |
|
2532 ^ AlignmentMorph newRow |
|
2533 cellPositioning: #topLeft; |
|
2534 color: Color transparent; |
|
2535 listCentering: #topLeft; |
|
2536 vResizing: #shrinkWrap; |
|
2537 hResizing: #shrinkWrap; |
|
2538 layoutInset: 0; |
|
2539 yourself!! !! |
|
2540 |
|
2541 !!PPParser methodsFor: ''*petitgui-morphic-creational'' stamp: ''lr 11/17/2009 22:03''!! |
|
2542 newSpacerMorph |
|
2543 ^ Morph new |
|
2544 color: Color transparent; |
|
2545 borderWidth: 0; |
|
2546 extent: 7 @ 7; |
|
2547 yourself!! !! |
|
2548 |
|
2549 |
|
2550 !!PPParser methodsFor: ''*petitanalyzer-querying'' stamp: ''lr 9/16/2010 17:55''!! |
|
2551 followSets |
|
2552 "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." |
|
2553 |
|
2554 | current previous continue firstSets followSets | |
|
2555 current := previous := 0. |
|
2556 firstSets := self firstSets. |
|
2557 followSets := IdentityDictionary new. |
|
2558 self allParsersDo: [ :each | followSets at: each put: IdentitySet new ]. |
|
2559 (followSets at: self) add: PPSentinel instance. |
|
2560 [ followSets keysAndValuesDo: [ :parser :follow | |
|
2561 parser |
|
2562 followSets: followSets |
|
2563 firstSets: firstSets |
|
2564 into: follow ]. |
|
2565 current := followSets |
|
2566 inject: 0 |
|
2567 into: [ :result :each | result + each size ]. |
|
2568 continue := previous < current. |
|
2569 previous := current. |
|
2570 continue ] whileTrue. |
|
2571 ^ followSets!! !! |
|
2572 |
|
2573 !!PPParser methodsFor: ''*petitanalyzer-querying'' stamp: ''lr 10/22/2009 19:59''!! |
|
2574 firstSet |
|
2575 "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." |
|
2576 |
|
2577 ^ self firstSets at: self!! !! |
|
2578 |
|
2579 !!PPParser methodsFor: ''*petitanalyzer-querying'' stamp: ''lr 11/19/2009 23:49''!! |
|
2580 cycleSet |
|
2581 "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." |
|
2582 |
|
2583 | cycles | |
|
2584 cycles := IdentitySet new. |
|
2585 self cycleSet: OrderedCollection new firstSets: self firstSets into: cycles. |
|
2586 ^ cycles!! !! |
|
2587 |
|
2588 !!PPParser methodsFor: ''*petitanalyzer-querying'' stamp: ''JanKurs 5/31/2013 11:49''!! |
|
2589 firstSets |
|
2590 "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." |
|
2591 |
|
2592 | firstSets | |
|
2593 firstSets := IdentityDictionary new. |
|
2594 self allParsersDo: [ :each | |
|
2595 firstSets at: each put: (each isFirstSetTerminal |
|
2596 ifTrue: [ IdentitySet with: each ] |
|
2597 ifFalse: [ IdentitySet new ]). |
|
2598 each isNullable |
|
2599 ifTrue: [ (firstSets at: each) add: PPSentinel instance ] ]. |
|
2600 [ | changed tally | |
|
2601 changed := false. |
|
2602 firstSets keysAndValuesDo: [ :parser :first | |
|
2603 tally := first size. |
|
2604 parser firstSets: firstSets into: first. |
|
2605 changed := changed or: [ tally ~= first size ] ]. |
|
2606 changed ] whileTrue. |
|
2607 ^ firstSets!! !! |
|
2608 |
|
2609 !!PPParser methodsFor: ''*petitanalyzer-querying'' stamp: ''lr 11/12/2009 21:13''!! |
|
2610 followSet |
|
2611 "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." |
|
2612 |
|
2613 ^ self followSets at: self!! !! |
|
2614 |
|
2615 |
|
2616 !!PPParser methodsFor: ''pp-context'' stamp: ''JanKurs 11/11/2013 09:30''!! |
|
2617 parseOn: aPPContext |
|
2618 "Parse aStream with the receiving parser and answer the parse-result or an instance of PPFailure. Override this method in subclasses to specify custom parse behavior. Do not call this method from outside, instead use #parse:." |
|
2619 |
|
2620 self subclassResponsibility!! !! |
|
2621 |
|
2622 !!PPParser methodsFor: ''pp-context'' stamp: ''JanKurs 3/17/2014 13:15''!! |
|
2623 debugWithContext: aPPContext |
|
2624 |
|
2625 ^ self enableDebug parseWithContext: aPPContext !! !! |
|
2626 |
|
2627 !!PPParser methodsFor: ''pp-context'' stamp: ''JanKurs 3/11/2014 13:33''!! |
|
2628 updateContext: aPPContext |
|
2629 "nothing to do"!! !! |
|
2630 |
|
2631 !!PPParser methodsFor: ''pp-context'' stamp: ''JanKurs 8/19/2014 13:26''!! |
|
2632 parse: anObject withContext: aPPContext |
|
2633 "Parse anObject with the receiving parser and answer the parse-result or an instance of PPFailure." |
|
2634 |
|
2635 aPPContext stream: anObject asPetitStream. |
|
2636 ^ self parseWithContext: aPPContext. |
|
2637 !! !! |
|
2638 |
|
2639 !!PPParser methodsFor: ''pp-context'' stamp: ''JanKurs 8/19/2014 13:25''!! |
|
2640 parse: anObject |
|
2641 "Parse anObject with the receiving parser and answer the parse-result or an instance of PPFailure." |
|
2642 |
|
2643 ^ self parse: anObject withContext: PPContext new!! !! |
|
2644 |
|
2645 !!PPParser methodsFor: ''pp-context'' stamp: ''JanKurs 3/19/2014 16:34''!! |
|
2646 parseWithContext: context |
|
2647 context root: self. |
|
2648 self updateContext: context. |
|
2649 ^ self parseOn: context!! !! |
|
2650 |
|
2651 |
|
2652 !!PPParser methodsFor: ''accessing'' stamp: ''lr 10/21/2009 16:38''!! |
|
2653 children |
|
2654 "Answer a set of child parsers that could follow the receiver." |
|
2655 |
|
2656 ^ #()!! !! |
|
2657 |
|
2658 !!PPParser methodsFor: ''accessing'' stamp: ''lr 4/19/2010 10:38''!! |
|
2659 name: aString |
|
2660 self propertyAt: #name put: aString!! !! |
|
2661 |
|
2662 !!PPParser methodsFor: ''accessing'' stamp: ''lr 4/19/2010 10:35''!! |
|
2663 name |
|
2664 "Answer the production name of the receiver." |
|
2665 |
|
2666 ^ self propertyAt: #name ifAbsent: [ nil ]!! !! |
|
2667 |
|
2668 |
|
2669 !!PPParser methodsFor: ''*petitanalyzer-private'' stamp: ''lr 11/19/2009 23:47''!! |
|
2670 cycleSet: aDictionary |
|
2671 "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." |
|
2672 |
|
2673 ^ self children!! !! |
|
2674 |
|
2675 !!PPParser methodsFor: ''*petitanalyzer-private'' stamp: ''lr 5/22/2010 10:45''!! |
|
2676 cycleSet: aStack firstSets: aDictionary into: aSet |
|
2677 "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." |
|
2678 |
|
2679 | index | |
|
2680 self isTerminal |
|
2681 ifTrue: [ ^ self ]. |
|
2682 (index := aStack indexOf: self) > 0 |
|
2683 ifTrue: [ ^ aSet addAll: (aStack copyFrom: index to: aStack size) ]. |
|
2684 aStack addLast: self. |
|
2685 (self cycleSet: aDictionary) |
|
2686 do: [ :each | each cycleSet: aStack firstSets: aDictionary into: aSet ]. |
|
2687 aStack removeLast!! !! |
|
2688 |
|
2689 !!PPParser methodsFor: ''*petitanalyzer-private'' stamp: ''lr 11/12/2009 21:25''!! |
|
2690 firstSets: aFirstDictionary into: aSet |
|
2691 "PRIVATE: Try to add additional elements to the first-set aSet of the receiver, use the incomplete aFirstDictionary." |
|
2692 |
|
2693 self children do: [ :parser | aSet addAll: (aFirstDictionary at: parser) ]!! !! |
|
2694 |
|
2695 !!PPParser methodsFor: ''*petitanalyzer-private'' stamp: ''lr 11/12/2009 21:25''!! |
|
2696 followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet |
|
2697 "PRIVATE: Try to add additional elements to the follow-set aSet of the receiver, use the incomplete aFollowDictionary and the complete aFirstDictionary." |
|
2698 |
|
2699 self children do: [ :parser | (aFollowDictionary at: parser) addAll: aSet ]!! !! |
|
2700 |
|
2701 |
|
2702 !!PPParser methodsFor: ''*petitgui-debug'' stamp: ''JanKurs 1/16/2014 15:41''!! |
|
2703 debug: anObject |
|
2704 "Parse anObject with the receiving parser and answer the parse-result or an instance of PPFailure." |
|
2705 |
|
2706 ^ self enableDebug parse: anObject asPetitStream!! !! |
|
2707 |
|
2708 !!PPParser methodsFor: ''*petitgui-debug'' stamp: ''JanKurs 3/18/2014 12:21''!! |
|
2709 enableDebuggerOutput |
|
2710 self debuggerOutput: true.!! !! |
|
2711 |
|
2712 !!PPParser methodsFor: ''*petitgui-debug'' stamp: ''JanKurs 4/22/2013 18:04''!! |
|
2713 debuggerOutput: aBoolean |
|
2714 self propertyAt: #debuggerOutput put: aBoolean!! !! |
|
2715 |
|
2716 !!PPParser methodsFor: ''*petitgui-debug'' stamp: ''JanKurs 3/18/2014 12:21''!! |
|
2717 disableDebuggerOutput |
|
2718 self debuggerOutput: false. !! !! |
|
2719 |
|
2720 !!PPParser methodsFor: ''*petitgui-debug'' stamp: ''JanKurs 3/18/2014 17:01''!! |
|
2721 enableDebug |
|
2722 | root newParser | |
|
2723 root := PPParserDebuggerResult new. |
|
2724 |
|
2725 newParser := self transform: [:each | |
|
2726 each >=> [:stream :continuation | |
|
2727 | result child | |
|
2728 child := PPParserDebuggerResult new |
|
2729 parser: each; |
|
2730 parent: root. |
|
2731 root := root children add: child. |
|
2732 child start: stream position + 1. |
|
2733 child showChildren: each debuggerOutput. |
|
2734 result := continuation value. |
|
2735 child end: stream position. |
|
2736 root result: result. |
|
2737 root := root parent. |
|
2738 result |
|
2739 ] |
|
2740 ]. |
|
2741 |
|
2742 ^ PPDebugParser on: newParser root: root. |
|
2743 !! !! |
|
2744 |
|
2745 !!PPParser methodsFor: ''*petitgui-debug'' stamp: ''JanKurs 4/22/2013 18:04''!! |
|
2746 debuggerOutput |
|
2747 ^ self propertyAt: #debuggerOutput ifAbsentPut: true.!! !! |
|
2748 |
|
2749 |
|
2750 !!PPParser methodsFor: ''operators'' stamp: ''lr 2/19/2010 07:36''!! |
|
2751 negate |
|
2752 "Answer a new parser consumes any input token but the receiver." |
|
2753 |
|
2754 ^ self not , #any asParser ==> #second!! !! |
|
2755 |
|
2756 !!PPParser methodsFor: ''operators'' stamp: ''lr 9/1/2010 22:03''!! |
|
2757 optional |
|
2758 "Answer a new parser that parses the receiver, if possible." |
|
2759 |
|
2760 ^ PPOptionalParser on: self!! !! |
|
2761 |
|
2762 !!PPParser methodsFor: ''operators'' stamp: ''lr 12/3/2010 11:34''!! |
|
2763 def: aParser |
|
2764 "Redefine the receiver as the argument aParser. This method is useful when defining recursive parsers: instantiate a PPUnresolvedParser and later redefine it with another one." |
|
2765 |
|
2766 ^ self becomeForward: (aParser name: self name)!! !! |
|
2767 |
|
2768 !!PPParser methodsFor: ''operators'' stamp: ''lr 10/23/2008 14:05''!! |
|
2769 wrapped |
|
2770 "Answer a new parser that is simply wrapped." |
|
2771 |
|
2772 ^ PPDelegateParser on: self!! !! |
|
2773 |
|
2774 !!PPParser methodsFor: ''operators'' stamp: ''lr 5/31/2010 16:34''!! |
|
2775 memoized |
|
2776 "Answer a new memoized parser, for refraining redundant computations. This ensures polynomial time O(n^4) for left-recursive grammars and O(n^3) for non left-recursive grammars in the worst case. Not necessary for most grammars that are carefully written and in O(n) anyway." |
|
2777 |
|
2778 ^ PPMemoizedParser on: self!! !! |
|
2779 |
|
2780 !!PPParser methodsFor: ''operators'' stamp: ''lr 5/31/2010 15:12''!! |
|
2781 and |
|
2782 "Answer a new parser (logical and-predicate) that succeeds whenever the receiver does, but never consumes input." |
|
2783 |
|
2784 ^ PPAndParser on: self!! !! |
|
2785 |
|
2786 !!PPParser methodsFor: ''operators'' stamp: ''lr 4/14/2010 11:46''!! |
|
2787 / aParser |
|
2788 "Answer a new parser that parses the receiver, if the receiver fails try with aParser (ordered-choice)." |
|
2789 |
|
2790 ^ PPChoiceParser with: self with: aParser!! !! |
|
2791 |
|
2792 !!PPParser methodsFor: ''operators'' stamp: ''lr 4/30/2010 12:13''!! |
|
2793 end |
|
2794 "Answer a new parser that succeeds at the end of the input and return the result of the receiver." |
|
2795 |
|
2796 ^ PPEndOfInputParser on: self!! !! |
|
2797 |
|
2798 !!PPParser methodsFor: ''operators'' stamp: ''lr 5/31/2010 15:12''!! |
|
2799 not |
|
2800 "Answer a new parser (logical not-predicate) that succeeds whenever the receiver fails, but never consumes input." |
|
2801 |
|
2802 ^ PPNotParser on: self!! !! |
|
2803 |
|
2804 !!PPParser methodsFor: ''operators'' stamp: ''lr 4/14/2010 11:53''!! |
|
2805 | aParser |
|
2806 "Answer a new parser that either parses the receiver or aParser. Fail if both pass or fail (exclusive choice, unordered choice)." |
|
2807 |
|
2808 ^ (self not , aParser) / (aParser not , self) ==> #second!! !! |
|
2809 |
|
2810 !!PPParser methodsFor: ''operators'' stamp: ''lr 9/23/2008 18:32''!! |
|
2811 , aParser |
|
2812 "Answer a new parser that parses the receiver followed by aParser." |
|
2813 |
|
2814 ^ PPSequenceParser with: self with: aParser!! !! |
|
2815 |
|
2816 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
2817 |
|
2818 PPParser class |
|
2819 instanceVariableNames: ''''!! |
|
2820 !!PPParser class commentStamp: ''<historical>'' prior: 0!! |
|
2821 !! |
|
2822 |
|
2823 |
|
2824 !!PPParser class methodsFor: ''instance creation'' stamp: ''lr 10/27/2008 11:17''!! |
|
2825 named: aString |
|
2826 ^ self new name: aString!! !! |
|
2827 |
|
2828 !!PPParser class methodsFor: ''instance creation'' stamp: ''lr 4/18/2008 14:00''!! |
|
2829 new |
|
2830 ^ self basicNew initialize!! !! |
|
2831 |
|
2832 |
|
2833 PPParser subclass: #PPPluggableParser |
|
2834 instanceVariableNames: ''block'' |
|
2835 classVariableNames: '''' |
|
2836 poolDictionaries: '''' |
|
2837 category: ''PetitParser-Parsers''!! |
|
2838 !!PPPluggableParser commentStamp: ''<historical>'' prior: 0!! |
|
2839 A pluggable parser that passes the parser stream into a block. This enables users to perform manual parsing or to embed other parser frameworks into PetitParser. |
|
2840 |
|
2841 Instance Variables: |
|
2842 block <BlockClosure> The pluggable one-argument block. |
|
2843 !! |
|
2844 |
|
2845 |
|
2846 !!PPPluggableParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 6/18/2010 14:09''!! |
|
2847 match: aParser inContext: aDictionary seen: anIdentitySet |
|
2848 ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self block = aParser block ]!! !! |
|
2849 |
|
2850 |
|
2851 !!PPPluggableParser methodsFor: ''initialization'' stamp: ''lr 5/2/2010 16:52''!! |
|
2852 initializeOn: aBlock |
|
2853 block := aBlock!! !! |
|
2854 |
|
2855 |
|
2856 !!PPPluggableParser methodsFor: ''pp-context'' stamp: ''JanKurs 11/11/2013 09:42''!! |
|
2857 parseOn: aPPContext |
|
2858 | position result | |
|
2859 position := aPPContext remember. |
|
2860 result := block value: aPPContext. |
|
2861 result isPetitFailure |
|
2862 ifTrue: [ aPPContext restore: position ]. |
|
2863 ^ result!! !! |
|
2864 |
|
2865 |
|
2866 !!PPPluggableParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/13/2009 14:41''!! |
|
2867 displayName |
|
2868 ^ String streamContents: [ :stream | block decompile shortPrintOn: stream ]!! !! |
|
2869 |
|
2870 |
|
2871 !!PPPluggableParser methodsFor: ''accessing'' stamp: ''lr 4/30/2010 11:10''!! |
|
2872 block |
|
2873 "Answer the pluggable block." |
|
2874 |
|
2875 ^ block!! !! |
|
2876 |
|
2877 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
2878 |
|
2879 PPPluggableParser class |
|
2880 instanceVariableNames: ''''!! |
|
2881 !!PPPluggableParser class commentStamp: ''<historical>'' prior: 0!! |
|
2882 !! |
|
2883 |
|
2884 |
|
2885 !!PPPluggableParser class methodsFor: ''instance creation'' stamp: ''lr 5/2/2010 16:52''!! |
|
2886 on: aBlock |
|
2887 ^ self new initializeOn: aBlock!! !! |
|
2888 |
|
2889 |
|
2890 PPParser subclass: #PPFailingParser |
|
2891 instanceVariableNames: ''message'' |
|
2892 classVariableNames: '''' |
|
2893 poolDictionaries: '''' |
|
2894 category: ''PetitParser-Parsers''!! |
|
2895 !!PPFailingParser commentStamp: ''<historical>'' prior: 0!! |
|
2896 A parser that consumes nothing and always fails. |
|
2897 |
|
2898 Instance Variables: |
|
2899 message <String> The failure message.!! |
|
2900 |
|
2901 |
|
2902 !!PPFailingParser methodsFor: ''initialization'' stamp: ''lr 5/2/2010 19:16''!! |
|
2903 setMessage: aString |
|
2904 message := aString!! !! |
|
2905 |
|
2906 |
|
2907 !!PPFailingParser methodsFor: ''pp-context'' stamp: ''JanKurs 8/19/2014 16:59''!! |
|
2908 parseOn: aPPContext |
|
2909 ^ PPFailure message: message context: aPPContext!! !! |
|
2910 |
|
2911 |
|
2912 !!PPFailingParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/6/2009 18:43''!! |
|
2913 displayName |
|
2914 ^ message!! !! |
|
2915 |
|
2916 !!PPFailingParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/13/2009 14:16''!! |
|
2917 displayColor |
|
2918 ^ Color red!! !! |
|
2919 |
|
2920 |
|
2921 !!PPFailingParser methodsFor: ''printing'' stamp: ''lr 4/16/2010 21:27''!! |
|
2922 printNameOn: aStream |
|
2923 super printNameOn: aStream. |
|
2924 aStream nextPutAll: '', ''; print: message!! !! |
|
2925 |
|
2926 |
|
2927 !!PPFailingParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 4/30/2010 12:01''!! |
|
2928 match: aParser inContext: aDictionary seen: anIdentitySet |
|
2929 ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self message = aParser message ]!! !! |
|
2930 |
|
2931 |
|
2932 !!PPFailingParser methodsFor: ''accessing'' stamp: ''lr 4/30/2010 11:10''!! |
|
2933 message |
|
2934 "Answer the error message of the receiving parser." |
|
2935 |
|
2936 ^ message!! !! |
|
2937 |
|
2938 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
2939 |
|
2940 PPFailingParser class |
|
2941 instanceVariableNames: ''''!! |
|
2942 !!PPFailingParser class commentStamp: ''<historical>'' prior: 0!! |
|
2943 !! |
|
2944 |
|
2945 |
|
2946 !!PPFailingParser class methodsFor: ''instance creation'' stamp: ''lr 5/2/2010 19:16''!! |
|
2947 message: aString |
|
2948 ^ self new setMessage: aString!! !! |
|
2949 |
|
2950 |
|
2951 PPParser subclass: #PPLiteralParser |
|
2952 instanceVariableNames: ''literal message'' |
|
2953 classVariableNames: '''' |
|
2954 poolDictionaries: '''' |
|
2955 category: ''PetitParser-Parsers''!! |
|
2956 !!PPLiteralParser commentStamp: ''<historical>'' prior: 0!! |
|
2957 Abstract literal parser that parses some kind of literal type (to be specified by subclasses). |
|
2958 |
|
2959 Instance Variables: |
|
2960 literal <Object> The literal object to be parsed. |
|
2961 message <String> The error message to be generated. |
|
2962 !! |
|
2963 |
|
2964 |
|
2965 !!PPLiteralParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 9/15/2010 12:08''!! |
|
2966 match: aParser inContext: aDictionary seen: anIdentitySet |
|
2967 ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self literal = aParser literal and: [ self message = aParser message ] ]!! !! |
|
2968 |
|
2969 |
|
2970 !!PPLiteralParser methodsFor: ''*petitgui-mondrian'' stamp: ''AlexandreBergel 12/18/2013 17:25''!! |
|
2971 visualizationGraphType |
|
2972 ^ literal printString!! !! |
|
2973 |
|
2974 |
|
2975 !!PPLiteralParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/13/2009 14:19''!! |
|
2976 displayName |
|
2977 ^ literal printString!! !! |
|
2978 |
|
2979 |
|
2980 !!PPLiteralParser methodsFor: ''accessing'' stamp: ''lr 5/2/2010 13:26''!! |
|
2981 message |
|
2982 "Answer the failure message." |
|
2983 |
|
2984 ^ message!! !! |
|
2985 |
|
2986 !!PPLiteralParser methodsFor: ''accessing'' stamp: ''lr 5/2/2010 13:26''!! |
|
2987 literal |
|
2988 "Answer the parsed literal." |
|
2989 |
|
2990 ^ literal!! !! |
|
2991 |
|
2992 |
|
2993 !!PPLiteralParser methodsFor: ''operators'' stamp: ''lr 6/1/2010 22:24''!! |
|
2994 caseInsensitive |
|
2995 "Answer a parser that can parse the receiver case-insensitive." |
|
2996 |
|
2997 self subclassResponsibility!! !! |
|
2998 |
|
2999 |
|
3000 !!PPLiteralParser methodsFor: ''initialization'' stamp: ''lr 5/2/2010 13:25''!! |
|
3001 initializeOn: anObject message: aString |
|
3002 literal := anObject. |
|
3003 message := aString!! !! |
|
3004 |
|
3005 |
|
3006 !!PPLiteralParser methodsFor: ''printing'' stamp: ''lr 4/16/2010 16:38''!! |
|
3007 printNameOn: aStream |
|
3008 super printNameOn: aStream. |
|
3009 aStream nextPutAll: '', ''; print: literal!! !! |
|
3010 |
|
3011 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
3012 |
|
3013 PPLiteralParser class |
|
3014 instanceVariableNames: ''''!! |
|
3015 !!PPLiteralParser class commentStamp: ''<historical>'' prior: 0!! |
|
3016 !! |
|
3017 |
|
3018 |
|
3019 !!PPLiteralParser class methodsFor: ''instance creation'' stamp: ''lr 1/7/2010 15:29''!! |
|
3020 on: anObject message: aString |
|
3021 ^ self new initializeOn: anObject message: aString!! !! |
|
3022 |
|
3023 !!PPLiteralParser class methodsFor: ''instance creation'' stamp: ''lr 1/7/2010 15:30''!! |
|
3024 on: anObject |
|
3025 ^ self on: anObject message: anObject printString , '' expected''!! !! |
|
3026 |
|
3027 |
|
3028 PPLiteralParser subclass: #PPLiteralObjectParser |
|
3029 instanceVariableNames: '''' |
|
3030 classVariableNames: '''' |
|
3031 poolDictionaries: '''' |
|
3032 category: ''PetitParser-Parsers''!! |
|
3033 !!PPLiteralObjectParser commentStamp: ''<historical>'' prior: 0!! |
|
3034 A parser that accepts a single literal object, such as a character. This is the same as the predicate parser ''PPPredicateParser expect: literal'' but slightly more efficient.!! |
|
3035 |
|
3036 |
|
3037 !!PPLiteralObjectParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/9/2009 14:25''!! |
|
3038 exampleOn: aStream |
|
3039 aStream nextPut: literal!! !! |
|
3040 |
|
3041 |
|
3042 !!PPLiteralObjectParser methodsFor: ''pp-context'' stamp: ''JanKurs 8/19/2014 17:00''!! |
|
3043 parseOn: aPPContext |
|
3044 ^ (aPPContext stream atEnd not and: [ literal = aPPContext stream uncheckedPeek ]) |
|
3045 ifFalse: [ PPFailure message: message context: aPPContext ] |
|
3046 ifTrue: [ aPPContext stream next ]!! !! |
|
3047 |
|
3048 |
|
3049 !!PPLiteralObjectParser methodsFor: ''operators'' stamp: ''lr 8/18/2010 20:16''!! |
|
3050 caseInsensitive |
|
3051 "Answer a parser that can parse the receiver case-insensitive." |
|
3052 |
|
3053 literal asUppercase = literal asLowercase ifTrue: [ ^ self ]. |
|
3054 ^ PPPredicateObjectParser on: [ :value | literal sameAs: value ] message: message!! !! |
|
3055 |
|
3056 !!PPLiteralObjectParser methodsFor: ''operators'' stamp: ''lr 4/28/2011 20:02''!! |
|
3057 negate |
|
3058 ^ (PPPredicateObjectParser expect: literal message: message) negate!! !! |
|
3059 |
|
3060 |
|
3061 PPParser subclass: #PPPredicateParser |
|
3062 instanceVariableNames: ''predicate predicateMessage negated negatedMessage'' |
|
3063 classVariableNames: '''' |
|
3064 poolDictionaries: '''' |
|
3065 category: ''PetitParser-Parsers''!! |
|
3066 !!PPPredicateParser commentStamp: ''<historical>'' prior: 0!! |
|
3067 An abstract parser that accepts if a given predicate holds. |
|
3068 |
|
3069 Instance Variables: |
|
3070 predicate <BlockClosure> The block testing for the predicate. |
|
3071 predicateMessage <String> The error message of the predicate. |
|
3072 negated <BlockClosure> The block testing for the negation of the predicate. |
|
3073 negatedMessage <String> The error message of the negated predicate.!! |
|
3074 |
|
3075 |
|
3076 !!PPPredicateParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 9/15/2010 11:56''!! |
|
3077 match: aParser inContext: aDictionary seen: anIdentitySet |
|
3078 ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self block = aParser block and: [ self message = aParser message ] ]!! !! |
|
3079 |
|
3080 |
|
3081 !!PPPredicateParser methodsFor: ''printing'' stamp: ''lr 5/2/2010 13:37''!! |
|
3082 printNameOn: aStream |
|
3083 super printNameOn: aStream. |
|
3084 aStream nextPutAll: '', ''; print: predicateMessage!! !! |
|
3085 |
|
3086 |
|
3087 !!PPPredicateParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 5/1/2010 17:05''!! |
|
3088 exampleOn: aStream |
|
3089 "Produce a random character that is valid. If there are characters in the alpha-numeric range prefer those over all others." |
|
3090 |
|
3091 | valid normal | |
|
3092 valid := Character allCharacters |
|
3093 select: [ :char | self matches: (String with: char) ]. |
|
3094 normal := valid |
|
3095 select: [ :char | char asInteger < 127 and: [ char isAlphaNumeric ] ]. |
|
3096 aStream nextPut: (normal isEmpty |
|
3097 ifTrue: [ valid atRandom ] |
|
3098 ifFalse: [ normal atRandom ])!! !! |
|
3099 |
|
3100 !!PPPredicateParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 5/2/2010 19:35''!! |
|
3101 displayName |
|
3102 ^ predicateMessage!! !! |
|
3103 |
|
3104 |
|
3105 !!PPPredicateParser methodsFor: ''accessing'' stamp: ''lr 5/2/2010 13:36''!! |
|
3106 message |
|
3107 "Answer the failure message." |
|
3108 |
|
3109 ^ predicateMessage!! !! |
|
3110 |
|
3111 !!PPPredicateParser methodsFor: ''accessing'' stamp: ''lr 5/2/2010 13:36''!! |
|
3112 block |
|
3113 "Answer the predicate block of the receiver." |
|
3114 |
|
3115 ^ predicate!! !! |
|
3116 |
|
3117 |
|
3118 PPPredicateParser subclass: #PPPredicateObjectParser |
|
3119 instanceVariableNames: '''' |
|
3120 classVariableNames: '''' |
|
3121 poolDictionaries: '''' |
|
3122 category: ''PetitParser-Parsers''!! |
|
3123 !!PPPredicateObjectParser commentStamp: ''<historical>'' prior: 0!! |
|
3124 A parser that accepts if a given predicate on one element of the input sequence holds.!! |
|
3125 |
|
3126 |
|
3127 !!PPPredicateObjectParser methodsFor: ''operators'' stamp: ''lr 6/12/2010 09:12''!! |
|
3128 negate |
|
3129 "Answer a parser that is the negation of the receiving predicate parser." |
|
3130 |
|
3131 ^ self class |
|
3132 on: negated message: negatedMessage |
|
3133 negated: predicate message: predicateMessage!! !! |
|
3134 |
|
3135 |
|
3136 !!PPPredicateObjectParser methodsFor: ''pp-context'' stamp: ''JanKurs 8/19/2014 17:03''!! |
|
3137 parseOn: aPPContext |
|
3138 ^ (aPPContext stream atEnd not and: [ predicate value: aPPContext stream uncheckedPeek ]) |
|
3139 ifFalse: [ PPFailure message: predicateMessage context: aPPContext ] |
|
3140 ifTrue: [ aPPContext stream next ]!! !! |
|
3141 |
|
3142 |
|
3143 !!PPPredicateObjectParser methodsFor: ''initialization'' stamp: ''lr 6/12/2010 09:12''!! |
|
3144 initializeOn: aBlock message: aString negated: aNegatedBlock message: aNegatedString |
|
3145 predicate := aBlock. |
|
3146 predicateMessage := aString. |
|
3147 negated := aNegatedBlock. |
|
3148 negatedMessage := aNegatedString!! !! |
|
3149 |
|
3150 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
3151 |
|
3152 PPPredicateObjectParser class |
|
3153 instanceVariableNames: ''''!! |
|
3154 !!PPPredicateObjectParser class commentStamp: ''<historical>'' prior: 0!! |
|
3155 !! |
|
3156 |
|
3157 |
|
3158 !!PPPredicateObjectParser class methodsFor: ''*petitregex-chars'' stamp: ''lr 8/30/2010 14:48''!! |
|
3159 control |
|
3160 ^ self chars: ((0 to: 31) collect: [ :each | Character value: each ]) message: ''control character expected''!! !! |
|
3161 |
|
3162 |
|
3163 !!PPPredicateObjectParser class methodsFor: ''factory-objects'' stamp: ''lr 8/25/2010 10:57''!! |
|
3164 expect: anObject |
|
3165 ^ self expect: anObject message: anObject printString , '' expected''!! !! |
|
3166 |
|
3167 !!PPPredicateObjectParser class methodsFor: ''factory-objects'' stamp: ''lr 4/1/2011 20:05''!! |
|
3168 anyExceptAnyOf: aCollection |
|
3169 ^ self |
|
3170 on: [ :each | (aCollection includes: each) not ] message: ''any except '' , aCollection printString , '' expected'' |
|
3171 negated: [ :each | aCollection includes: each ] message: aCollection printString , '' not expected''!! !! |
|
3172 |
|
3173 !!PPPredicateObjectParser class methodsFor: ''factory-objects'' stamp: ''lr 4/1/2011 20:05''!! |
|
3174 anyOf: aCollection |
|
3175 ^ self |
|
3176 on: [ :each | aCollection includes: each ] message: ''any of '' , aCollection printString , '' expected'' |
|
3177 negated: [ :each | (aCollection includes: each) not ] message: ''none of '' , aCollection printString , ''expected''!! !! |
|
3178 |
|
3179 !!PPPredicateObjectParser class methodsFor: ''factory-objects'' stamp: ''lr 6/12/2010 09:10''!! |
|
3180 any |
|
3181 ^ self |
|
3182 on: [ :each | true ] message: ''input expected'' |
|
3183 negated: [ :each | false ] message: ''no input expected''!! !! |
|
3184 |
|
3185 !!PPPredicateObjectParser class methodsFor: ''factory-objects'' stamp: ''lr 6/12/2010 09:10''!! |
|
3186 between: min and: max |
|
3187 ^ self |
|
3188 on: [ :each | each >= min and: [ each <= max ] ] message: min printString , ''..'' , max printString , '' expected'' |
|
3189 negated: [ :each | each < min or: [ each > max ] ] message: min printString , ''..'' , max printString , '' not expected''!! !! |
|
3190 |
|
3191 !!PPPredicateObjectParser class methodsFor: ''factory-objects'' stamp: ''lr 8/25/2010 10:57''!! |
|
3192 expect: anObject message: aString |
|
3193 ^ self |
|
3194 on: [ :each | each = anObject ] message: aString |
|
3195 negated: [ :each | each ~= anObject ] message: ''no '' , aString!! !! |
|
3196 |
|
3197 |
|
3198 !!PPPredicateObjectParser class methodsFor: ''instance creation'' stamp: ''lr 6/12/2010 09:10''!! |
|
3199 on: aBlock message: aString |
|
3200 ^ self on: aBlock message: aString negated: [ :each | (aBlock value: each) not ] message: ''no '' , aString!! !! |
|
3201 |
|
3202 !!PPPredicateObjectParser class methodsFor: ''instance creation'' stamp: ''lr 6/12/2010 09:10''!! |
|
3203 on: aBlock message: aString negated: aNegatedBlock message: aNegatedString |
|
3204 ^ self new initializeOn: aBlock message: aString negated: aNegatedBlock message: aNegatedString!! !! |
|
3205 |
|
3206 |
|
3207 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:02''!! |
|
3208 char: aCharacter |
|
3209 ^ self expect: aCharacter message: (String with: $" with: aCharacter with: $") , '' expected''!! !! |
|
3210 |
|
3211 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:04''!! |
|
3212 punctuation |
|
3213 ^ self chars: ''.,"''''?!!!!;:#$%&()*+-/<>=@[]\^_{}|~'' message: ''punctuation expected''!! !! |
|
3214 |
|
3215 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:02''!! |
|
3216 blank |
|
3217 ^ self chars: (String with: Character space with: Character tab) message: ''blank expected''!! !! |
|
3218 |
|
3219 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:06''!! |
|
3220 hex |
|
3221 ^ self |
|
3222 on: (PPCharSetPredicate on: [ :char | |
|
3223 (char between: $0 and: $9) |
|
3224 or: [ (char between: $a and: $f) |
|
3225 or: [ (char between: $A and: $F) ] ] ]) |
|
3226 message: ''hex digit expected''!! !! |
|
3227 |
|
3228 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:04''!! |
|
3229 newline |
|
3230 ^ self chars: (String with: Character cr with: Character lf) message: ''newline expected''!! !! |
|
3231 |
|
3232 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:06''!! |
|
3233 word |
|
3234 ^ self on: (PPCharSetPredicate on: [ :char | char isAlphaNumeric ]) message: ''letter or digit expected''!! !! |
|
3235 |
|
3236 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 6/12/2010 09:10''!! |
|
3237 lf |
|
3238 ^ self char: Character lf!! !! |
|
3239 |
|
3240 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:06''!! |
|
3241 digit |
|
3242 ^ self on: (PPCharSetPredicate on: [ :char | char isDigit ]) message: ''digit expected''!! !! |
|
3243 |
|
3244 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:05''!! |
|
3245 letter |
|
3246 ^ self on: (PPCharSetPredicate on: [ :char | char isLetter ]) message: ''letter expected''!! !! |
|
3247 |
|
3248 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:06''!! |
|
3249 uppercase |
|
3250 ^ self on: (PPCharSetPredicate on: [ :char | char isUppercase ]) message: ''uppercase letter expected''!! !! |
|
3251 |
|
3252 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:02''!! |
|
3253 cr |
|
3254 ^ self char: Character cr message: ''carriage return expected''!! !! |
|
3255 |
|
3256 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:06''!! |
|
3257 space |
|
3258 ^ self on: (PPCharSetPredicate on: [ :char | char isSeparator ]) message: ''separator expected''!! !! |
|
3259 |
|
3260 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:06''!! |
|
3261 lowercase |
|
3262 ^ self on: (PPCharSetPredicate on: [ :char | char isLowercase ]) message: ''lowercase letter expected''!! !! |
|
3263 |
|
3264 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:04''!! |
|
3265 tab |
|
3266 ^ self char: Character tab message: ''tab expected''!! !! |
|
3267 |
|
3268 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 11:06''!! |
|
3269 chars: aCollection message: aString |
|
3270 ^ self on: (PPCharSetPredicate on: [ :char | aCollection includes: char ]) message: aString!! !! |
|
3271 |
|
3272 !!PPPredicateObjectParser class methodsFor: ''factory-chars'' stamp: ''lr 8/25/2010 10:57''!! |
|
3273 char: aCharacter message: aString |
|
3274 ^ self expect: aCharacter message: aString!! !! |
|
3275 |
|
3276 |
|
3277 PPPredicateParser subclass: #PPPredicateSequenceParser |
|
3278 instanceVariableNames: ''size'' |
|
3279 classVariableNames: '''' |
|
3280 poolDictionaries: '''' |
|
3281 category: ''PetitParser-Parsers''!! |
|
3282 !!PPPredicateSequenceParser commentStamp: ''<historical>'' prior: 0!! |
|
3283 A parser that accepts if a given predicate on an arbitrary number of elements of the input sequence holds. |
|
3284 |
|
3285 Instance Variables: |
|
3286 size <Integer> The number of elements to consume.!! |
|
3287 |
|
3288 |
|
3289 !!PPPredicateSequenceParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 6/18/2010 14:09''!! |
|
3290 match: aParser inContext: aDictionary seen: anIdentitySet |
|
3291 ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self size = aParser size ]!! !! |
|
3292 |
|
3293 |
|
3294 !!PPPredicateSequenceParser methodsFor: ''operators'' stamp: ''lr 6/12/2010 09:14''!! |
|
3295 negate |
|
3296 "Answer a parser that is the negation of the receiving predicate parser." |
|
3297 |
|
3298 ^ self class |
|
3299 on: negated message: negatedMessage |
|
3300 negated: predicate message: predicateMessage |
|
3301 size: size!! !! |
|
3302 |
|
3303 |
|
3304 !!PPPredicateSequenceParser methodsFor: ''pp-context'' stamp: ''JanKurs 8/19/2014 17:03''!! |
|
3305 parseOn: aPPContext |
|
3306 | position result | |
|
3307 position := aPPContext remember. |
|
3308 result := aPPContext stream next: size. |
|
3309 (result size = size and: [ predicate value: result ]) |
|
3310 ifTrue: [ ^ result ]. |
|
3311 aPPContext restore: position. |
|
3312 ^ PPFailure message: predicateMessage context: aPPContext!! !! |
|
3313 |
|
3314 |
|
3315 !!PPPredicateSequenceParser methodsFor: ''accessing'' stamp: ''lr 6/12/2010 08:58''!! |
|
3316 size |
|
3317 "Answer the sequence size of the receiver." |
|
3318 |
|
3319 ^ size!! !! |
|
3320 |
|
3321 |
|
3322 !!PPPredicateSequenceParser methodsFor: ''initialization'' stamp: ''lr 6/12/2010 09:13''!! |
|
3323 initializeOn: aBlock message: aString negated: aNegatedBlock message: aNegatedString size: anInteger |
|
3324 predicate := aBlock. |
|
3325 predicateMessage := aString. |
|
3326 negated := aNegatedBlock. |
|
3327 negatedMessage := aNegatedString. |
|
3328 size := anInteger !! !! |
|
3329 |
|
3330 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
3331 |
|
3332 PPPredicateSequenceParser class |
|
3333 instanceVariableNames: ''''!! |
|
3334 !!PPPredicateSequenceParser class commentStamp: ''<historical>'' prior: 0!! |
|
3335 !! |
|
3336 |
|
3337 |
|
3338 !!PPPredicateSequenceParser class methodsFor: ''instance creation'' stamp: ''lr 6/12/2010 09:14''!! |
|
3339 on: aBlock message: aString negated: aNegatedBlock message: aNegatedString size: anInteger |
|
3340 ^ self new initializeOn: aBlock message: aString negated: aNegatedBlock message: aNegatedString size: anInteger!! !! |
|
3341 |
|
3342 !!PPPredicateSequenceParser class methodsFor: ''instance creation'' stamp: ''lr 6/12/2010 09:14''!! |
|
3343 on: aBlock message: aString size: anInteger |
|
3344 ^ self on: aBlock message: aString negated: [ :each | (aBlock value: each) not ] message: ''no '' , aString size: anInteger !! !! |
|
3345 |
|
3346 |
|
3347 PPParser subclass: #PPDelegateParser |
|
3348 instanceVariableNames: ''parser'' |
|
3349 classVariableNames: '''' |
|
3350 poolDictionaries: '''' |
|
3351 category: ''PetitParser-Parsers''!! |
|
3352 !!PPDelegateParser commentStamp: ''<historical>'' prior: 0!! |
|
3353 A parser that delegates to another parser. |
|
3354 |
|
3355 Instance Variables: |
|
3356 parser <PPParser> The parser to delegate to.!! |
|
3357 |
|
3358 |
|
3359 !!PPDelegateParser methodsFor: ''accessing'' stamp: ''lr 10/21/2009 16:37''!! |
|
3360 children |
|
3361 ^ Array with: parser!! !! |
|
3362 |
|
3363 |
|
3364 !!PPDelegateParser methodsFor: ''*petitanalyzer-transforming'' stamp: ''lr 4/13/2010 09:39''!! |
|
3365 replace: aParser with: anotherParser |
|
3366 super replace: aParser with: anotherParser. |
|
3367 parser == aParser ifTrue: [ parser := anotherParser ]!! !! |
|
3368 |
|
3369 |
|
3370 !!PPDelegateParser methodsFor: ''pp-context'' stamp: ''JanKurs 11/11/2013 09:31''!! |
|
3371 parseOn: aPPContext |
|
3372 ^ parser parseOn: aPPContext!! !! |
|
3373 |
|
3374 |
|
3375 !!PPDelegateParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/9/2009 14:27''!! |
|
3376 exampleOn: aStream |
|
3377 parser exampleOn: aStream!! !! |
|
3378 |
|
3379 !!PPDelegateParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/13/2009 14:20''!! |
|
3380 displayDescription |
|
3381 ^ nil!! !! |
|
3382 |
|
3383 |
|
3384 !!PPDelegateParser methodsFor: ''initialization'' stamp: ''lr 4/20/2008 16:23''!! |
|
3385 setParser: aParser |
|
3386 parser := aParser!! !! |
|
3387 |
|
3388 |
|
3389 !!PPDelegateParser methodsFor: ''*petitgui-morphic'' stamp: ''lr 11/18/2009 11:21''!! |
|
3390 morphicShapeSeen: aSet depth: anInteger |
|
3391 ^ self morphicShapeSeen: aSet depth: anInteger do: [ :cc | |
|
3392 self displayDescription isNil |
|
3393 ifTrue: [ cc value: parser ] |
|
3394 ifFalse: [ |
|
3395 self newRowMorph |
|
3396 addMorphBack: (self newColumnMorph |
|
3397 addMorphBack: (self newSpacerMorph height: 10); |
|
3398 addMorphBack: (LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1); |
|
3399 yourself); |
|
3400 addMorphBack: (self newRowMorph |
|
3401 color: (self backgroundForDepth: anInteger); |
|
3402 addMorphBack: (self newColumnMorph |
|
3403 addMorphBack: (cc value: parser); |
|
3404 addMorphBack: (self newRowMorph |
|
3405 hResizing: #spaceFill; |
|
3406 addMorphBack: (self newSpacerMorph |
|
3407 width: 20; |
|
3408 yourself); |
|
3409 addMorphBack: (self newColumnMorph |
|
3410 hResizing: #spaceFill; |
|
3411 listCentering: #center; |
|
3412 addMorphBack: (self newSpacerMorph); |
|
3413 addMorphBack: (StringMorph new |
|
3414 contents: self displayDescription; |
|
3415 yourself); |
|
3416 yourself); |
|
3417 yourself); |
|
3418 yourself); |
|
3419 addMorphBack: (self newColumnMorph |
|
3420 addMorphBack: (self newSpacerMorph height: 10); |
|
3421 addMorphBack: (LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1); |
|
3422 yourself); |
|
3423 yourself); |
|
3424 yourself ] ]!! !! |
|
3425 |
|
3426 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
3427 |
|
3428 PPDelegateParser class |
|
3429 instanceVariableNames: ''''!! |
|
3430 !!PPDelegateParser class commentStamp: ''<historical>'' prior: 0!! |
|
3431 !! |
|
3432 |
|
3433 |
|
3434 !!PPDelegateParser class methodsFor: ''instance creation'' stamp: ''lr 4/20/2008 16:22''!! |
|
3435 on: aParser |
|
3436 ^ self new setParser: aParser!! !! |
|
3437 |
|
3438 |
|
3439 PPDelegateParser subclass: #PPAndParser |
|
3440 instanceVariableNames: '''' |
|
3441 classVariableNames: '''' |
|
3442 poolDictionaries: '''' |
|
3443 category: ''PetitParser-Parsers''!! |
|
3444 !!PPAndParser commentStamp: ''TudorGirba 2/27/2011 22:22'' prior: 0!! |
|
3445 The and-predicate, a parser that succeeds whenever its delegate does, but does not consume the input stream [Parr 1994, 1995].!! |
|
3446 |
|
3447 |
|
3448 !!PPAndParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 5/1/2010 16:16''!! |
|
3449 exampleOn: aStream!! !! |
|
3450 |
|
3451 !!PPAndParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/13/2009 14:17''!! |
|
3452 displayDescription |
|
3453 ^ ''and''!! !! |
|
3454 |
|
3455 |
|
3456 !!PPAndParser methodsFor: ''operators'' stamp: ''lr 5/1/2010 16:16''!! |
|
3457 and |
|
3458 ^ self!! !! |
|
3459 |
|
3460 |
|
3461 !!PPAndParser methodsFor: ''pp-context'' stamp: ''JanKurs 1/15/2014 15:50''!! |
|
3462 parseOn: aPPContext |
|
3463 | element position | |
|
3464 position := aPPContext remember. |
|
3465 element := parser parseOn: aPPContext. |
|
3466 aPPContext restore: position. |
|
3467 ^ element!! !! |
|
3468 |
|
3469 |
|
3470 PPDelegateParser subclass: #PPTrimmingParser |
|
3471 instanceVariableNames: ''trimmer'' |
|
3472 classVariableNames: '''' |
|
3473 poolDictionaries: '''' |
|
3474 category: ''PetitParser-Parsers''!! |
|
3475 !!PPTrimmingParser commentStamp: ''lr 4/6/2010 19:27'' prior: 0!! |
|
3476 A parser that silently consumes spaces before and after the delegate parser.!! |
|
3477 |
|
3478 |
|
3479 !!PPTrimmingParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 4/14/2010 20:48''!! |
|
3480 exampleOn: aStream |
|
3481 super exampleOn: aStream. |
|
3482 aStream nextPut: Character space!! !! |
|
3483 |
|
3484 |
|
3485 !!PPTrimmingParser methodsFor: ''pp-context'' stamp: ''JanKurs 1/15/2014 15:42''!! |
|
3486 parseOn: aPPContext |
|
3487 | position element | |
|
3488 position := aPPContext remember. |
|
3489 [ (trimmer parseOn: aPPContext) isPetitFailure ] |
|
3490 whileFalse. |
|
3491 element := parser parseOn: aPPContext. |
|
3492 element isPetitFailure ifTrue: [ |
|
3493 aPPContext restore: position. |
|
3494 ^ element ]. |
|
3495 [ (trimmer parseOn: aPPContext) isPetitFailure ] |
|
3496 whileFalse. |
|
3497 ^ element!! !! |
|
3498 |
|
3499 |
|
3500 !!PPTrimmingParser methodsFor: ''initialization'' stamp: ''lr 7/31/2010 12:00''!! |
|
3501 setTrimmer: aParser |
|
3502 trimmer := aParser!! !! |
|
3503 |
|
3504 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
3505 |
|
3506 PPTrimmingParser class |
|
3507 instanceVariableNames: ''''!! |
|
3508 !!PPTrimmingParser class commentStamp: ''<historical>'' prior: 0!! |
|
3509 !! |
|
3510 |
|
3511 |
|
3512 !!PPTrimmingParser class methodsFor: ''instance creation'' stamp: ''lr 7/31/2010 12:01''!! |
|
3513 on: aParser trimmer: aTrimParser |
|
3514 ^ self new |
|
3515 setParser: aParser; |
|
3516 setTrimmer: aTrimParser; |
|
3517 yourself!! !! |
|
3518 |
|
3519 |
|
3520 PPDelegateParser subclass: #PPMemoizedParser |
|
3521 instanceVariableNames: ''buffer context'' |
|
3522 classVariableNames: '''' |
|
3523 poolDictionaries: '''' |
|
3524 category: ''PetitParser-Parsers''!! |
|
3525 !!PPMemoizedParser commentStamp: ''<historical>'' prior: 0!! |
|
3526 A memoized parser, for refraining redundant computations. |
|
3527 |
|
3528 Instance Variables: |
|
3529 stream <PositionableStream> The stream of the associated memento objects. |
|
3530 buffer <Array of: PPMemento> The buffer of memento objects. |
|
3531 !! |
|
3532 |
|
3533 |
|
3534 !!PPMemoizedParser methodsFor: ''operators'' stamp: ''lr 4/2/2009 19:48''!! |
|
3535 memoized |
|
3536 "Ther is no point in memoizing more than once." |
|
3537 |
|
3538 ^ self!! !! |
|
3539 |
|
3540 |
|
3541 !!PPMemoizedParser methodsFor: ''pp-context'' stamp: ''JanKurs 8/19/2014 13:20''!! |
|
3542 reset: aPPContext |
|
3543 context := aPPContext. |
|
3544 buffer := Dictionary new.!! !! |
|
3545 |
|
3546 !!PPMemoizedParser methodsFor: ''pp-context'' stamp: ''JanKurs 8/19/2014 17:00''!! |
|
3547 parseOn: aPPContext |
|
3548 | memento contextMemento aStream | |
|
3549 "TODO: JK memoizing needs review!!!!" |
|
3550 |
|
3551 contextMemento := aPPContext remember. |
|
3552 context == aPPContext |
|
3553 ifFalse: [ self reset: aPPContext ]. |
|
3554 memento := (buffer at: contextMemento ifAbsentPut: [ PPMemento new ]). |
|
3555 |
|
3556 memento contextMemento isNil |
|
3557 ifTrue: [ |
|
3558 aStream := aPPContext stream. |
|
3559 memento result: (aStream size - aStream position + 2 < memento count |
|
3560 ifTrue: [ PPFailure message: ''overflow'' context: aPPContext ] |
|
3561 ifFalse: [ memento increment. parser parseOn: aPPContext ]). |
|
3562 memento contextMemento: aPPContext remember ] |
|
3563 ifFalse: [ context restore: memento contextMemento ]. |
|
3564 ^ memento result.!! !! |
|
3565 |
|
3566 |
|
3567 PPDelegateParser subclass: #PPEndOfInputParser |
|
3568 instanceVariableNames: '''' |
|
3569 classVariableNames: '''' |
|
3570 poolDictionaries: '''' |
|
3571 category: ''PetitParser-Parsers''!! |
|
3572 !!PPEndOfInputParser commentStamp: ''lr 4/18/2008 13:46'' prior: 0!! |
|
3573 A parser that succeeds only at the end of the input stream.!! |
|
3574 |
|
3575 |
|
3576 !!PPEndOfInputParser methodsFor: ''pp-context'' stamp: ''JanKurs 8/19/2014 16:58''!! |
|
3577 parseOn: aPPContext |
|
3578 | position result | |
|
3579 position := aPPContext remember. |
|
3580 result := parser parseOn: aPPContext. |
|
3581 (result isPetitFailure or: [ aPPContext stream atEnd ]) |
|
3582 ifTrue: [ ^ result ]. |
|
3583 result := PPFailure |
|
3584 message: ''end of input expected'' |
|
3585 context: aPPContext. |
|
3586 aPPContext restore: position. |
|
3587 ^ result!! !! |
|
3588 |
|
3589 |
|
3590 !!PPEndOfInputParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/13/2009 14:18''!! |
|
3591 displayDescription |
|
3592 ^ ''end of input''!! !! |
|
3593 |
|
3594 |
|
3595 !!PPEndOfInputParser methodsFor: ''operators'' stamp: ''lr 12/7/2009 08:53''!! |
|
3596 end |
|
3597 ^ self!! !! |
|
3598 |
|
3599 |
|
3600 PPDelegateParser subclass: #PPActionParser |
|
3601 instanceVariableNames: ''block'' |
|
3602 classVariableNames: '''' |
|
3603 poolDictionaries: '''' |
|
3604 category: ''PetitParser-Parsers''!! |
|
3605 !!PPActionParser commentStamp: ''<historical>'' prior: 0!! |
|
3606 A parser that performs an action block with the successful parse result of the delegate. |
|
3607 |
|
3608 Instance Variables: |
|
3609 block <BlockClosure> The action block to be executed. |
|
3610 !! |
|
3611 |
|
3612 |
|
3613 !!PPActionParser methodsFor: ''initialization'' stamp: ''lr 5/2/2010 16:58''!! |
|
3614 setBlock: aBlock |
|
3615 block := aBlock!! !! |
|
3616 |
|
3617 |
|
3618 !!PPActionParser methodsFor: ''*petitgui-mondrian'' stamp: ''AlexandreBergel 12/18/2013 16:41''!! |
|
3619 visualizationGraphType |
|
3620 ^ ''[]''!! !! |
|
3621 |
|
3622 |
|
3623 !!PPActionParser methodsFor: ''pp-context'' stamp: ''JanKurs 11/11/2013 09:31''!! |
|
3624 parseOn: aPPContext |
|
3625 | element | |
|
3626 ^ (element := parser parseOn: aPPContext) isPetitFailure |
|
3627 ifFalse: [ block value: element ] |
|
3628 ifTrue: [ element ]!! !! |
|
3629 |
|
3630 |
|
3631 !!PPActionParser methodsFor: ''accessing'' stamp: ''lr 4/30/2010 11:10''!! |
|
3632 block |
|
3633 "Answer the action block of the receiver." |
|
3634 |
|
3635 ^ block!! !! |
|
3636 |
|
3637 |
|
3638 !!PPActionParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 5/7/2011 15:08''!! |
|
3639 match: aParser inContext: aDictionary seen: anIdentitySet |
|
3640 ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self block = aParser block ]!! !! |
|
3641 |
|
3642 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
3643 |
|
3644 PPActionParser class |
|
3645 instanceVariableNames: ''''!! |
|
3646 !!PPActionParser class commentStamp: ''<historical>'' prior: 0!! |
|
3647 !! |
|
3648 |
|
3649 |
|
3650 !!PPActionParser class methodsFor: ''instance creation'' stamp: ''lr 5/2/2010 16:58''!! |
|
3651 on: aParser block: aBlock |
|
3652 ^ (self on: aParser) setBlock: aBlock!! !! |
|
3653 |
|
3654 |
|
3655 PPActionParser subclass: #PPWrappingParser |
|
3656 instanceVariableNames: '''' |
|
3657 classVariableNames: '''' |
|
3658 poolDictionaries: '''' |
|
3659 category: ''PetitParser-Parsers''!! |
|
3660 !!PPWrappingParser commentStamp: ''<historical>'' prior: 0!! |
|
3661 A parser that performs an action block upon activation with the stream and a continuation block.!! |
|
3662 |
|
3663 |
|
3664 !!PPWrappingParser methodsFor: ''pp-context'' stamp: ''JanKurs 11/11/2013 09:31''!! |
|
3665 parseOn: aPPContext |
|
3666 ^ block value: aPPContext value: [ parser parseOn: aPPContext ]!! !! |
|
3667 |
|
3668 |
|
3669 PPParser subclass: #PPListParser |
|
3670 instanceVariableNames: ''parsers'' |
|
3671 classVariableNames: '''' |
|
3672 poolDictionaries: '''' |
|
3673 category: ''PetitParser-Parsers''!! |
|
3674 !!PPListParser commentStamp: ''<historical>'' prior: 0!! |
|
3675 Abstract parser that parses a list of things in some way (to be specified by the subclasses). |
|
3676 |
|
3677 Instance Variables: |
|
3678 parsers <SequenceableCollection of: PPParser> A sequence of other parsers to delegate to.!! |
|
3679 |
|
3680 |
|
3681 !!PPListParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 4/30/2010 08:15''!! |
|
3682 copyInContext: aDictionary seen: aSeenDictionary |
|
3683 | copy copies | |
|
3684 aSeenDictionary at: self ifPresent: [ :value | ^ value ]. |
|
3685 copy := aSeenDictionary at: self put: self copy. |
|
3686 copies := OrderedCollection new. |
|
3687 parsers do: [ :each | |
|
3688 | result | |
|
3689 result := each |
|
3690 copyInContext: aDictionary |
|
3691 seen: aSeenDictionary. |
|
3692 result isCollection |
|
3693 ifTrue: [ copies addAll: result ] |
|
3694 ifFalse: [ copies add: result ] ]. |
|
3695 ^ copy |
|
3696 setParsers: copies; |
|
3697 yourself!! !! |
|
3698 |
|
3699 |
|
3700 !!PPListParser methodsFor: ''*petitanalyzer-transforming'' stamp: ''lr 5/22/2010 10:24''!! |
|
3701 replace: aParser with: anotherParser |
|
3702 super replace: aParser with: anotherParser. |
|
3703 parsers keysAndValuesDo: [ :index :parser | |
|
3704 parser == aParser |
|
3705 ifTrue: [ parsers at: index put: anotherParser ] ]!! !! |
|
3706 |
|
3707 |
|
3708 !!PPListParser methodsFor: ''initialization'' stamp: ''lr 4/29/2010 10:12''!! |
|
3709 setParsers: aCollection |
|
3710 parsers := aCollection asArray!! !! |
|
3711 |
|
3712 !!PPListParser methodsFor: ''initialization'' stamp: ''lr 4/29/2010 10:12''!! |
|
3713 initialize |
|
3714 super initialize. |
|
3715 self setParsers: #()!! !! |
|
3716 |
|
3717 |
|
3718 !!PPListParser methodsFor: ''accessing'' stamp: ''lr 10/21/2009 16:37''!! |
|
3719 children |
|
3720 ^ parsers!! !! |
|
3721 |
|
3722 |
|
3723 !!PPListParser methodsFor: ''copying'' stamp: ''lr 9/17/2008 22:36''!! |
|
3724 copyWith: aParser |
|
3725 ^ self species withAll: (parsers copyWith: aParser)!! !! |
|
3726 |
|
3727 !!PPListParser methodsFor: ''copying'' stamp: ''lr 5/22/2010 10:26''!! |
|
3728 postCopy |
|
3729 super postCopy. |
|
3730 parsers := parsers copy!! !! |
|
3731 |
|
3732 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
3733 |
|
3734 PPListParser class |
|
3735 instanceVariableNames: ''''!! |
|
3736 !!PPListParser class commentStamp: ''<historical>'' prior: 0!! |
|
3737 !! |
|
3738 |
|
3739 |
|
3740 !!PPListParser class methodsFor: ''instance creation'' stamp: ''lr 9/23/2008 18:32''!! |
|
3741 with: aFirstParser with: aSecondParser |
|
3742 ^ self withAll: (Array with: aFirstParser with: aSecondParser)!! !! |
|
3743 |
|
3744 !!PPListParser class methodsFor: ''instance creation'' stamp: ''lr 5/3/2010 20:26''!! |
|
3745 with: aParser |
|
3746 ^ self withAll: (Array with: aParser)!! !! |
|
3747 |
|
3748 !!PPListParser class methodsFor: ''instance creation'' stamp: ''lr 4/29/2010 10:12''!! |
|
3749 withAll: aCollection |
|
3750 ^ self basicNew setParsers: aCollection!! !! |
|
3751 |
|
3752 |
|
3753 PPListParser subclass: #PPChoiceParser |
|
3754 instanceVariableNames: '''' |
|
3755 classVariableNames: '''' |
|
3756 poolDictionaries: '''' |
|
3757 category: ''PetitParser-Parsers''!! |
|
3758 !!PPChoiceParser commentStamp: ''lr 4/18/2008 15:35'' prior: 0!! |
|
3759 A parser that uses the first parser that succeeds.!! |
|
3760 |
|
3761 |
|
3762 !!PPChoiceParser methodsFor: ''*petitgui-mondrian'' stamp: ''AlexandreBergel 12/18/2013 16:42''!! |
|
3763 visualizationGraphType |
|
3764 ^ ''/''!! !! |
|
3765 |
|
3766 |
|
3767 !!PPChoiceParser methodsFor: ''operators'' stamp: ''lr 9/17/2008 00:16''!! |
|
3768 / aRule |
|
3769 ^ self copyWith: aRule!! !! |
|
3770 |
|
3771 |
|
3772 !!PPChoiceParser methodsFor: ''pp-context'' stamp: ''JanKurs 11/11/2013 09:31''!! |
|
3773 parseOn: aPPContext |
|
3774 "This is optimized code that avoids unnecessary block activations, do not change. When all choices fail, the last failure is answered." |
|
3775 |
|
3776 | element | |
|
3777 1 to: parsers size do: [ :index | |
|
3778 element := (parsers at: index) |
|
3779 parseOn: aPPContext. |
|
3780 element isPetitFailure |
|
3781 ifFalse: [ ^ element ] ]. |
|
3782 ^ element!! !! |
|
3783 |
|
3784 |
|
3785 !!PPChoiceParser methodsFor: ''*petitgui-morphic'' stamp: ''lr 5/2/2010 20:15''!! |
|
3786 exampleOn: aStream |
|
3787 "If there is already a lot written, try to pick an empty possiblity." |
|
3788 |
|
3789 aStream position > 512 ifTrue: [ |
|
3790 (parsers anySatisfy: [ :each | each isNullable ]) |
|
3791 ifTrue: [ ^ self ] ]. |
|
3792 parsers atRandom exampleOn: aStream!! !! |
|
3793 |
|
3794 !!PPChoiceParser methodsFor: ''*petitgui-morphic'' stamp: ''lr 11/18/2009 11:14''!! |
|
3795 morphicShapeSeen: aSet depth: anInteger |
|
3796 ^ self morphicShapeSeen: aSet depth: anInteger do: [ :cc | |
|
3797 | morph | |
|
3798 morph := self newColumnMorph |
|
3799 cellInset: 5; |
|
3800 yourself. |
|
3801 self children do: [ :each | |
|
3802 morph addMorphBack: (self newRowMorph |
|
3803 hResizing: #spaceFill; |
|
3804 addMorphBack: (cc value: each); |
|
3805 addMorphBack: (self newColumnMorph |
|
3806 hResizing: #spaceFill; |
|
3807 addMorphBack: (self newSpacerMorph height: 10); |
|
3808 addMorphBack: ((LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1) |
|
3809 hResizing: #spaceFill; |
|
3810 minWidth: 20; |
|
3811 yourself); |
|
3812 yourself); |
|
3813 yourself) ]. |
|
3814 morph fullBounds. |
|
3815 self newRowMorph |
|
3816 addMorphBack: (self newColumnMorph |
|
3817 addMorphBack: (self newSpacerMorph height: 10); |
|
3818 addMorphBack: (LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1); |
|
3819 yourself); |
|
3820 addMorphBack: (self newColumnMorph |
|
3821 addMorphBack: (self newSpacerMorph width: 1; height: 10); |
|
3822 addMorphBack: (LineMorph from: 0 @ 0 to: 0 @ (morph height - 23) color: Color black width: 1); |
|
3823 yourself); |
|
3824 addMorphBack: morph; |
|
3825 addMorphBack: (self newColumnMorph |
|
3826 addMorphBack: (self newSpacerMorph width: 1; height: 10); |
|
3827 addMorphBack: (LineMorph from: 0 @ (morph height - 23) to: 0 @ 0 color: Color black width: 1) |
|
3828 makeForwardArrow; |
|
3829 width: 1; |
|
3830 yourself); |
|
3831 yourself ]!! !! |
|
3832 |
|
3833 |
|
3834 PPDelegateParser subclass: #PPNotParser |
|
3835 instanceVariableNames: '''' |
|
3836 classVariableNames: '''' |
|
3837 poolDictionaries: '''' |
|
3838 category: ''PetitParser-Parsers''!! |
|
3839 !!PPNotParser commentStamp: ''<historical>'' prior: 0!! |
|
3840 The not-predicate, a parser that succeeds whenever its delegate does not, but consumes no input [Parr 1994, 1995].!! |
|
3841 |
|
3842 |
|
3843 !!PPNotParser methodsFor: ''*petitanalyzer-testing'' stamp: ''JanKurs 5/31/2013 11:50''!! |
|
3844 isFirstSetTerminal |
|
3845 ^ true!! !! |
|
3846 |
|
3847 |
|
3848 !!PPNotParser methodsFor: ''pp-context'' stamp: ''JanKurs 8/19/2014 17:01''!! |
|
3849 parseOn: aPPContext |
|
3850 | element position | |
|
3851 position := aPPContext remember. |
|
3852 element := parser parseOn: aPPContext. |
|
3853 aPPContext restore: position. |
|
3854 ^ element isPetitFailure |
|
3855 ifFalse: [ PPFailure message: '''' context: aPPContext ]!! !! |
|
3856 |
|
3857 |
|
3858 !!PPNotParser methodsFor: ''*petitanalyzer-private'' stamp: ''JanKurs 5/31/2013 11:50''!! |
|
3859 firstSets: aFirstDictionary into: aSet |
|
3860 !! !! |
|
3861 |
|
3862 |
|
3863 !!PPNotParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/11/2009 21:09''!! |
|
3864 exampleOn: aStream!! !! |
|
3865 |
|
3866 !!PPNotParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/13/2009 14:17''!! |
|
3867 displayDescription |
|
3868 ^ ''not''!! !! |
|
3869 |
|
3870 |
|
3871 PPLiteralParser subclass: #PPLiteralSequenceParser |
|
3872 instanceVariableNames: ''size'' |
|
3873 classVariableNames: '''' |
|
3874 poolDictionaries: '''' |
|
3875 category: ''PetitParser-Parsers''!! |
|
3876 !!PPLiteralSequenceParser commentStamp: ''lr 12/4/2009 18:39'' prior: 0!! |
|
3877 A parser accepts a sequence of literal objects, such as a String. This is an optimization to avoid having to compose longer sequences from PPSequenceParser.!! |
|
3878 |
|
3879 |
|
3880 !!PPLiteralSequenceParser methodsFor: ''pp-context'' stamp: ''JanKurs 8/19/2014 16:38''!! |
|
3881 parseOn: aPPContext |
|
3882 | memento result | |
|
3883 memento := aPPContext remember. |
|
3884 result := aPPContext stream next: size. |
|
3885 literal = result ifTrue: [ ^ result ]. |
|
3886 aPPContext restore: memento. |
|
3887 ^ PPFailure message: message context: aPPContext!! !! |
|
3888 |
|
3889 |
|
3890 !!PPLiteralSequenceParser methodsFor: ''initialization'' stamp: ''lr 6/1/2010 22:21''!! |
|
3891 initializeOn: anObject message: aString |
|
3892 super initializeOn: anObject message: aString. |
|
3893 size := literal size!! !! |
|
3894 |
|
3895 |
|
3896 !!PPLiteralSequenceParser methodsFor: ''accessing'' stamp: ''lr 9/15/2010 11:16''!! |
|
3897 size |
|
3898 "Answer the sequence size of the receiver." |
|
3899 |
|
3900 ^ size!! !! |
|
3901 |
|
3902 |
|
3903 !!PPLiteralSequenceParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/9/2009 14:25''!! |
|
3904 exampleOn: aStream |
|
3905 aStream nextPutAll: literal!! !! |
|
3906 |
|
3907 |
|
3908 !!PPLiteralSequenceParser methodsFor: ''operators'' stamp: ''lr 8/18/2010 20:16''!! |
|
3909 caseInsensitive |
|
3910 "Answer a parser that can parse the receiver case-insensitive." |
|
3911 |
|
3912 literal asUppercase = literal asLowercase ifTrue: [ ^ self ]. |
|
3913 ^ PPPredicateSequenceParser on: [ :value | literal sameAs: value ] message: message size: size!! !! |
|
3914 |
|
3915 |
|
3916 PPDelegateParser subclass: #PPOptionalParser |
|
3917 instanceVariableNames: '''' |
|
3918 classVariableNames: '''' |
|
3919 poolDictionaries: '''' |
|
3920 category: ''PetitParser-Parsers''!! |
|
3921 !!PPOptionalParser commentStamp: ''lr 4/3/2011 14:46'' prior: 0!! |
|
3922 A parser that optionally parsers its delegate, or answers nil.!! |
|
3923 |
|
3924 |
|
3925 !!PPOptionalParser methodsFor: ''*petitanalyzer-testing'' stamp: ''lr 9/1/2010 22:10''!! |
|
3926 isNullable |
|
3927 ^ true!! !! |
|
3928 |
|
3929 |
|
3930 !!PPOptionalParser methodsFor: ''*petitgui-mondrian'' stamp: ''AlexandreBergel 12/18/2013 16:44''!! |
|
3931 visualizationGraphType |
|
3932 ^ ''?''!! !! |
|
3933 |
|
3934 |
|
3935 !!PPOptionalParser methodsFor: ''pp-context'' stamp: ''JanKurs 3/19/2014 15:12''!! |
|
3936 parseOn: aPPContext |
|
3937 | element | |
|
3938 element := parser parseOn: aPPContext. |
|
3939 ^ element isPetitFailure ifFalse: [ element ]!! !! |
|
3940 |
|
3941 |
|
3942 PPDelegateParser subclass: #PPFlattenParser |
|
3943 instanceVariableNames: '''' |
|
3944 classVariableNames: '''' |
|
3945 poolDictionaries: '''' |
|
3946 category: ''PetitParser-Parsers''!! |
|
3947 !!PPFlattenParser commentStamp: ''lr 11/22/2009 13:09'' prior: 0!! |
|
3948 A parser that answers a flat copy of the range my delegate parses.!! |
|
3949 |
|
3950 |
|
3951 !!PPFlattenParser methodsFor: ''private'' stamp: ''lr 2/25/2013 23:31''!! |
|
3952 on: aCollection start: aStartInteger stop: aStopInteger value: anObject |
|
3953 ^ aCollection copyFrom: aStartInteger to: aStopInteger!! !! |
|
3954 |
|
3955 |
|
3956 !!PPFlattenParser methodsFor: ''pp-context'' stamp: ''JanKurs 1/15/2014 15:42''!! |
|
3957 parseOn: aPPContext |
|
3958 | start element | |
|
3959 start := aPPContext stream position. |
|
3960 element := parser parseOn: aPPContext. |
|
3961 element isPetitFailure ifTrue: [ ^ element ]. |
|
3962 ^ self on: aPPContext stream collection start: start + 1 stop: aPPContext stream position value: element!! !! |
|
3963 |
|
3964 |
|
3965 PPFlattenParser subclass: #PPTokenParser |
|
3966 instanceVariableNames: ''tokenClass'' |
|
3967 classVariableNames: '''' |
|
3968 poolDictionaries: '''' |
|
3969 category: ''PetitParser-Parsers''!! |
|
3970 !!PPTokenParser commentStamp: ''lr 2/25/2013 23:31'' prior: 0!! |
|
3971 A parser that answers a token with the value of my delegate parses. |
|
3972 |
|
3973 Instance Variables: |
|
3974 tokenClass <PPToken class> The token sub-class to be used.!! |
|
3975 |
|
3976 |
|
3977 !!PPTokenParser methodsFor: ''private'' stamp: ''lr 4/6/2010 19:18''!! |
|
3978 defaultTokenClass |
|
3979 ^ PPToken!! !! |
|
3980 |
|
3981 !!PPTokenParser methodsFor: ''private'' stamp: ''lr 2/25/2013 23:32''!! |
|
3982 on: aCollection start: aStartInteger stop: aStopInteger value: anObject |
|
3983 ^ self tokenClass on: aCollection start: aStartInteger stop: aStopInteger value: anObject!! !! |
|
3984 |
|
3985 |
|
3986 !!PPTokenParser methodsFor: ''initialization'' stamp: ''lr 4/6/2010 19:19''!! |
|
3987 initialize |
|
3988 tokenClass := self defaultTokenClass |
|
3989 !! !! |
|
3990 |
|
3991 |
|
3992 !!PPTokenParser methodsFor: ''accessing'' stamp: ''lr 4/6/2010 19:23''!! |
|
3993 tokenClass |
|
3994 ^ tokenClass!! !! |
|
3995 |
|
3996 !!PPTokenParser methodsFor: ''accessing'' stamp: ''lr 4/6/2010 19:24''!! |
|
3997 tokenClass: aTokenClass |
|
3998 tokenClass := aTokenClass!! !! |
|
3999 |
|
4000 |
|
4001 !!PPTokenParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 6/18/2010 14:09''!! |
|
4002 match: aParser inContext: aDictionary seen: anIdentitySet |
|
4003 ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self tokenClass = aParser tokenClass ]!! !! |
|
4004 |
|
4005 |
|
4006 PPDelegateParser subclass: #PPRepeatingParser |
|
4007 instanceVariableNames: ''min max'' |
|
4008 classVariableNames: '''' |
|
4009 poolDictionaries: '''' |
|
4010 category: ''PetitParser-Parsers''!! |
|
4011 !!PPRepeatingParser commentStamp: ''lr 4/3/2011 14:45'' prior: 0!! |
|
4012 An abstract parser that repeatedly parses between ''min'' and ''max'' instances of its delegate. The default configuration parses an infinite number of elements, as ''min'' is set to 0 and ''max'' to infinity (SmallInteger maxVal). |
|
4013 |
|
4014 Instance Variables: |
|
4015 min <Integer> The minimum number of repetitions. |
|
4016 max <Integer> The maximum number of repetitions.!! |
|
4017 |
|
4018 |
|
4019 !!PPRepeatingParser methodsFor: ''*petitanalyzer-matching'' stamp: ''lr 6/18/2010 14:09''!! |
|
4020 match: aParser inContext: aDictionary seen: anIdentitySet |
|
4021 ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self min = aParser min and: [ self max = aParser max ] ]!! !! |
|
4022 |
|
4023 |
|
4024 !!PPRepeatingParser methodsFor: ''initialization'' stamp: ''lr 4/1/2011 21:00''!! |
|
4025 setMax: anInteger |
|
4026 max := anInteger!! !! |
|
4027 |
|
4028 !!PPRepeatingParser methodsFor: ''initialization'' stamp: ''lr 4/1/2011 21:01''!! |
|
4029 setMin: anInteger |
|
4030 min := anInteger!! !! |
|
4031 |
|
4032 !!PPRepeatingParser methodsFor: ''initialization'' stamp: ''lr 4/1/2011 21:06''!! |
|
4033 initialize |
|
4034 super initialize. |
|
4035 self setMin: 0; setMax: SmallInteger maxVal!! !! |
|
4036 |
|
4037 |
|
4038 !!PPRepeatingParser methodsFor: ''accessing'' stamp: ''lr 4/30/2010 11:08''!! |
|
4039 max |
|
4040 "Answer the maximum number of repetitions." |
|
4041 |
|
4042 ^ max!! !! |
|
4043 |
|
4044 !!PPRepeatingParser methodsFor: ''accessing'' stamp: ''lr 4/30/2010 11:08''!! |
|
4045 min |
|
4046 "Answer the minimum number of repetitions." |
|
4047 |
|
4048 ^ min!! !! |
|
4049 |
|
4050 |
|
4051 !!PPRepeatingParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/11/2009 20:57''!! |
|
4052 exampleOn: aStream |
|
4053 "Perform the minimal repeatitions required, and a random amount of more if possible and if not that much output has been produced yet." |
|
4054 |
|
4055 min timesRepeat: [ |
|
4056 super exampleOn: aStream ]. |
|
4057 (max - min min: 5) atRandom timesRepeat: [ |
|
4058 aStream position > 512 |
|
4059 ifTrue: [ ^ self ]. |
|
4060 super exampleOn: aStream ]!! !! |
|
4061 |
|
4062 !!PPRepeatingParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/13/2009 14:18''!! |
|
4063 displayDescription |
|
4064 ^ String streamContents: [ :stream | |
|
4065 min = 0 |
|
4066 ifFalse: [ stream print: min; nextPutAll: ''..'' ]. |
|
4067 max = SmallInteger maxVal |
|
4068 ifTrue: [ stream nextPut: $* ] |
|
4069 ifFalse: [ stream print: max ] ]!! !! |
|
4070 |
|
4071 |
|
4072 !!PPRepeatingParser methodsFor: ''*petitanalyzer-testing'' stamp: ''lr 10/21/2009 12:13''!! |
|
4073 isNullable |
|
4074 ^ min = 0!! !! |
|
4075 |
|
4076 |
|
4077 !!PPRepeatingParser methodsFor: ''*petitanalyzer-private'' stamp: ''JanKurs 5/31/2013 11:51''!! |
|
4078 followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet |
|
4079 | firstSet | |
|
4080 super followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet. |
|
4081 |
|
4082 firstSet := aFirstDictionary at: self. |
|
4083 self children do: [:p | (aFollowDictionary at: p) addAll: (firstSet reject: [:each | each isNullable]) ]!! !! |
|
4084 |
|
4085 |
|
4086 !!PPRepeatingParser methodsFor: ''*petitgui-mondrian'' stamp: ''AlexandreBergel 12/18/2013 16:44''!! |
|
4087 visualizationGraphType |
|
4088 ^ ''*''!! !! |
|
4089 |
|
4090 |
|
4091 !!PPRepeatingParser methodsFor: ''printing'' stamp: ''lr 6/3/2010 14:00''!! |
|
4092 printOn: aStream |
|
4093 super printOn: aStream. |
|
4094 aStream nextPutAll: '' [''; print: min; nextPutAll: '', ''; nextPutAll: (max = SmallInteger maxVal |
|
4095 ifTrue: [ ''*'' ] ifFalse: [ max printString ]); nextPut: $]!! !! |
|
4096 |
|
4097 |
|
4098 PPRepeatingParser subclass: #PPPossessiveRepeatingParser |
|
4099 instanceVariableNames: '''' |
|
4100 classVariableNames: '''' |
|
4101 poolDictionaries: '''' |
|
4102 category: ''PetitParser-Parsers''!! |
|
4103 !!PPPossessiveRepeatingParser commentStamp: ''lr 4/3/2011 14:35'' prior: 0!! |
|
4104 The default repeating parser with standard PEG semantics (i.e. possessive, blind, eager).!! |
|
4105 |
|
4106 |
|
4107 !!PPPossessiveRepeatingParser methodsFor: ''pp-context'' stamp: ''JanKurs 1/15/2014 15:43''!! |
|
4108 parseOn: aPPContext |
|
4109 | start element elements | |
|
4110 start := aPPContext remember. |
|
4111 elements := OrderedCollection new. |
|
4112 [ elements size < min ] whileTrue: [ |
|
4113 (element := parser parseOn: aPPContext) isPetitFailure ifTrue: [ |
|
4114 aPPContext restore: start. |
|
4115 ^ element ]. |
|
4116 elements addLast: element ]. |
|
4117 [ elements size < max ] whileTrue: [ |
|
4118 (element := parser parseOn: aPPContext) isPetitFailure |
|
4119 ifTrue: [ ^ elements asArray ]. |
|
4120 elements addLast: element ]. |
|
4121 ^ elements asArray!! !! |
|
4122 |
|
4123 |
|
4124 PPRepeatingParser subclass: #PPLimitedRepeatingParser |
|
4125 instanceVariableNames: ''limit'' |
|
4126 classVariableNames: '''' |
|
4127 poolDictionaries: '''' |
|
4128 category: ''PetitParser-Parsers''!! |
|
4129 !!PPLimitedRepeatingParser commentStamp: ''lr 4/3/2011 14:37'' prior: 0!! |
|
4130 An abstract parser that repeatedly parses between ''min'' and ''max'' instances of my delegate and that requires the input to be completed with a specified parser ''limit''. Subclasses provide repeating behavior as typically seen in regular expression implementations (non-blind). |
|
4131 |
|
4132 Instance Variables: |
|
4133 limit <PPParser> The parser to complete the input with.!! |
|
4134 |
|
4135 |
|
4136 !!PPLimitedRepeatingParser methodsFor: ''*petitanalyzer-transforming'' stamp: ''lr 4/4/2011 18:46''!! |
|
4137 replace: aParser with: anotherParser |
|
4138 super replace: aParser with: anotherParser. |
|
4139 limit == aParser ifTrue: [ limit := anotherParser ]!! !! |
|
4140 |
|
4141 |
|
4142 !!PPLimitedRepeatingParser methodsFor: ''initialization'' stamp: ''lr 4/2/2011 10:00''!! |
|
4143 setLimit: aParser |
|
4144 limit := aParser!! !! |
|
4145 |
|
4146 |
|
4147 !!PPLimitedRepeatingParser methodsFor: ''accessing'' stamp: ''lr 4/4/2011 18:46''!! |
|
4148 children |
|
4149 ^ Array with: parser with: limit!! !! |
|
4150 |
|
4151 !!PPLimitedRepeatingParser methodsFor: ''accessing'' stamp: ''lr 4/2/2011 10:00''!! |
|
4152 limit |
|
4153 "Answer the parser that limits (or ends) this repetition." |
|
4154 |
|
4155 ^ limit!! !! |
|
4156 |
|
4157 |
|
4158 !!PPLimitedRepeatingParser methodsFor: ''pp-context'' stamp: ''JanKurs 1/15/2014 16:04''!! |
|
4159 matchesLimitOn: aPPContext |
|
4160 | element position | |
|
4161 position := aPPContext remember. |
|
4162 element := limit parseOn: aPPContext. |
|
4163 aPPContext restore: position. |
|
4164 ^ element isPetitFailure not!! !! |
|
4165 |
|
4166 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
4167 |
|
4168 PPLimitedRepeatingParser class |
|
4169 instanceVariableNames: ''''!! |
|
4170 !!PPLimitedRepeatingParser class commentStamp: ''<historical>'' prior: 0!! |
|
4171 !! |
|
4172 |
|
4173 |
|
4174 !!PPLimitedRepeatingParser class methodsFor: ''instance creation'' stamp: ''lr 4/3/2011 14:58''!! |
|
4175 on: aParser limit: aLimitParser |
|
4176 ^ (self on: aParser) setLimit: aLimitParser!! !! |
|
4177 |
|
4178 |
|
4179 PPLimitedRepeatingParser subclass: #PPGreedyRepeatingParser |
|
4180 instanceVariableNames: '''' |
|
4181 classVariableNames: '''' |
|
4182 poolDictionaries: '''' |
|
4183 category: ''PetitParser-Parsers''!! |
|
4184 !!PPGreedyRepeatingParser commentStamp: ''lr 4/3/2011 15:08'' prior: 0!! |
|
4185 A greedy repeating parser, commonly seen in regular expression implementations. It aggressively consumes as much input as possible and then backtracks to meet the ''limit'' condition. |
|
4186 |
|
4187 This class essentially implements the iterative version of the following recursive parser composition: |
|
4188 |
|
4189 | parser | |
|
4190 parser := PPChoiceParser new. |
|
4191 parser setParsers: (Array |
|
4192 with: (self , parser map: [ :each :rest | rest addFirst: each; yourself ]) |
|
4193 with: (limit and ==> [ :each | OrderedCollection new ])). |
|
4194 ^ parser ==> [ :rest | rest asArray ]!! |
|
4195 |
|
4196 |
|
4197 !!PPGreedyRepeatingParser methodsFor: ''pp-context'' stamp: ''JanKurs 8/19/2014 16:59''!! |
|
4198 parseOn: aPPContext |
|
4199 | start element elements positions | |
|
4200 start := aPPContext remember. |
|
4201 elements := OrderedCollection new. |
|
4202 [ elements size < min ] whileTrue: [ |
|
4203 (element := parser parseOn: aPPContext) isPetitFailure ifTrue: [ |
|
4204 aPPContext restore: start. |
|
4205 ^ element ]. |
|
4206 elements addLast: element ]. |
|
4207 positions := OrderedCollection with: aPPContext remember. |
|
4208 [ elements size < max and: [ (element := parser parseOn: aPPContext) isPetitFailure not ] ] whileTrue: [ |
|
4209 elements addLast: element. |
|
4210 positions addLast: aPPContext remember ]. |
|
4211 [ positions isEmpty ] whileFalse: [ |
|
4212 aPPContext restore: positions last. |
|
4213 element := limit parseOn: aPPContext. |
|
4214 element isPetitFailure ifFalse: [ |
|
4215 aPPContext restore: positions last. |
|
4216 ^ elements asArray ]. |
|
4217 elements isEmpty ifTrue: [ |
|
4218 aPPContext restore: start. |
|
4219 ^ element ]. |
|
4220 elements removeLast. |
|
4221 positions removeLast ]. |
|
4222 aPPContext restore: start. |
|
4223 ^ PPFailure message: ''overflow'' context: aPPContext at: start!! !! |
|
4224 |
|
4225 |
|
4226 PPParser subclass: #PPEpsilonParser |
|
4227 instanceVariableNames: '''' |
|
4228 classVariableNames: '''' |
|
4229 poolDictionaries: '''' |
|
4230 category: ''PetitParser-Parsers''!! |
|
4231 !!PPEpsilonParser commentStamp: ''lr 5/15/2008 15:09'' prior: 0!! |
|
4232 A parser that consumes nothing and always succeeds.!! |
|
4233 |
|
4234 |
|
4235 !!PPEpsilonParser methodsFor: ''*petitanalyzer-testing'' stamp: ''lr 10/21/2009 12:11''!! |
|
4236 isNullable |
|
4237 ^ true!! !! |
|
4238 |
|
4239 |
|
4240 !!PPEpsilonParser methodsFor: ''*petitgui-morphic'' stamp: ''lr 11/18/2009 11:15''!! |
|
4241 morphicShapeSeen: aSet depth: anInteger |
|
4242 ^ self morphicShapeSeen: aSet depth: anInteger do: [ :cc | |
|
4243 self newRowMorph |
|
4244 addMorphBack: (self newColumnMorph |
|
4245 addMorphBack: (self newSpacerMorph height: 10); |
|
4246 addMorphBack: (LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1); |
|
4247 yourself); |
|
4248 yourself ]!! !! |
|
4249 |
|
4250 |
|
4251 !!PPEpsilonParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/6/2009 18:42''!! |
|
4252 displayName |
|
4253 ^ ''epsilon''!! !! |
|
4254 |
|
4255 |
|
4256 !!PPEpsilonParser methodsFor: ''parsing'' stamp: ''lr 2/7/2010 20:49''!! |
|
4257 parseOn: aStream |
|
4258 ^ nil!! !! |
|
4259 |
|
4260 |
|
4261 PPLimitedRepeatingParser subclass: #PPLazyRepeatingParser |
|
4262 instanceVariableNames: '''' |
|
4263 classVariableNames: '''' |
|
4264 poolDictionaries: '''' |
|
4265 category: ''PetitParser-Parsers''!! |
|
4266 !!PPLazyRepeatingParser commentStamp: ''lr 4/3/2011 15:08'' prior: 0!! |
|
4267 A lazy repeating parser, commonly seen in regular expression implementations. It limits its consumption to meet the ''limit'' condition as early as possible. |
|
4268 |
|
4269 This class essentially implements the iterative version of the following recursive parser composition: |
|
4270 |
|
4271 | parser | |
|
4272 parser := PPChoiceParser new. |
|
4273 parser setParsers: (Array |
|
4274 with: (limit and ==> [ :each | OrderedCollection new ]) |
|
4275 with: (self , parser map: [ :each :rest | rest addFirst: each; yourself ])). |
|
4276 ^ parser ==> [ :rest | rest asArray ]!! |
|
4277 |
|
4278 |
|
4279 !!PPLazyRepeatingParser methodsFor: ''pp-context'' stamp: ''JanKurs 8/19/2014 17:00''!! |
|
4280 parseOn: aPPContext |
|
4281 | start element elements | |
|
4282 start := aPPContext remember. |
|
4283 elements := OrderedCollection new. |
|
4284 [ elements size < min ] whileTrue: [ |
|
4285 (element := parser parseOn: aPPContext) isPetitFailure ifTrue: [ |
|
4286 aPPContext restore: start. |
|
4287 ^ element ]. |
|
4288 elements addLast: element ]. |
|
4289 [ self matchesLimitOn: aPPContext ] whileFalse: [ |
|
4290 elements size < max ifFalse: [ |
|
4291 aPPContext restore: start. |
|
4292 ^ PPFailure message: ''overflow'' context: aPPContext at: start ]. |
|
4293 element := parser parseOn: aPPContext. |
|
4294 element isPetitFailure ifTrue: [ |
|
4295 aPPContext restore: start. |
|
4296 ^ element ]. |
|
4297 elements addLast: element ]. |
|
4298 ^ elements asArray!! !! |
|
4299 |
|
4300 |
|
4301 PPListParser subclass: #PPSequenceParser |
|
4302 instanceVariableNames: '''' |
|
4303 classVariableNames: '''' |
|
4304 poolDictionaries: '''' |
|
4305 category: ''PetitParser-Parsers''!! |
|
4306 !!PPSequenceParser commentStamp: ''lr 4/18/2008 15:34'' prior: 0!! |
|
4307 A parser that parses a sequence of parsers.!! |
|
4308 |
|
4309 |
|
4310 !!PPSequenceParser methodsFor: ''operators-mapping'' stamp: ''lr 5/6/2011 20:27''!! |
|
4311 map: aBlock |
|
4312 ^ aBlock numArgs = self children size |
|
4313 ifTrue: [ self ==> [ :nodes | aBlock valueWithArguments: nodes ] ] |
|
4314 ifFalse: [ self error: aBlock numArgs asString , '' arguments expected.'' ]!! !! |
|
4315 |
|
4316 !!PPSequenceParser methodsFor: ''operators-mapping'' stamp: ''lr 1/8/2010 12:01''!! |
|
4317 permutation: anArrayOfIntegers |
|
4318 "Answer a permutation of the receivers sequence." |
|
4319 |
|
4320 anArrayOfIntegers do: [ :index | |
|
4321 (index isInteger and: [ index between: 1 and: parsers size ]) |
|
4322 ifFalse: [ self error: ''Invalid permutation index: '' , index printString ] ]. |
|
4323 ^ self ==> [ :nodes | anArrayOfIntegers collect: [ :index | nodes at: index ] ]!! !! |
|
4324 |
|
4325 |
|
4326 !!PPSequenceParser methodsFor: ''*petitgui-morphic'' stamp: ''lr 11/17/2009 21:54''!! |
|
4327 morphicShapeSeen: aSet depth: anInteger |
|
4328 ^ self morphicShapeSeen: aSet depth: anInteger do: [ :cc | |
|
4329 self children |
|
4330 inject: self newRowMorph |
|
4331 into: [ :result :each | |
|
4332 result |
|
4333 addMorphBack: (cc value: each); |
|
4334 yourself ] ]!! !! |
|
4335 |
|
4336 |
|
4337 !!PPSequenceParser methodsFor: ''*petitgui-accessing'' stamp: ''lr 11/9/2009 14:24''!! |
|
4338 exampleOn: aStream |
|
4339 parsers do: [ :each | each exampleOn: aStream ]!! !! |
|
4340 |
|
4341 |
|
4342 !!PPSequenceParser methodsFor: ''pp-context'' stamp: ''JanKurs 11/11/2013 09:43''!! |
|
4343 parseOn: aPPContext |
|
4344 "This is optimized code that avoids unnecessary block activations, do not change." |
|
4345 |
|
4346 | start elements element | |
|
4347 start := aPPContext remember. |
|
4348 elements := Array new: parsers size. |
|
4349 1 to: parsers size do: [ :index | |
|
4350 element := (parsers at: index) |
|
4351 parseOn: aPPContext. |
|
4352 element isPetitFailure ifTrue: [ |
|
4353 aPPContext restore: start. |
|
4354 ^ element ]. |
|
4355 elements at: index put: element ]. |
|
4356 ^ elements!! !! |
|
4357 |
|
4358 |
|
4359 !!PPSequenceParser methodsFor: ''operators'' stamp: ''lr 9/17/2008 00:17''!! |
|
4360 , aRule |
|
4361 ^ self copyWith: aRule!! !! |
|
4362 |
|
4363 |
|
4364 !!PPSequenceParser methodsFor: ''*petitanalyzer-private'' stamp: ''lr 12/9/2010 10:37''!! |
|
4365 cycleSet: aDictionary |
|
4366 | firstSet | |
|
4367 1 to: parsers size do: [ :index | |
|
4368 firstSet := aDictionary at: (parsers at: index). |
|
4369 (firstSet anySatisfy: [ :each | each isNullable ]) |
|
4370 ifFalse: [ ^ parsers copyFrom: 1 to: index ] ]. |
|
4371 ^ parsers!! !! |
|
4372 |
|
4373 !!PPSequenceParser methodsFor: ''*petitanalyzer-private'' stamp: ''lr 9/16/2010 17:56''!! |
|
4374 firstSets: aFirstDictionary into: aSet |
|
4375 | nullable | |
|
4376 parsers do: [ :parser | |
|
4377 nullable := false. |
|
4378 (aFirstDictionary at: parser) do: [ :each | |
|
4379 each isNullable |
|
4380 ifTrue: [ nullable := true ] |
|
4381 ifFalse: [ aSet add: each ] ]. |
|
4382 nullable |
|
4383 ifFalse: [ ^ self ] ]. |
|
4384 aSet add: PPSentinel instance!! !! |
|
4385 |
|
4386 !!PPSequenceParser methodsFor: ''*petitanalyzer-private'' stamp: ''lr 8/14/2010 13:51''!! |
|
4387 followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet |
|
4388 parsers keysAndValuesDo: [ :index :parser | |
|
4389 | followSet firstSet | |
|
4390 followSet := aFollowDictionary at: parser. |
|
4391 index = parsers size |
|
4392 ifTrue: [ followSet addAll: aSet ] |
|
4393 ifFalse: [ |
|
4394 (self class withAll: (parsers |
|
4395 copyFrom: index + 1 to: parsers size)) |
|
4396 firstSets: aFirstDictionary |
|
4397 into: (firstSet := IdentitySet new). |
|
4398 (firstSet anySatisfy: [ :each | each isNullable ]) |
|
4399 ifTrue: [ followSet addAll: aSet ]. |
|
4400 followSet addAll: (firstSet |
|
4401 reject: [ :each | each isNullable ]) ] ]!! !! |
|
4402 |
|
4403 |
|
4404 !!PPSequenceParser methodsFor: ''*petitgui-mondrian'' stamp: ''AlexandreBergel 12/18/2013 16:44''!! |
|
4405 visualizationGraphType |
|
4406 ^ '',''!! !! |
|
4407 Object subclass: #PPFailure |
|
4408 instanceVariableNames: ''message context position'' |
|
4409 classVariableNames: '''' |
|
4410 poolDictionaries: '''' |
|
4411 category: ''PetitParser-Core''!! |
|
4412 !!PPFailure commentStamp: ''<historical>'' prior: 0!! |
|
4413 The failure object in PetitParser. It is the only class that responds to #isPetitFailure with true. It contains an error message and a position of the occurrence of the failure. |
|
4414 |
|
4415 Instance Variables: |
|
4416 message <String> The error message of this failure. |
|
4417 position <Integer> The position of this failure in the input stream. |
|
4418 !! |
|
4419 |
|
4420 |
|
4421 !!PPFailure methodsFor: ''*petitgui'' stamp: ''JanKurs 8/19/2014 16:39''!! |
|
4422 sampleIn: composite |
|
4423 |
|
4424 (composite text) |
|
4425 title: ''Sample''; |
|
4426 display: [:res | res findStream contents ifNil: [''''] ]; |
|
4427 allowNil.!! !! |
|
4428 |
|
4429 !!PPFailure methodsFor: ''*petitgui'' stamp: ''JanKurs 8/19/2014 16:40''!! |
|
4430 treeViewIn: composite |
|
4431 composite tree |
|
4432 title: ''Execution Traces''; |
|
4433 format: [:resultNode | resultNode formattedText ]; |
|
4434 children: [:resultNode | resultNode showChildren |
|
4435 ifTrue: [ resultNode children ] |
|
4436 ifFalse: [ #() ] ]. !! !! |
|
4437 |
|
4438 !!PPFailure methodsFor: ''*petitgui'' stamp: ''JanKurs 8/19/2014 16:53''!! |
|
4439 gtDebugView: composite |
|
4440 <gtInspectorPresentationOrder: 40> |
|
4441 |
|
4442 | browser | |
|
4443 browser := |
|
4444 composite tabulator. |
|
4445 |
|
4446 browser title: ''Debug View''. |
|
4447 browser row: #tree; |
|
4448 row: #source. |
|
4449 browser transmit |
|
4450 fromOutsideEntityPort; |
|
4451 toOutsidePort: #debugResult; |
|
4452 transformed: [ :failure | failure debugResult ]. |
|
4453 |
|
4454 browser transmit |
|
4455 from: #tree; |
|
4456 to: #source port: #selectionInterval; |
|
4457 transformed: [:debuggingResult | |
|
4458 debuggingResult ifNotNil: [ |
|
4459 debuggingResult start to: debuggingResult end] |
|
4460 ]. |
|
4461 |
|
4462 browser transmit |
|
4463 fromOutsidePort: #debugResult; |
|
4464 to: #source; |
|
4465 andShow: [ :a | self sampleIn: a ]. |
|
4466 |
|
4467 browser transmit |
|
4468 fromOutsidePort: #debugResult; |
|
4469 to: #tree; |
|
4470 andShow: [ :a | self treeViewIn: a ]. |
|
4471 |
|
4472 browser startOn: self!! !! |
|
4473 |
|
4474 !!PPFailure methodsFor: ''*petitgui'' stamp: ''JanKurs 8/19/2014 16:54''!! |
|
4475 debugResult |
|
4476 ^ context root enableDebug parse: context stream reset!! !! |
|
4477 |
|
4478 |
|
4479 !!PPFailure methodsFor: ''testing'' stamp: ''lr 2/7/2010 20:54''!! |
|
4480 isPetitFailure |
|
4481 "I am the only class that should implement this method to return true." |
|
4482 |
|
4483 ^ true!! !! |
|
4484 |
|
4485 |
|
4486 !!PPFailure methodsFor: ''printing'' stamp: ''JanKurs 8/19/2014 16:30''!! |
|
4487 printOn: aStream |
|
4488 aStream nextPutAll: self message; nextPutAll: '' at ''; print: self position!! !! |
|
4489 |
|
4490 |
|
4491 !!PPFailure methodsFor: ''initialization'' stamp: ''JanKurs 8/19/2014 16:57''!! |
|
4492 initializeMessage: aString context: aPPContext |
|
4493 self initializeMessage: aString context: aPPContext position: aPPContext position!! !! |
|
4494 |
|
4495 !!PPFailure methodsFor: ''initialization'' stamp: ''JanKurs 8/19/2014 16:33''!! |
|
4496 initializeMessage: aString at: anInteger |
|
4497 self halt: ''deprecated''.!! !! |
|
4498 |
|
4499 !!PPFailure methodsFor: ''initialization'' stamp: ''JanKurs 8/19/2014 16:57''!! |
|
4500 initializeMessage: aString context: aPPContext position: position |
|
4501 message := aString. |
|
4502 context := aPPContext. |
|
4503 position := position.!! !! |
|
4504 |
|
4505 |
|
4506 !!PPFailure methodsFor: ''accessing'' stamp: ''lr 5/5/2010 13:56''!! |
|
4507 message |
|
4508 "Answer a human readable error message of this parse failure." |
|
4509 |
|
4510 ^ message!! !! |
|
4511 |
|
4512 !!PPFailure methodsFor: ''accessing'' stamp: ''lr 5/5/2010 13:55''!! |
|
4513 position |
|
4514 "Answer the position in the source string that caused this parse failure." |
|
4515 |
|
4516 ^ position!! !! |
|
4517 |
|
4518 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
4519 |
|
4520 PPFailure class |
|
4521 instanceVariableNames: ''''!! |
|
4522 !!PPFailure class commentStamp: ''<historical>'' prior: 0!! |
|
4523 !! |
|
4524 |
|
4525 |
|
4526 !!PPFailure class methodsFor: ''instance creation'' stamp: ''JanKurs 8/19/2014 16:33''!! |
|
4527 message: aString at: anInteger |
|
4528 self halt: ''deprecated, use message:context:''. |
|
4529 ^ self basicNew initializeMessage: aString at: anInteger!! !! |
|
4530 |
|
4531 !!PPFailure class methodsFor: ''instance creation'' stamp: ''JanKurs 8/19/2014 16:32''!! |
|
4532 message: aString context: aPPContext |
|
4533 ^ self basicNew initializeMessage: aString context: aPPContext!! !! |
|
4534 |
|
4535 !!PPFailure class methodsFor: ''instance creation'' stamp: ''JanKurs 8/19/2014 16:57''!! |
|
4536 message: aString context: aPPContext at: position |
|
4537 ^ self basicNew initializeMessage: aString context: aPPContext position: position!! !! |
|
4538 |
|
4539 |
|
4540 ReadStream subclass: #PPStream |
|
4541 instanceVariableNames: '''' |
|
4542 classVariableNames: '''' |
|
4543 poolDictionaries: '''' |
|
4544 category: ''PetitParser-Core''!! |
|
4545 !!PPStream commentStamp: ''<historical>'' prior: 0!! |
|
4546 A positional stream implementation used for parsing. It overrides some methods for optimization reasons.!! |
|
4547 |
|
4548 |
|
4549 !!PPStream methodsFor: ''accessing'' stamp: ''lr 4/29/2008 21:48''!! |
|
4550 peek |
|
4551 "An improved version of peek, that is slightly faster than the built in version." |
|
4552 |
|
4553 ^ self atEnd ifFalse: [ collection at: position + 1 ]!! !! |
|
4554 |
|
4555 !!PPStream methodsFor: ''accessing'' stamp: ''lr 10/5/2010 16:29''!! |
|
4556 uncheckedPeek |
|
4557 "An unchecked version of peek that throws an error if we try to peek over the end of the stream, even faster than #peek." |
|
4558 |
|
4559 ^ collection at: position + 1!! !! |
|
4560 |
|
4561 !!PPStream methodsFor: ''accessing'' stamp: ''lr 2/13/2012 20:25''!! |
|
4562 collection |
|
4563 "Answer the underlying collection." |
|
4564 |
|
4565 ^ collection!! !! |
|
4566 |
|
4567 !!PPStream methodsFor: ''accessing'' stamp: ''lr 8/25/2010 11:36''!! |
|
4568 position: anInteger |
|
4569 "The receiver does not check for invalid arguments passed to this method, as it is solely used with valid indexes for backtracking." |
|
4570 |
|
4571 position := anInteger!! !! |
|
4572 |
|
4573 |
|
4574 !!PPStream methodsFor: ''printing'' stamp: ''lr 11/4/2010 19:23''!! |
|
4575 printOn: aStream |
|
4576 collection isString |
|
4577 ifFalse: [ ^ super printOn: aStream ]. |
|
4578 aStream |
|
4579 nextPutAll: (collection copyFrom: 1 to: position); |
|
4580 nextPutAll: ''·''; |
|
4581 nextPutAll: (collection copyFrom: position + 1 to: readLimit)!! !! |
|
4582 |
|
4583 |
|
4584 !!PPStream methodsFor: ''converting'' stamp: ''lr 2/7/2010 20:53''!! |
|
4585 asPetitStream |
|
4586 ^ self!! !! |
|
4587 |
|
4588 |
|
4589 Object subclass: #PPToken |
|
4590 instanceVariableNames: ''collection start stop value'' |
|
4591 classVariableNames: ''NewLineParser'' |
|
4592 poolDictionaries: '''' |
|
4593 category: ''PetitParser-Core''!! |
|
4594 !!PPToken commentStamp: ''lr 2/25/2013 23:34'' prior: 0!! |
|
4595 PPToken represents a parsed part of the input stream. Contrary to a simple String it remembers where it came from, the original collection, its start and stop position and its parse value. |
|
4596 |
|
4597 Instance Variables: |
|
4598 collection <SequenceableCollection> The collection this token comes from. |
|
4599 start <Integer> The start position in the collection. |
|
4600 stop <Integer> The stop position in the collection. |
|
4601 value <Object> The parse result.!! |
|
4602 |
|
4603 |
|
4604 !!PPToken methodsFor: ''querying'' stamp: ''lr 9/7/2011 20:41''!! |
|
4605 line |
|
4606 "Answer the line number of this token in the underlying collection." |
|
4607 |
|
4608 | line | |
|
4609 line := 1. |
|
4610 (NewLineParser , [ :stream | |
|
4611 start <= stream position |
|
4612 ifTrue: [ ^ line ]. |
|
4613 line := line + 1 ] asParser |
|
4614 / #any asParser) star |
|
4615 parse: collection. |
|
4616 ^ line!! !! |
|
4617 |
|
4618 !!PPToken methodsFor: ''querying'' stamp: ''lr 9/7/2011 20:40''!! |
|
4619 column |
|
4620 "Answer the column number of this token in the underlying collection." |
|
4621 |
|
4622 | position | |
|
4623 position := 0. |
|
4624 (NewLineParser , [ :stream | |
|
4625 start <= stream position |
|
4626 ifTrue: [ ^ start - position ]. |
|
4627 position := stream position ] asParser |
|
4628 / #any asParser) star |
|
4629 parse: collection. |
|
4630 ^ start - position!! !! |
|
4631 |
|
4632 |
|
4633 !!PPToken methodsFor: ''initialization'' stamp: ''lr 2/25/2013 23:36''!! |
|
4634 initializeOn: aSequenceableCollection start: aStartInteger stop: aStopInteger value: anObject |
|
4635 collection := aSequenceableCollection. |
|
4636 start := aStartInteger. |
|
4637 stop := aStopInteger. |
|
4638 value := anObject!! !! |
|
4639 |
|
4640 |
|
4641 !!PPToken methodsFor: ''accessing'' stamp: ''lr 6/15/2010 23:33''!! |
|
4642 stop |
|
4643 "Answer the stop position of this token in the underlying collection." |
|
4644 |
|
4645 ^ stop!! !! |
|
4646 |
|
4647 !!PPToken methodsFor: ''accessing'' stamp: ''lr 2/25/2013 23:56''!! |
|
4648 size |
|
4649 "Answer the size of this token in the underlying collection." |
|
4650 |
|
4651 ^ stop - start + 1!! !! |
|
4652 |
|
4653 !!PPToken methodsFor: ''accessing'' stamp: ''lr 6/15/2010 23:34''!! |
|
4654 collection |
|
4655 "Answer the underlying collection of this token." |
|
4656 |
|
4657 ^ collection!! !! |
|
4658 |
|
4659 !!PPToken methodsFor: ''accessing'' stamp: ''lr 6/15/2010 23:33''!! |
|
4660 start |
|
4661 "Answer the start position of this token in the underlying collection." |
|
4662 |
|
4663 ^ start!! !! |
|
4664 |
|
4665 |
|
4666 !!PPToken methodsFor: ''printing'' stamp: ''lr 2/26/2013 00:37''!! |
|
4667 printOn: aStream |
|
4668 super printOn: aStream. |
|
4669 aStream nextPut: $[; print: self start; nextPut: $,; print: self stop; nextPut: $]. |
|
4670 aStream nextPut: $(; print: self parsedValue; nextPut: $)!! !! |
|
4671 |
|
4672 |
|
4673 !!PPToken methodsFor: ''copying'' stamp: ''lr 2/26/2013 00:34''!! |
|
4674 copyFrom: aStartInteger to: aStopInteger |
|
4675 ^ self class on: collection start: start + aStartInteger - 1 stop: stop + aStopInteger - 3 value: value!! !! |
|
4676 |
|
4677 |
|
4678 !!PPToken methodsFor: ''accessing-values'' stamp: ''lr 2/26/2013 00:34''!! |
|
4679 value |
|
4680 self notify: ''Token>>#value is no longer supported. Instead use Token>>#inputValue or the more pragmatic #parsedValue.''. |
|
4681 ^ self inputValue!! !! |
|
4682 |
|
4683 !!PPToken methodsFor: ''accessing-values'' stamp: ''lr 2/26/2013 00:32''!! |
|
4684 inputValue |
|
4685 "Answer the consumed input of this token." |
|
4686 |
|
4687 ^ collection copyFrom: start to: stop!! !! |
|
4688 |
|
4689 !!PPToken methodsFor: ''accessing-values'' stamp: ''lr 2/26/2013 00:32''!! |
|
4690 parsedValue |
|
4691 "Answer the parsed value of this token." |
|
4692 |
|
4693 ^ value!! !! |
|
4694 |
|
4695 |
|
4696 !!PPToken methodsFor: ''comparing'' stamp: ''lr 2/26/2013 00:34''!! |
|
4697 = anObject |
|
4698 ^ self class = anObject class and: [ self parsedValue = anObject parsedValue ]!! !! |
|
4699 |
|
4700 !!PPToken methodsFor: ''comparing'' stamp: ''lr 2/26/2013 00:34''!! |
|
4701 hash |
|
4702 ^ self parsedValue hash!! !! |
|
4703 |
|
4704 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
4705 |
|
4706 PPToken class |
|
4707 instanceVariableNames: ''''!! |
|
4708 !!PPToken class commentStamp: ''<historical>'' prior: 0!! |
|
4709 !! |
|
4710 |
|
4711 |
|
4712 !!PPToken class methodsFor: ''initialization'' stamp: ''lr 11/29/2011 20:42''!! |
|
4713 initialize |
|
4714 "Platform independent newline sequence. LF: Unix, CR+LF: Windows, and CR: Apple." |
|
4715 |
|
4716 NewLineParser := (Character lf asParser) / (Character cr asParser , Character lf asParser optional)!! !! |
|
4717 |
|
4718 |
|
4719 !!PPToken class methodsFor: ''instance creation'' stamp: ''lr 2/25/2013 23:39''!! |
|
4720 on: aSequenceableCollection start: aStartInteger stop: aStopInteger value: anObject |
|
4721 ^ self basicNew |
|
4722 initializeOn: aSequenceableCollection |
|
4723 start: aStartInteger stop: aStopInteger |
|
4724 value: anObject!! !! |
|
4725 |
|
4726 !!PPToken class methodsFor: ''instance creation'' stamp: ''lr 2/25/2013 23:36''!! |
|
4727 on: aSequenceableCollection |
|
4728 ^ self on: aSequenceableCollection start: 1 stop: aSequenceableCollection size value: nil!! !! |
|
4729 |
|
4730 !!PPToken class methodsFor: ''instance creation'' stamp: ''lr 4/6/2010 20:58''!! |
|
4731 new |
|
4732 self error: ''Token can only be created using a dedicated constructor.''!! !! |
|
4733 |
|
4734 |
|
4735 Object subclass: #PPContextMemento |
|
4736 instanceVariableNames: ''stream position properties'' |
|
4737 classVariableNames: '''' |
|
4738 poolDictionaries: '''' |
|
4739 category: ''PetitParser-Core''!! |
|
4740 !!PPContextMemento commentStamp: ''<historical>'' prior: 0!! |
|
4741 !! |
|
4742 |
|
4743 |
|
4744 !!PPContextMemento methodsFor: ''comparing'' stamp: ''JanKurs 3/19/2014 13:03''!! |
|
4745 = anObject |
|
4746 |
|
4747 (self == anObject) ifTrue: [ ^ true ]. |
|
4748 (anObject class = PPContextMemento) ifFalse: [ ^ false ]. |
|
4749 |
|
4750 (anObject stream == stream) ifFalse: [ ^ false ]. |
|
4751 (anObject position = position) ifFalse: [ ^ false ]. |
|
4752 (anObject properties = properties) ifFalse: [ ^ false ]. |
|
4753 |
|
4754 ^ true. |
|
4755 !! !! |
|
4756 |
|
4757 !!PPContextMemento methodsFor: ''comparing'' stamp: ''JanKurs 3/19/2014 13:04''!! |
|
4758 hash |
|
4759 ^ (position hash bitXor: stream hash) bitXor: properties hash.!! !! |
|
4760 |
|
4761 |
|
4762 !!PPContextMemento methodsFor: ''accessing - properties'' stamp: ''JanKurs 3/19/2014 12:15''!! |
|
4763 propertyAt: aKey ifAbsentPut: aBlock |
|
4764 "Answer the property associated with aKey or, if aKey isn''t found store the result of evaluating aBlock as new value." |
|
4765 |
|
4766 ^ self propertyAt: aKey ifAbsent: [ self propertyAt: aKey put: aBlock value ]!! !! |
|
4767 |
|
4768 !!PPContextMemento methodsFor: ''accessing - properties'' stamp: ''JanKurs 3/19/2014 12:15''!! |
|
4769 removeProperty: aKey ifAbsent: aBlock |
|
4770 "Remove the property with aKey. Answer the value or, if aKey isn''t found, answer the result of evaluating aBlock." |
|
4771 |
|
4772 | answer | |
|
4773 properties isNil ifTrue: [ ^ aBlock value ]. |
|
4774 answer := properties removeKey: aKey ifAbsent: aBlock. |
|
4775 properties isEmpty ifTrue: [ properties := nil ]. |
|
4776 ^ answer!! !! |
|
4777 |
|
4778 !!PPContextMemento methodsFor: ''accessing - properties'' stamp: ''JanKurs 3/19/2014 12:14''!! |
|
4779 propertyAt: aKey |
|
4780 "Answer the property value associated with aKey." |
|
4781 |
|
4782 ^ self propertyAt: aKey ifAbsent: [ self error: ''Property not found'' ]!! !! |
|
4783 |
|
4784 !!PPContextMemento methodsFor: ''accessing - properties'' stamp: ''JanKurs 3/19/2014 12:15''!! |
|
4785 propertyAt: aKey ifAbsent: aBlock |
|
4786 "Answer the property value associated with aKey or, if aKey isn''t found, answer the result of evaluating aBlock." |
|
4787 |
|
4788 ^ properties isNil |
|
4789 ifTrue: [ aBlock value ] |
|
4790 ifFalse: [ properties at: aKey ifAbsent: aBlock ]!! !! |
|
4791 |
|
4792 !!PPContextMemento methodsFor: ''accessing - properties'' stamp: ''JanKurs 3/19/2014 12:15''!! |
|
4793 propertyAt: aKey put: anObject |
|
4794 "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." |
|
4795 |
|
4796 ^ (properties ifNil: [ properties := Dictionary new: 1 ]) |
|
4797 at: aKey put: anObject!! !! |
|
4798 |
|
4799 !!PPContextMemento methodsFor: ''accessing - properties'' stamp: ''JanKurs 3/19/2014 12:14''!! |
|
4800 hasProperty: aKey |
|
4801 "Test if the property aKey is present." |
|
4802 |
|
4803 ^ properties notNil and: [ properties includesKey: aKey ]!! !! |
|
4804 |
|
4805 !!PPContextMemento methodsFor: ''accessing - properties'' stamp: ''JanKurs 3/19/2014 12:15''!! |
|
4806 removeProperty: aKey |
|
4807 "Remove the property with aKey. Answer the property or raise an error if aKey isn''t found." |
|
4808 |
|
4809 ^ self removeProperty: aKey ifAbsent: [ self error: ''Property not found'' ]!! !! |
|
4810 |
|
4811 !!PPContextMemento methodsFor: ''accessing - properties'' stamp: ''JanKurs 3/19/2014 13:04''!! |
|
4812 properties |
|
4813 ^ properties !! !! |
|
4814 |
|
4815 |
|
4816 !!PPContextMemento methodsFor: ''as yet unclassified'' stamp: ''JanKurs 10/28/2013 16:52''!! |
|
4817 stream: aStream |
|
4818 stream := aStream!! !! |
|
4819 |
|
4820 !!PPContextMemento methodsFor: ''as yet unclassified'' stamp: ''JanKurs 10/28/2013 16:51''!! |
|
4821 position |
|
4822 ^ position!! !! |
|
4823 |
|
4824 !!PPContextMemento methodsFor: ''as yet unclassified'' stamp: ''JanKurs 10/28/2013 16:52''!! |
|
4825 position: anInteger |
|
4826 position := anInteger !! !! |
|
4827 |
|
4828 !!PPContextMemento methodsFor: ''as yet unclassified'' stamp: ''JanKurs 10/28/2013 16:51''!! |
|
4829 stream |
|
4830 ^ stream!! !! |
|
4831 |
|
4832 |
|
4833 Object subclass: #PPContext |
|
4834 instanceVariableNames: ''stream root properties'' |
|
4835 classVariableNames: '''' |
|
4836 poolDictionaries: '''' |
|
4837 category: ''PetitParser-Core''!! |
|
4838 !!PPContext commentStamp: ''<historical>'' prior: 0!! |
|
4839 !! |
|
4840 |
|
4841 |
|
4842 !!PPContext methodsFor: ''memoization'' stamp: ''JanKurs 3/19/2014 16:27''!! |
|
4843 remember |
|
4844 | memento | |
|
4845 memento := PPContextMemento new |
|
4846 stream: stream; |
|
4847 position: stream position; |
|
4848 yourself. |
|
4849 |
|
4850 self rememberProperties: memento. |
|
4851 ^ memento!! !! |
|
4852 |
|
4853 !!PPContext methodsFor: ''memoization'' stamp: ''JanKurs 3/19/2014 16:26''!! |
|
4854 restore: aPPContextMemento |
|
4855 aPPContextMemento stream == stream ifFalse: [ self error: ''Oops!!!!'' ]. |
|
4856 |
|
4857 stream position: aPPContextMemento position. |
|
4858 self restoreProperties: aPPContextMemento.!! !! |
|
4859 |
|
4860 !!PPContext methodsFor: ''memoization'' stamp: ''JanKurs 3/19/2014 16:29''!! |
|
4861 restoreProperties: aPPContextMemento |
|
4862 aPPContextMemento stream == stream ifFalse: [ self error: ''Oops!!!!'' ]. |
|
4863 |
|
4864 aPPContextMemento class selectorsAndMethodsDo: [ :selector :method | |
|
4865 (selector beginsWith: ''restore'') ifTrue: [ |
|
4866 aPPContextMemento withArgs: (Array with: self) executeMethod: method. |
|
4867 ] |
|
4868 ]!! !! |
|
4869 |
|
4870 !!PPContext methodsFor: ''memoization'' stamp: ''JanKurs 3/19/2014 16:28''!! |
|
4871 rememberProperties: aPPContextMemento |
|
4872 aPPContextMemento class selectorsAndMethodsDo: [ :selector :method | |
|
4873 (selector beginsWith: ''remember'') ifTrue: [ |
|
4874 aPPContextMemento withArgs: (Array with: self) executeMethod: method. |
|
4875 ] |
|
4876 ] |
|
4877 !! !! |
|
4878 |
|
4879 |
|
4880 !!PPContext methodsFor: ''stream mimicry'' stamp: ''JanKurs 4/29/2014 16:25''!! |
|
4881 peekTwice |
|
4882 ^ stream peekTwice!! !! |
|
4883 |
|
4884 !!PPContext methodsFor: ''stream mimicry'' stamp: ''JanKurs 1/15/2014 16:02''!! |
|
4885 position |
|
4886 ^ stream position!! !! |
|
4887 |
|
4888 !!PPContext methodsFor: ''stream mimicry'' stamp: ''JanKurs 8/19/2014 14:08''!! |
|
4889 uncheckedPeek |
|
4890 ^ stream uncheckedPeek!! !! |
|
4891 |
|
4892 !!PPContext methodsFor: ''stream mimicry'' stamp: ''JanKurs 1/15/2014 16:11''!! |
|
4893 upTo: anObject |
|
4894 ^ stream upTo: anObject!! !! |
|
4895 |
|
4896 !!PPContext methodsFor: ''stream mimicry'' stamp: ''JanKurs 8/19/2014 14:08''!! |
|
4897 collection |
|
4898 ^ stream collection !! !! |
|
4899 |
|
4900 !!PPContext methodsFor: ''stream mimicry'' stamp: ''JanKurs 1/16/2014 12:13''!! |
|
4901 atEnd |
|
4902 ^ stream atEnd!! !! |
|
4903 |
|
4904 !!PPContext methodsFor: ''stream mimicry'' stamp: ''JanKurs 4/29/2014 16:24''!! |
|
4905 peek |
|
4906 ^ stream peek!! !! |
|
4907 |
|
4908 !!PPContext methodsFor: ''stream mimicry'' stamp: ''JanKurs 4/29/2014 16:29''!! |
|
4909 upToAll: whatever |
|
4910 ^ stream upToAll: whatever!! !! |
|
4911 |
|
4912 !!PPContext methodsFor: ''stream mimicry'' stamp: ''JanKurs 8/19/2014 14:08''!! |
|
4913 skip: anInteger |
|
4914 ^ stream skip: anInteger !! !! |
|
4915 |
|
4916 !!PPContext methodsFor: ''stream mimicry'' stamp: ''JanKurs 4/29/2014 16:31''!! |
|
4917 upToAnyOf: whatever |
|
4918 ^ stream upToAnyOf: whatever!! !! |
|
4919 |
|
4920 !!PPContext methodsFor: ''stream mimicry'' stamp: ''JanKurs 1/15/2014 16:02''!! |
|
4921 next |
|
4922 ^ stream next!! !! |
|
4923 |
|
4924 |
|
4925 !!PPContext methodsFor: ''accessing-properties'' stamp: ''JanKurs 1/16/2014 11:25''!! |
|
4926 propertyAt: aKey ifAbsentPut: aBlock |
|
4927 "Answer the property associated with aKey or, if aKey isn''t found store the result of evaluating aBlock as new value." |
|
4928 |
|
4929 ^ self propertyAt: aKey ifAbsent: [ self propertyAt: aKey put: aBlock value ]!! !! |
|
4930 |
|
4931 !!PPContext methodsFor: ''accessing-properties'' stamp: ''JanKurs 1/16/2014 11:25''!! |
|
4932 removeProperty: aKey ifAbsent: aBlock |
|
4933 "Remove the property with aKey. Answer the value or, if aKey isn''t found, answer the result of evaluating aBlock." |
|
4934 |
|
4935 | answer | |
|
4936 properties isNil ifTrue: [ ^ aBlock value ]. |
|
4937 answer := properties removeKey: aKey ifAbsent: aBlock. |
|
4938 properties isEmpty ifTrue: [ properties := nil ]. |
|
4939 ^ answer!! !! |
|
4940 |
|
4941 !!PPContext methodsFor: ''accessing-properties'' stamp: ''JanKurs 1/16/2014 11:25''!! |
|
4942 propertyAt: aKey |
|
4943 "Answer the property value associated with aKey." |
|
4944 |
|
4945 ^ self propertyAt: aKey ifAbsent: [ self error: ''Property not found'' ]!! !! |
|
4946 |
|
4947 !!PPContext methodsFor: ''accessing-properties'' stamp: ''JanKurs 1/16/2014 11:25''!! |
|
4948 propertyAt: aKey ifAbsent: aBlock |
|
4949 "Answer the property value associated with aKey or, if aKey isn''t found, answer the result of evaluating aBlock." |
|
4950 |
|
4951 ^ properties isNil |
|
4952 ifTrue: [ aBlock value ] |
|
4953 ifFalse: [ properties at: aKey ifAbsent: aBlock ]!! !! |
|
4954 |
|
4955 !!PPContext methodsFor: ''accessing-properties'' stamp: ''JanKurs 1/16/2014 11:25''!! |
|
4956 propertyAt: aKey put: anObject |
|
4957 "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." |
|
4958 |
|
4959 ^ (properties ifNil: [ properties := Dictionary new: 1 ]) |
|
4960 at: aKey put: anObject!! !! |
|
4961 |
|
4962 !!PPContext methodsFor: ''accessing-properties'' stamp: ''JanKurs 1/16/2014 11:25''!! |
|
4963 hasProperty: aKey |
|
4964 "Test if the property aKey is present." |
|
4965 |
|
4966 ^ properties notNil and: [ properties includesKey: aKey ]!! !! |
|
4967 |
|
4968 !!PPContext methodsFor: ''accessing-properties'' stamp: ''JanKurs 1/16/2014 11:25''!! |
|
4969 removeProperty: aKey |
|
4970 "Remove the property with aKey. Answer the property or raise an error if aKey isn''t found." |
|
4971 |
|
4972 ^ self removeProperty: aKey ifAbsent: [ self error: ''Property not found'' ]!! !! |
|
4973 |
|
4974 |
|
4975 !!PPContext methodsFor: ''initialization'' stamp: ''JanKurs 1/16/2014 11:24''!! |
|
4976 initialize |
|
4977 stream := nil.!! !! |
|
4978 |
|
4979 |
|
4980 !!PPContext methodsFor: ''as yet unclassified'' stamp: ''JanKurs 3/19/2014 16:26''!! |
|
4981 parsed: aPPParser at: anInteger result: anObject |
|
4982 self halt. |
|
4983 ^ anObject!! !! |
|
4984 |
|
4985 |
|
4986 !!PPContext methodsFor: ''acessing'' stamp: ''JanKurs 10/29/2013 10:13''!! |
|
4987 root: aPPParser |
|
4988 root := aPPParser !! !! |
|
4989 |
|
4990 !!PPContext methodsFor: ''acessing'' stamp: ''JanKurs 10/29/2013 10:13''!! |
|
4991 root |
|
4992 ^ root !! !! |
|
4993 |
|
4994 !!PPContext methodsFor: ''acessing'' stamp: ''JanKurs 1/15/2014 15:36''!! |
|
4995 stream: aStream |
|
4996 stream := aStream.!! !! |
|
4997 |
|
4998 !!PPContext methodsFor: ''acessing'' stamp: ''JanKurs 1/16/2014 15:12''!! |
|
4999 stream |
|
5000 ^ stream!! !! |
|
5001 |
|
5002 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
5003 |
|
5004 PPContext class |
|
5005 instanceVariableNames: ''''!! |
|
5006 !!PPContext class commentStamp: ''<historical>'' prior: 0!! |
|
5007 !! |
|
5008 |
|
5009 |
|
5010 !!PPContext class methodsFor: ''as yet unclassified'' stamp: ''JanKurs 1/16/2014 14:38''!! |
|
5011 on: aPPParser stream: aStream |
|
5012 ^ self basicNew |
|
5013 initialize; |
|
5014 root: aPPParser; |
|
5015 stream: aStream asPetitStream; |
|
5016 yourself!! !! |
|
5017 |
|
5018 |
|
5019 Object subclass: #PPMemento |
|
5020 instanceVariableNames: ''result count context'' |
|
5021 classVariableNames: '''' |
|
5022 poolDictionaries: '''' |
|
5023 category: ''PetitParser-Core''!! |
|
5024 !!PPMemento commentStamp: ''<historical>'' prior: 0!! |
|
5025 PPMemento is an internal class used by PPMemoizedParser to cache results and detect left-recursive calls. |
|
5026 |
|
5027 Instance Variables: |
|
5028 result <Object> The cached result. |
|
5029 count <Integer> The number of recursive cycles followed. |
|
5030 position <Integer> The position of the cached result in the input stream.!! |
|
5031 |
|
5032 |
|
5033 !!PPMemento methodsFor: ''accessing'' stamp: ''JanKurs 1/15/2014 16:09''!! |
|
5034 contextMemento: aPPContextMemento |
|
5035 context := aPPContextMemento |
|
5036 !! !! |
|
5037 |
|
5038 !!PPMemento methodsFor: ''accessing'' stamp: ''JanKurs 1/15/2014 16:09''!! |
|
5039 contextMemento |
|
5040 ^ context!! !! |
|
5041 |
|
5042 !!PPMemento methodsFor: ''accessing'' stamp: ''lr 4/24/2008 10:15''!! |
|
5043 result |
|
5044 ^ result!! !! |
|
5045 |
|
5046 !!PPMemento methodsFor: ''accessing'' stamp: ''lr 4/22/2008 18:23''!! |
|
5047 result: anObject |
|
5048 result := anObject!! !! |
|
5049 |
|
5050 |
|
5051 !!PPMemento methodsFor: ''accessing-readonly'' stamp: ''lr 4/22/2008 18:23''!! |
|
5052 count |
|
5053 ^ count!! !! |
|
5054 |
|
5055 |
|
5056 !!PPMemento methodsFor: ''initialization'' stamp: ''lr 4/22/2008 18:21''!! |
|
5057 initialize |
|
5058 count := 0 |
|
5059 !! !! |
|
5060 |
|
5061 |
|
5062 !!PPMemento methodsFor: ''actions'' stamp: ''lr 4/22/2008 18:20''!! |
|
5063 increment |
|
5064 count := count + 1!! !! |
|
5065 |
|
5066 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!! |
|
5067 |
|
5068 PPMemento class |
|
5069 instanceVariableNames: ''''!! |
|
5070 !!PPMemento class commentStamp: ''<historical>'' prior: 0!! |
|
5071 !! |
|
5072 |
|
5073 |
|
5074 !!PPMemento class methodsFor: ''instance creation'' stamp: ''lr 4/22/2008 18:21''!! |
|
5075 new |
|
5076 ^ self basicNew initialize!! !! |
|
5077 |
|
5078 PPToken initialize!!''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5079 |
|
5080 !!SequenceableCollection methodsFor: ''*petitparser-core-converting'' stamp: ''lr 2/7/2010 20:53''!! |
|
5081 asPetitStream |
|
5082 ^ PPStream on: self!! !! |
|
5083 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5084 |
|
5085 !!Character methodsFor: ''*petitparser-core-operators'' stamp: ''lr 6/12/2010 09:04''!! |
|
5086 - aCharacter |
|
5087 "Create a range of characters between the receiver and the argument." |
|
5088 |
|
5089 ^ PPPredicateObjectParser between: self and: aCharacter!! !! |
|
5090 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5091 |
|
5092 !!Character methodsFor: ''*petitparser-core-converting'' stamp: ''lr 12/18/2011 15:58''!! |
|
5093 asParser |
|
5094 "Answer a parser that accepts the receiving character." |
|
5095 |
|
5096 ^ PPLiteralObjectParser on: self!! !! |
|
5097 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5098 |
|
5099 !!PositionableStream methodsFor: ''*petitparser-core'' stamp: ''sback 9/3/2010 10:00''!! |
|
5100 peekTwice |
|
5101 "Answer what would be returned if the message next were sent to the |
|
5102 receiver. If the receiver is at the end, answer nil." |
|
5103 |
|
5104 | array | |
|
5105 self atEnd |
|
5106 ifTrue: [^Array with: nil with: nil]. |
|
5107 array := Array with: (self next) with: (self peek). |
|
5108 position := position - 1. |
|
5109 ^array!! !! |
|
5110 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5111 |
|
5112 !!Stream methodsFor: ''*petitparser-core-converting'' stamp: ''lr 4/8/2010 14:46''!! |
|
5113 asPetitStream |
|
5114 ^ self contents asPetitStream!! !! |
|
5115 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5116 |
|
5117 !!Symbol methodsFor: ''*petitparser-core-converting'' stamp: ''lr 12/18/2011 15:58''!! |
|
5118 asParser |
|
5119 "Answer a predicate parser named after the receiving symbol. Possible symbols are the method selectors on the class-side of PPPredicateObjectParser." |
|
5120 |
|
5121 ^ PPPredicateObjectParser perform: self!! !! |
|
5122 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5123 |
|
5124 !!String methodsFor: ''*petitparser-core-converting'' stamp: ''lr 11/29/2011 20:48''!! |
|
5125 asParser |
|
5126 "Answer a parser that accepts the receiving string." |
|
5127 |
|
5128 ^ PPLiteralSequenceParser on: self!! !! |
|
5129 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5130 |
|
5131 !!BlockClosure methodsFor: ''*petitparser-core-converting'' stamp: ''lr 11/29/2011 20:48''!! |
|
5132 asParser |
|
5133 "Answer a parser implemented in the receiving one-argument block." |
|
5134 |
|
5135 ^ PPPluggableParser on: self!! !! |
|
5136 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5137 |
|
5138 !!UndefinedObject methodsFor: ''*petitparser-converting'' stamp: ''lr 11/29/2011 20:49''!! |
|
5139 asParser |
|
5140 "Answer a parser that succeeds and does not consume anything." |
|
5141 |
|
5142 ^ PPEpsilonParser new!! !! |
|
5143 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5144 |
|
5145 !!Text methodsFor: ''*petitparser-core-converting'' stamp: ''lr 2/7/2010 20:53''!! |
|
5146 asPetitStream |
|
5147 ^ string asPetitStream!! !! |
|
5148 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5149 |
|
5150 !!Collection methodsFor: ''*petitparser-core-converting'' stamp: ''lr 11/29/2011 20:38''!! |
|
5151 asChoiceParser |
|
5152 ^ PPChoiceParser withAll: (self collect: [ :each | each asParser ])!! !! |
|
5153 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5154 |
|
5155 !!Collection methodsFor: ''*petitparser-core-converting'' stamp: ''lr 11/29/2011 20:38''!! |
|
5156 asSequenceParser |
|
5157 ^ PPSequenceParser withAll: (self collect: [ :each | each asParser ])!! !! |
|
5158 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5159 |
|
5160 !!Object methodsFor: ''*petitparser-core-testing'' stamp: ''lr 8/6/2010 16:44''!! |
|
5161 isPetitParser |
|
5162 ^ false!! !! |
|
5163 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.312417 pm''!! |
|
5164 |
|
5165 !!Object methodsFor: ''*petitparser-core-converting'' stamp: ''lr 12/18/2011 15:58''!! |
|
5166 asParser |
|
5167 "Answer a parser accepting the receiving object." |
|
5168 |
|
5169 ^ PPPredicateObjectParser expect: self!! !! |
|
5170 ''From Pharo3.0 of 18 March 2013 [Latest update: #30854] on 22 August 2014 at 8:49:56.314418 pm''!! |
|
5171 |
|
5172 !!Object methodsFor: ''*petitparser-core-testing'' stamp: ''lr 2/7/2010 20:54''!! |
|
5173 isPetitFailure |
|
5174 ^ false!! !! |
|
5175 ' |
|
5176 ! |
|
5177 |
|
5178 smalltalkObjectMethods |
|
5179 ^ Object allMethods collect: [ :m | m sourceCode ]. |
|
5180 ! |
|
5181 |
|
5182 smalltalkSourcesBig |
|
5183 ^ ((Smalltalk allClasses copyFrom: 1 to: 30) collect: [ :c | |
|
5184 c allMethods collect: [ :m | m sourceCode ] |
|
5185 ]) gather: [:each | each ]. |
|
5186 ! |
|
5187 |
|
5188 workingJavaInDirectory: directory |
|
5189 | sources parser | |
|
5190 "return only such a files, that can be parsed by PPJavaSyntax" |
|
5191 |
|
5192 javaCache ifNil: [ javaCache := Dictionary new ]. |
|
5193 |
|
5194 ^ javaCache at: directory ifAbsentPut: [ |
|
5195 sources := self javaInDirectory: directory. |
|
5196 parser := PPJavaSyntax new. |
|
5197 |
|
5198 sources select: [ :source | ([parser parse: source ] on: Error do: [ PPFailure new ]) isPetitFailure not ] |
|
5199 ] |
|
5200 ! ! |
|
5201 |
|
5202 !PPCBenchmarkResources methodsFor:'private utilities'! |
|
5203 |
|
5204 files: files withExtension: extension |
|
5205 ^ files select: [ :f | f extension = extension ] |
|
5206 ! |
|
5207 |
|
5208 readDirectory: directory |
|
5209 | file | |
|
5210 file := directory asFileReference. |
|
5211 file exists ifTrue: [ |
|
5212 ^ file allFiles |
|
5213 ]. |
|
5214 ^ #() |
|
5215 ! ! |
|
5216 |