treetop 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,103 @@
1
+ #Syntactic Recognition
2
+ Treetop grammars are written in a custom language based on parsing expression grammars. Literature on the subject of parsing expression grammars is useful in writing Treetop grammars.
3
+
4
+ #Grammar Structure
5
+ Treetop grammars look like this:
6
+
7
+ grammar GrammarName
8
+ rule rule_name
9
+ ...
10
+ end
11
+
12
+ rule rule_name
13
+ ...
14
+ end
15
+
16
+ ...
17
+ end
18
+
19
+ The main keywords are:
20
+
21
+ * `grammar` : This introduces a new grammar. It is followed by a constant name to which the grammar will be bound when it is loaded.
22
+
23
+ * `rule` : This defines a parsing rule within the grammar. It is followed by a name by which this rule can be referenced within other rules. It is then followed by a parsing expression defining the rule.
24
+
25
+ #Parsing Expressions
26
+ Each rule associates a name with a _parsing expression_. Parsing expressions are a generalization of vanilla regular expressions. Their key feature is the ability to reference other expressions in the grammar by name.
27
+
28
+ ##Atomic Expressions
29
+ ###Terminal Symbols
30
+ ####Strings
31
+ Strings are surrounded in double or single quotes and must be matched exactly.
32
+
33
+ * `"foo"`
34
+ * `'foo'`
35
+
36
+ ####Character Classes
37
+ Character classes are surrounded by brackets. Their semantics are identical to those used in Ruby's regular expressions.
38
+
39
+ * `[a-zA-Z]`
40
+ * `[0-9]`
41
+
42
+ ####The Anything Symbol
43
+ The anything symbol is represented by a dot (`.`) and matches any single character.
44
+
45
+ ###Nonterminal Symbols
46
+ Nonterminal symbols are unquoted references to other named rules. They are equivalent to an inline substitution of the named expression.
47
+
48
+ rule foo
49
+ "the dog " bar
50
+ end
51
+
52
+ rule bar
53
+ "jumped"
54
+ end
55
+
56
+ The above grammar is equivalent to:
57
+
58
+ rule foo
59
+ "the dog jumped"
60
+ end
61
+
62
+ ##Composite Expressions
63
+ ###Ordered Choice
64
+ Parsers attempt to match ordered choices in left-to-right order, and stop after the first successful match.
65
+
66
+ "foobar" / "foo" / "bar"
67
+
68
+ Note that if `"foo"` in the above expression came first, `"foobar"` would never be matched.
69
+
70
+ ###Sequences
71
+
72
+ Sequences are a space-separated list of parsing expressions. They have higher precedence than choices, so choices must be parenthesized to be used as the elements of a sequence.
73
+
74
+ "foo" "bar" ("baz" / "bop")
75
+
76
+ ###Repetitions
77
+ ####Zero or More
78
+ Parsers will greedily match an expression zero or more times if it is followed by the star (`*`) symbol.
79
+
80
+ * `'foo'*` matches the empty string, `"foo"`, `"foofoo"`, etc.
81
+
82
+ ####One or More
83
+ Parsers will greedily match an expression one or more times if it is followed by the star (`+`) symbol.
84
+
85
+ * `'foo'+` does not match the empty string, but matches `"foo"`, `"foofoo"`, etc.
86
+
87
+ ###Optional Expressions
88
+ An expression can be declared optional by following it with a question mark (`?`).
89
+
90
+ * `'foo'?` matches `"foo"` or the empty string.
91
+
92
+ ##Lookahead Assertions
93
+ Lookahead assertions can be used to give parsing expressions a limited degree of context-sensitivity. The parser will look ahead into the buffer and attempt to match an expression without consuming input.
94
+
95
+ ###Positive Lookahead Assertion
96
+ Preceding an expression with an ampersand `(&)` indicates that it must match, but no input will be consumed in the process of determining whether this is true.
97
+
98
+ * `"foo" &"bar"` matches `"foobar"` but only consumes up to the end `"foo"`. It will not match `"foobaz"`.
99
+
100
+ ###Negative Lookahead Assertion
101
+ Preceding an expression with a bang `(!)` indicates that the expression must not match, but no input will be consumed in the process of determining whether this is true.
102
+
103
+ * `"foo" !"bar"` matches `"foobaz"` but only consumes up to the end `"foo"`. It will not match `"foobar"`.
@@ -0,0 +1,17 @@
1
+ #Using Treetop Grammars in Ruby
2
+ ##Using the Command Line Compiler
3
+ You can `.treetop` files into Ruby source code with the `tt` command line script. `tt` takes an list of files with a `.treetop` extension and compiles them into `.rb` files of the same name. You can then `require` these files like any other Ruby script. Alternately, you can supply just one `.treetop` file and a `-o` flag to name specify the name of the output file. Improvements to this compilation script are welcome.
4
+
5
+ tt foo.treetop bar.treetop
6
+ tt foo.treetop -o foogrammar.rb
7
+
8
+ ##Loading A Grammar Directly
9
+ The `load_grammar` method takes the path to a `.treetop` file (where the extension is optional), and automatically compiles and evaluates the Ruby source. If you are getting errors in methods you define on the syntax tree, try using the command line compiler for better stack trace feedback. The need to do this is being addressed.
10
+
11
+ ##Instantiating and Using Parsers
12
+ If a grammar by the name of `Foo` is defined, the compiled Ruby source will define a `FooParser` class. To parse input, create an instance and call its `parse` method with a string.
13
+
14
+ load_grammar "arithmetic"
15
+
16
+ parser = ArithmeticParser.new
17
+ puts parser.parse('1+1').success?
File without changes
@@ -0,0 +1,751 @@
1
+ module LambdaCalculus
2
+ include ::Treetop::Runtime
3
+
4
+ def root
5
+ result = _nt_program
6
+ if index == input.size
7
+ return result
8
+ else
9
+ return ParseFailure.new(input, index, result.nested_failures)
10
+ end
11
+ end
12
+
13
+ include Arithmetic
14
+
15
+ module Program0
16
+ def space
17
+ elements[1]
18
+ end
19
+
20
+ def expression
21
+ elements[2]
22
+ end
23
+ end
24
+
25
+ module Program1
26
+ def expression
27
+ elements[0]
28
+ end
29
+
30
+ def more_expressions
31
+ elements[1]
32
+ end
33
+ end
34
+
35
+ module Program2
36
+ def eval(env={})
37
+ env = env.clone
38
+ last_eval = nil
39
+ expressions.each do |exp|
40
+ last_eval = exp.eval(env)
41
+ end
42
+ last_eval
43
+ end
44
+
45
+ def expressions
46
+ [expression] + more_expressions.elements.map {|elt| elt.expression}
47
+ end
48
+ end
49
+
50
+ def _nt_program
51
+ start_index = index
52
+ cached = node_cache[:program][index]
53
+ if cached
54
+ @index = cached.interval.end
55
+ return cached
56
+ end
57
+
58
+ i0, s0, nr0 = index, [], []
59
+ r1 = _nt_expression
60
+ s0 << r1
61
+ if r1.success?
62
+ s2, nr2, i2 = [], [], index
63
+ loop do
64
+ i3, s3, nr3 = index, [], []
65
+ r4 = parse_terminal(';', SyntaxNode)
66
+ s3 << r4
67
+ if r4.success?
68
+ r5 = _nt_space
69
+ s3 << r5
70
+ if r5.success?
71
+ r6 = _nt_expression
72
+ s3 << r6
73
+ end
74
+ end
75
+ if s3.last.success?
76
+ r3 = (SyntaxNode).new(input, i3...index, s3)
77
+ r3.extend(Program0)
78
+ else
79
+ self.index = i3
80
+ r3 = ParseFailure.new(input, i3, s3)
81
+ end
82
+ nr2 << r3
83
+ if r3.success?
84
+ s2 << r3
85
+ else
86
+ break
87
+ end
88
+ end
89
+ r2 = SyntaxNode.new(input, i2...index, s2, nr2)
90
+ s0 << r2
91
+ end
92
+ if s0.last.success?
93
+ r0 = (SyntaxNode).new(input, i0...index, s0)
94
+ r0.extend(Program1)
95
+ r0.extend(Program2)
96
+ else
97
+ self.index = i0
98
+ r0 = ParseFailure.new(input, i0, s0)
99
+ end
100
+
101
+ node_cache[:program][start_index] = r0
102
+
103
+ return r0
104
+ end
105
+
106
+ def _nt_expression
107
+ start_index = index
108
+ cached = node_cache[:expression][index]
109
+ if cached
110
+ @index = cached.interval.end
111
+ return cached
112
+ end
113
+
114
+ i0, nr0 = index, []
115
+ r1 = _nt_definition
116
+ nr0 << r1
117
+ if r1.success?
118
+ r0 = r1
119
+ r1.update_nested_results(nr0)
120
+ else
121
+ r2 = _nt_conditional
122
+ nr0 << r2
123
+ if r2.success?
124
+ r0 = r2
125
+ r2.update_nested_results(nr0)
126
+ else
127
+ r3 = _nt_application
128
+ nr0 << r3
129
+ if r3.success?
130
+ r0 = r3
131
+ r3.update_nested_results(nr0)
132
+ else
133
+ r4 = _nt_function
134
+ nr0 << r4
135
+ if r4.success?
136
+ r0 = r4
137
+ r4.update_nested_results(nr0)
138
+ else
139
+ r5 = super
140
+ nr0 << r5
141
+ if r5.success?
142
+ r0 = r5
143
+ r5.update_nested_results(nr0)
144
+ else
145
+ self.index = i0
146
+ r0 = ParseFailure.new(input, i0, nr0)
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ node_cache[:expression][start_index] = r0
154
+
155
+ return r0
156
+ end
157
+
158
+ module Definition0
159
+ def space
160
+ elements[1]
161
+ end
162
+
163
+ def variable
164
+ elements[2]
165
+ end
166
+
167
+ def space
168
+ elements[3]
169
+ end
170
+
171
+ def expression
172
+ elements[4]
173
+ end
174
+ end
175
+
176
+ module Definition1
177
+ def eval(env)
178
+ env[variable.name] = expression.eval(env)
179
+ end
180
+ end
181
+
182
+ def _nt_definition
183
+ start_index = index
184
+ cached = node_cache[:definition][index]
185
+ if cached
186
+ @index = cached.interval.end
187
+ return cached
188
+ end
189
+
190
+ i0, s0, nr0 = index, [], []
191
+ r1 = parse_terminal('def', SyntaxNode)
192
+ s0 << r1
193
+ if r1.success?
194
+ r2 = _nt_space
195
+ s0 << r2
196
+ if r2.success?
197
+ r3 = _nt_variable
198
+ s0 << r3
199
+ if r3.success?
200
+ r4 = _nt_space
201
+ s0 << r4
202
+ if r4.success?
203
+ r5 = _nt_expression
204
+ s0 << r5
205
+ end
206
+ end
207
+ end
208
+ end
209
+ if s0.last.success?
210
+ r0 = (SyntaxNode).new(input, i0...index, s0)
211
+ r0.extend(Definition0)
212
+ r0.extend(Definition1)
213
+ else
214
+ self.index = i0
215
+ r0 = ParseFailure.new(input, i0, s0)
216
+ end
217
+
218
+ node_cache[:definition][start_index] = r0
219
+
220
+ return r0
221
+ end
222
+
223
+ module Conditional0
224
+ def space
225
+ elements[1]
226
+ end
227
+
228
+ def space
229
+ elements[3]
230
+ end
231
+
232
+ def condition
233
+ elements[4]
234
+ end
235
+
236
+ def space
237
+ elements[5]
238
+ end
239
+
240
+ def space
241
+ elements[7]
242
+ end
243
+
244
+ def true_case
245
+ elements[8]
246
+ end
247
+
248
+ def space
249
+ elements[9]
250
+ end
251
+
252
+ def space
253
+ elements[11]
254
+ end
255
+
256
+ def false_case
257
+ elements[12]
258
+ end
259
+ end
260
+
261
+ module Conditional1
262
+ def eval(env)
263
+ if condition.eval(env)
264
+ true_case.eval(env)
265
+ else
266
+ false_case.eval(env)
267
+ end
268
+ end
269
+ end
270
+
271
+ def _nt_conditional
272
+ start_index = index
273
+ cached = node_cache[:conditional][index]
274
+ if cached
275
+ @index = cached.interval.end
276
+ return cached
277
+ end
278
+
279
+ i0, s0, nr0 = index, [], []
280
+ r1 = parse_terminal('if', SyntaxNode)
281
+ s0 << r1
282
+ if r1.success?
283
+ r2 = _nt_space
284
+ s0 << r2
285
+ if r2.success?
286
+ r3 = parse_terminal('(', SyntaxNode)
287
+ s0 << r3
288
+ if r3.success?
289
+ r4 = _nt_space
290
+ s0 << r4
291
+ if r4.success?
292
+ r5 = _nt_expression
293
+ s0 << r5
294
+ if r5.success?
295
+ r6 = _nt_space
296
+ s0 << r6
297
+ if r6.success?
298
+ r7 = parse_terminal(')', SyntaxNode)
299
+ s0 << r7
300
+ if r7.success?
301
+ r8 = _nt_space
302
+ s0 << r8
303
+ if r8.success?
304
+ r9 = _nt_expression
305
+ s0 << r9
306
+ if r9.success?
307
+ r10 = _nt_space
308
+ s0 << r10
309
+ if r10.success?
310
+ r11 = parse_terminal('else', SyntaxNode)
311
+ s0 << r11
312
+ if r11.success?
313
+ r12 = _nt_space
314
+ s0 << r12
315
+ if r12.success?
316
+ r13 = _nt_expression
317
+ s0 << r13
318
+ end
319
+ end
320
+ end
321
+ end
322
+ end
323
+ end
324
+ end
325
+ end
326
+ end
327
+ end
328
+ end
329
+ end
330
+ if s0.last.success?
331
+ r0 = (SyntaxNode).new(input, i0...index, s0)
332
+ r0.extend(Conditional0)
333
+ r0.extend(Conditional1)
334
+ else
335
+ self.index = i0
336
+ r0 = ParseFailure.new(input, i0, s0)
337
+ end
338
+
339
+ node_cache[:conditional][start_index] = r0
340
+
341
+ return r0
342
+ end
343
+
344
+ def _nt_primary
345
+ start_index = index
346
+ cached = node_cache[:primary][index]
347
+ if cached
348
+ @index = cached.interval.end
349
+ return cached
350
+ end
351
+
352
+ i0, nr0 = index, []
353
+ r1 = _nt_application
354
+ nr0 << r1
355
+ if r1.success?
356
+ r0 = r1
357
+ r1.update_nested_results(nr0)
358
+ else
359
+ r2 = super
360
+ nr0 << r2
361
+ if r2.success?
362
+ r0 = r2
363
+ r2.update_nested_results(nr0)
364
+ else
365
+ self.index = i0
366
+ r0 = ParseFailure.new(input, i0, nr0)
367
+ end
368
+ end
369
+
370
+ node_cache[:primary][start_index] = r0
371
+
372
+ return r0
373
+ end
374
+
375
+ module Application0
376
+ def operator
377
+ elements[0]
378
+ end
379
+
380
+ def space
381
+ elements[1]
382
+ end
383
+
384
+ def expression
385
+ elements[2]
386
+ end
387
+ end
388
+
389
+ module Application1
390
+ def eval(env={})
391
+ left_associative_apply(operator.eval(env), env)
392
+ end
393
+
394
+ def left_associative_apply(operator, env)
395
+ if expression.instance_of?(Application)
396
+ expression.left_associative_apply(operator.apply(expression.operator.eval(env)), env)
397
+ else
398
+ operator.apply(expression.eval(env))
399
+ end
400
+ end
401
+
402
+ def to_s(env={})
403
+ operator.to_s(env) + ' ' + expression.to_s(env)
404
+ end
405
+ end
406
+
407
+ def _nt_application
408
+ start_index = index
409
+ cached = node_cache[:application][index]
410
+ if cached
411
+ @index = cached.interval.end
412
+ return cached
413
+ end
414
+
415
+ i0, s0, nr0 = index, [], []
416
+ r1 = _nt_operator
417
+ s0 << r1
418
+ if r1.success?
419
+ r2 = _nt_space
420
+ s0 << r2
421
+ if r2.success?
422
+ r3 = _nt_expression
423
+ s0 << r3
424
+ end
425
+ end
426
+ if s0.last.success?
427
+ r0 = (Application).new(input, i0...index, s0)
428
+ r0.extend(Application0)
429
+ r0.extend(Application1)
430
+ else
431
+ self.index = i0
432
+ r0 = ParseFailure.new(input, i0, s0)
433
+ end
434
+
435
+ node_cache[:application][start_index] = r0
436
+
437
+ return r0
438
+ end
439
+
440
+ def _nt_operator
441
+ start_index = index
442
+ cached = node_cache[:operator][index]
443
+ if cached
444
+ @index = cached.interval.end
445
+ return cached
446
+ end
447
+
448
+ i0, nr0 = index, []
449
+ r1 = _nt_function
450
+ nr0 << r1
451
+ if r1.success?
452
+ r0 = r1
453
+ r1.update_nested_results(nr0)
454
+ else
455
+ r2 = _nt_variable
456
+ nr0 << r2
457
+ if r2.success?
458
+ r0 = r2
459
+ r2.update_nested_results(nr0)
460
+ else
461
+ self.index = i0
462
+ r0 = ParseFailure.new(input, i0, nr0)
463
+ end
464
+ end
465
+
466
+ node_cache[:operator][start_index] = r0
467
+
468
+ return r0
469
+ end
470
+
471
+ def _nt_non_application
472
+ start_index = index
473
+ cached = node_cache[:non_application][index]
474
+ if cached
475
+ @index = cached.interval.end
476
+ return cached
477
+ end
478
+
479
+ i0, nr0 = index, []
480
+ r1 = _nt_function
481
+ nr0 << r1
482
+ if r1.success?
483
+ r0 = r1
484
+ r1.update_nested_results(nr0)
485
+ else
486
+ r2 = _nt_variable
487
+ nr0 << r2
488
+ if r2.success?
489
+ r0 = r2
490
+ r2.update_nested_results(nr0)
491
+ else
492
+ self.index = i0
493
+ r0 = ParseFailure.new(input, i0, nr0)
494
+ end
495
+ end
496
+
497
+ node_cache[:non_application][start_index] = r0
498
+
499
+ return r0
500
+ end
501
+
502
+ module Function0
503
+ def param
504
+ elements[1]
505
+ end
506
+
507
+ def body
508
+ elements[3]
509
+ end
510
+
511
+ end
512
+
513
+ module Function1
514
+ class Closure
515
+ attr_reader :env, :function
516
+
517
+ def initialize(function, env)
518
+ @function = function
519
+ @env = env
520
+ end
521
+
522
+ def apply(arg)
523
+ function.body.eval(function.param.bind(arg, env))
524
+ end
525
+
526
+ def to_s(other_env={})
527
+ "\\#{function.param.to_s}(#{function.body.to_s(other_env.merge(env))})"
528
+ end
529
+ end
530
+
531
+ def eval(env={})
532
+ Closure.new(self, env)
533
+ end
534
+
535
+ def to_s(env={})
536
+ eval(env).to_s
537
+ end
538
+ end
539
+
540
+ def _nt_function
541
+ start_index = index
542
+ cached = node_cache[:function][index]
543
+ if cached
544
+ @index = cached.interval.end
545
+ return cached
546
+ end
547
+
548
+ i0, s0, nr0 = index, [], []
549
+ r1 = parse_terminal('\\', SyntaxNode)
550
+ s0 << r1
551
+ if r1.success?
552
+ r2 = _nt_variable
553
+ s0 << r2
554
+ if r2.success?
555
+ r3 = parse_terminal('(', SyntaxNode)
556
+ s0 << r3
557
+ if r3.success?
558
+ r4 = _nt_expression
559
+ s0 << r4
560
+ if r4.success?
561
+ r5 = parse_terminal(')', SyntaxNode)
562
+ s0 << r5
563
+ end
564
+ end
565
+ end
566
+ end
567
+ if s0.last.success?
568
+ r0 = (SyntaxNode).new(input, i0...index, s0)
569
+ r0.extend(Function0)
570
+ r0.extend(Function1)
571
+ else
572
+ self.index = i0
573
+ r0 = ParseFailure.new(input, i0, s0)
574
+ end
575
+
576
+ node_cache[:function][start_index] = r0
577
+
578
+ return r0
579
+ end
580
+
581
+ module Variable0
582
+ def bind(value, env)
583
+ env.merge(name => value)
584
+ end
585
+
586
+ def to_s(env={})
587
+ env.has_key?(name) ? env[name].to_s : name
588
+ end
589
+ end
590
+
591
+ module Variable1
592
+ end
593
+
594
+ def _nt_variable
595
+ start_index = index
596
+ cached = node_cache[:variable][index]
597
+ if cached
598
+ @index = cached.interval.end
599
+ return cached
600
+ end
601
+
602
+ i0, s0, nr0 = index, [], []
603
+ i1 = index
604
+ r2 = _nt_keyword
605
+ if r2.success?
606
+ r1 = ParseFailure.new(input, i1, r2.nested_failures)
607
+ else
608
+ self.index = i1
609
+ r1 = SyntaxNode.new(input, index...index, r2.nested_failures)
610
+ end
611
+ s0 << r1
612
+ if r1.success?
613
+ r3 = super
614
+ r3.extend(Variable0)
615
+ s0 << r3
616
+ end
617
+ if s0.last.success?
618
+ r0 = (SyntaxNode).new(input, i0...index, s0)
619
+ r0.extend(Variable1)
620
+ else
621
+ self.index = i0
622
+ r0 = ParseFailure.new(input, i0, s0)
623
+ end
624
+
625
+ node_cache[:variable][start_index] = r0
626
+
627
+ return r0
628
+ end
629
+
630
+ module Keyword0
631
+ end
632
+
633
+ def _nt_keyword
634
+ start_index = index
635
+ cached = node_cache[:keyword][index]
636
+ if cached
637
+ @index = cached.interval.end
638
+ return cached
639
+ end
640
+
641
+ i0, s0, nr0 = index, [], []
642
+ i1, nr1 = index, []
643
+ r2 = parse_terminal('if', SyntaxNode)
644
+ nr1 << r2
645
+ if r2.success?
646
+ r1 = r2
647
+ r2.update_nested_results(nr1)
648
+ else
649
+ r3 = parse_terminal('else', SyntaxNode)
650
+ nr1 << r3
651
+ if r3.success?
652
+ r1 = r3
653
+ r3.update_nested_results(nr1)
654
+ else
655
+ self.index = i1
656
+ r1 = ParseFailure.new(input, i1, nr1)
657
+ end
658
+ end
659
+ s0 << r1
660
+ if r1.success?
661
+ i4 = index
662
+ r5 = _nt_non_space_char
663
+ if r5.success?
664
+ r4 = ParseFailure.new(input, i4, r5.nested_failures)
665
+ else
666
+ self.index = i4
667
+ r4 = SyntaxNode.new(input, index...index, r5.nested_failures)
668
+ end
669
+ s0 << r4
670
+ end
671
+ if s0.last.success?
672
+ r0 = (SyntaxNode).new(input, i0...index, s0)
673
+ r0.extend(Keyword0)
674
+ else
675
+ self.index = i0
676
+ r0 = ParseFailure.new(input, i0, s0)
677
+ end
678
+
679
+ node_cache[:keyword][start_index] = r0
680
+
681
+ return r0
682
+ end
683
+
684
+ module NonSpaceChar0
685
+ end
686
+
687
+ def _nt_non_space_char
688
+ start_index = index
689
+ cached = node_cache[:non_space_char][index]
690
+ if cached
691
+ @index = cached.interval.end
692
+ return cached
693
+ end
694
+
695
+ i0, s0, nr0 = index, [], []
696
+ i1 = index
697
+ r2 = parse_char_class(/[ \n]/, ' \n', SyntaxNode)
698
+ if r2.success?
699
+ r1 = ParseFailure.new(input, i1, r2.nested_failures)
700
+ else
701
+ self.index = i1
702
+ r1 = SyntaxNode.new(input, index...index, r2.nested_failures)
703
+ end
704
+ s0 << r1
705
+ if r1.success?
706
+ r3 = parse_anything(SyntaxNode)
707
+ s0 << r3
708
+ end
709
+ if s0.last.success?
710
+ r0 = (SyntaxNode).new(input, i0...index, s0)
711
+ r0.extend(NonSpaceChar0)
712
+ else
713
+ self.index = i0
714
+ r0 = ParseFailure.new(input, i0, s0)
715
+ end
716
+
717
+ node_cache[:non_space_char][start_index] = r0
718
+
719
+ return r0
720
+ end
721
+
722
+ def _nt_space
723
+ start_index = index
724
+ cached = node_cache[:space][index]
725
+ if cached
726
+ @index = cached.interval.end
727
+ return cached
728
+ end
729
+
730
+ s0, nr0, i0 = [], [], index
731
+ loop do
732
+ r1 = parse_char_class(/[ \n]/, ' \n', SyntaxNode)
733
+ nr0 << r1
734
+ if r1.success?
735
+ s0 << r1
736
+ else
737
+ break
738
+ end
739
+ end
740
+ r0 = SyntaxNode.new(input, i0...index, s0, nr0)
741
+
742
+ node_cache[:space][start_index] = r0
743
+
744
+ return r0
745
+ end
746
+
747
+ end
748
+
749
+ class LambdaCalculusParser < ::Treetop::Runtime::CompiledParser
750
+ include LambdaCalculus
751
+ end