treetop 1.1.4 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +1 -1
- data/Rakefile +3 -2
- data/doc/contributing_and_planned_features.markdown +1 -1
- data/doc/using_in_ruby.markdown +2 -2
- data/examples/lambda_calculus/arithmetic.rb +551 -0
- data/examples/lambda_calculus/arithmetic_test.rb +1 -1
- data/examples/lambda_calculus/lambda_calculus.rb +39 -72
- data/examples/lambda_calculus/lambda_calculus_test.rb +2 -2
- data/examples/lambda_calculus/test_helper.rb +3 -3
- data/lib/treetop.rb +3 -0
- data/lib/treetop/bootstrap_gen_1_metagrammar.rb +22 -14
- data/lib/treetop/compiler.rb +1 -2
- data/lib/treetop/compiler/grammar_compiler.rb +12 -5
- data/lib/treetop/compiler/metagrammar.rb +931 -558
- data/lib/treetop/compiler/metagrammar.treetop +26 -6
- data/lib/treetop/compiler/node_classes/anything_symbol.rb +10 -2
- data/lib/treetop/compiler/node_classes/atomic_expression.rb +4 -0
- data/lib/treetop/compiler/node_classes/character_class.rb +10 -1
- data/lib/treetop/compiler/node_classes/choice.rb +2 -4
- data/lib/treetop/compiler/node_classes/parsing_expression.rb +8 -17
- data/lib/treetop/compiler/node_classes/parsing_rule.rb +3 -3
- data/lib/treetop/compiler/node_classes/predicate.rb +1 -1
- data/lib/treetop/compiler/node_classes/repetition.rb +3 -4
- data/lib/treetop/compiler/node_classes/sequence.rb +4 -4
- data/lib/treetop/compiler/node_classes/terminal.rb +11 -1
- data/lib/treetop/compiler/ruby_builder.rb +2 -2
- data/lib/treetop/ruby_extensions.rb +1 -1
- data/lib/treetop/runtime.rb +0 -3
- data/lib/treetop/runtime/compiled_parser.rb +42 -34
- data/lib/treetop/runtime/node_cache.rb +1 -1
- data/lib/treetop/runtime/syntax_node.rb +51 -32
- data/lib/treetop/runtime/terminal_parse_failure.rb +7 -24
- data/lib/treetop/runtime/terminal_syntax_node.rb +7 -2
- metadata +12 -7
- data/examples/TALK +0 -33
- data/lib/treetop/compiler/load_grammar.rb +0 -7
- data/lib/treetop/compiler/metagrammar. +0 -0
- data/lib/treetop/runtime/parse_failure.rb +0 -32
- data/lib/treetop/runtime/parse_result.rb +0 -30
data/README
CHANGED
@@ -26,7 +26,7 @@ The first rule becomes the *root* of the grammar, causing its expression to be m
|
|
26
26
|
# use_grammar.rb
|
27
27
|
require 'rubygems'
|
28
28
|
require 'treetop'
|
29
|
-
|
29
|
+
Treetop.load 'my_grammar'
|
30
30
|
|
31
31
|
parser = MyGrammarParser.new
|
32
32
|
puts parser.parse('hello chomsky').success? # => true
|
data/Rakefile
CHANGED
@@ -15,7 +15,7 @@ end
|
|
15
15
|
|
16
16
|
gemspec = Gem::Specification.new do |s|
|
17
17
|
s.name = "treetop"
|
18
|
-
s.version = "1.
|
18
|
+
s.version = "1.2.0"
|
19
19
|
s.author = "Nathan Sobo"
|
20
20
|
s.email = "nathansobo@gmail.com"
|
21
21
|
s.homepage = "http://functionalform.blogspot.com"
|
@@ -28,8 +28,9 @@ gemspec = Gem::Specification.new do |s|
|
|
28
28
|
s.autorequire = "treetop"
|
29
29
|
s.has_rdoc = false
|
30
30
|
s.add_dependency "facets", ">=2.0.2"
|
31
|
+
s.add_dependency "polyglot"
|
31
32
|
end
|
32
33
|
|
33
34
|
Rake::GemPackageTask.new(gemspec) do |pkg|
|
34
35
|
pkg.need_tar = true
|
35
|
-
end
|
36
|
+
end
|
@@ -15,7 +15,7 @@ Due to shortcomings in Ruby's semantics that scope constant definitions in a blo
|
|
15
15
|
##Small Stuff
|
16
16
|
* Migrate the tests back to RSpec.
|
17
17
|
* Improve the `tt` command line tool to allow `.treetop` extensions to be elided in its arguments.
|
18
|
-
* Generate and load temp files with `
|
18
|
+
* Generate and load temp files with `Treetop.load` rather than evaluating strings to improve stack trace readability.
|
19
19
|
* Allow `do/end` style blocks as well as curly brace blocks. This was originally omitted because I thought it would be confusing. It probably isn't.
|
20
20
|
* Allow the root of a grammar to be dynamically set for testing purposes.
|
21
21
|
|
data/doc/using_in_ruby.markdown
CHANGED
@@ -6,12 +6,12 @@ You can `.treetop` files into Ruby source code with the `tt` command line script
|
|
6
6
|
tt foo.treetop -o foogrammar.rb
|
7
7
|
|
8
8
|
##Loading A Grammar Directly
|
9
|
-
The `
|
9
|
+
The `Treetop.load` 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
10
|
|
11
11
|
##Instantiating and Using Parsers
|
12
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
13
|
|
14
|
-
|
14
|
+
Treetop.load "arithmetic"
|
15
15
|
|
16
16
|
parser = ArithmeticParser.new
|
17
17
|
puts parser.parse('1+1').success?
|
@@ -0,0 +1,551 @@
|
|
1
|
+
module Arithmetic
|
2
|
+
include Treetop::Runtime
|
3
|
+
|
4
|
+
def root
|
5
|
+
@root || :expression
|
6
|
+
end
|
7
|
+
|
8
|
+
def _nt_expression
|
9
|
+
start_index = index
|
10
|
+
cached = node_cache[:expression][index]
|
11
|
+
if cached
|
12
|
+
@index = cached.interval.end
|
13
|
+
return cached
|
14
|
+
end
|
15
|
+
|
16
|
+
i0 = index
|
17
|
+
r1 = _nt_comparative
|
18
|
+
if r1.success?
|
19
|
+
r0 = r1
|
20
|
+
else
|
21
|
+
r2 = _nt_additive
|
22
|
+
if r2.success?
|
23
|
+
r0 = r2
|
24
|
+
else
|
25
|
+
self.index = i0
|
26
|
+
r0 = ParseFailure.new(input, i0)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
node_cache[:expression][start_index] = r0
|
31
|
+
|
32
|
+
return r0
|
33
|
+
end
|
34
|
+
|
35
|
+
module Comparative0
|
36
|
+
def operand_1
|
37
|
+
elements[0]
|
38
|
+
end
|
39
|
+
|
40
|
+
def space
|
41
|
+
elements[1]
|
42
|
+
end
|
43
|
+
|
44
|
+
def operator
|
45
|
+
elements[2]
|
46
|
+
end
|
47
|
+
|
48
|
+
def space
|
49
|
+
elements[3]
|
50
|
+
end
|
51
|
+
|
52
|
+
def operand_2
|
53
|
+
elements[4]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def _nt_comparative
|
58
|
+
start_index = index
|
59
|
+
cached = node_cache[:comparative][index]
|
60
|
+
if cached
|
61
|
+
@index = cached.interval.end
|
62
|
+
return cached
|
63
|
+
end
|
64
|
+
|
65
|
+
i0, s0 = index, []
|
66
|
+
r1 = _nt_additive
|
67
|
+
s0 << r1
|
68
|
+
if r1.success?
|
69
|
+
r2 = _nt_space
|
70
|
+
s0 << r2
|
71
|
+
if r2.success?
|
72
|
+
r3 = _nt_equality_op
|
73
|
+
s0 << r3
|
74
|
+
if r3.success?
|
75
|
+
r4 = _nt_space
|
76
|
+
s0 << r4
|
77
|
+
if r4.success?
|
78
|
+
r5 = _nt_additive
|
79
|
+
s0 << r5
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
if s0.last.success?
|
85
|
+
r0 = (BinaryOperation).new(input, i0...index, s0)
|
86
|
+
r0.extend(Comparative0)
|
87
|
+
else
|
88
|
+
self.index = i0
|
89
|
+
r0 = ParseFailure.new(input, i0)
|
90
|
+
end
|
91
|
+
|
92
|
+
node_cache[:comparative][start_index] = r0
|
93
|
+
|
94
|
+
return r0
|
95
|
+
end
|
96
|
+
|
97
|
+
module EqualityOp0
|
98
|
+
def apply(a, b)
|
99
|
+
a == b
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def _nt_equality_op
|
104
|
+
start_index = index
|
105
|
+
cached = node_cache[:equality_op][index]
|
106
|
+
if cached
|
107
|
+
@index = cached.interval.end
|
108
|
+
return cached
|
109
|
+
end
|
110
|
+
|
111
|
+
r0 = parse_terminal('==', SyntaxNode, EqualityOp0)
|
112
|
+
|
113
|
+
node_cache[:equality_op][start_index] = r0
|
114
|
+
|
115
|
+
return r0
|
116
|
+
end
|
117
|
+
|
118
|
+
module Additive0
|
119
|
+
def operand_1
|
120
|
+
elements[0]
|
121
|
+
end
|
122
|
+
|
123
|
+
def space
|
124
|
+
elements[1]
|
125
|
+
end
|
126
|
+
|
127
|
+
def operator
|
128
|
+
elements[2]
|
129
|
+
end
|
130
|
+
|
131
|
+
def space
|
132
|
+
elements[3]
|
133
|
+
end
|
134
|
+
|
135
|
+
def operand_2
|
136
|
+
elements[4]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def _nt_additive
|
141
|
+
start_index = index
|
142
|
+
cached = node_cache[:additive][index]
|
143
|
+
if cached
|
144
|
+
@index = cached.interval.end
|
145
|
+
return cached
|
146
|
+
end
|
147
|
+
|
148
|
+
i0 = index
|
149
|
+
i1, s1 = index, []
|
150
|
+
r2 = _nt_multitive
|
151
|
+
s1 << r2
|
152
|
+
if r2.success?
|
153
|
+
r3 = _nt_space
|
154
|
+
s1 << r3
|
155
|
+
if r3.success?
|
156
|
+
r4 = _nt_additive_op
|
157
|
+
s1 << r4
|
158
|
+
if r4.success?
|
159
|
+
r5 = _nt_space
|
160
|
+
s1 << r5
|
161
|
+
if r5.success?
|
162
|
+
r6 = _nt_additive
|
163
|
+
s1 << r6
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
if s1.last.success?
|
169
|
+
r1 = (BinaryOperation).new(input, i1...index, s1)
|
170
|
+
r1.extend(Additive0)
|
171
|
+
else
|
172
|
+
self.index = i1
|
173
|
+
r1 = ParseFailure.new(input, i1)
|
174
|
+
end
|
175
|
+
if r1.success?
|
176
|
+
r0 = r1
|
177
|
+
else
|
178
|
+
r7 = _nt_multitive
|
179
|
+
if r7.success?
|
180
|
+
r0 = r7
|
181
|
+
else
|
182
|
+
self.index = i0
|
183
|
+
r0 = ParseFailure.new(input, i0)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
node_cache[:additive][start_index] = r0
|
188
|
+
|
189
|
+
return r0
|
190
|
+
end
|
191
|
+
|
192
|
+
module AdditiveOp0
|
193
|
+
def apply(a, b)
|
194
|
+
a + b
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
module AdditiveOp1
|
199
|
+
def apply(a, b)
|
200
|
+
a - b
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def _nt_additive_op
|
205
|
+
start_index = index
|
206
|
+
cached = node_cache[:additive_op][index]
|
207
|
+
if cached
|
208
|
+
@index = cached.interval.end
|
209
|
+
return cached
|
210
|
+
end
|
211
|
+
|
212
|
+
i0 = index
|
213
|
+
r1 = parse_terminal('+', SyntaxNode, AdditiveOp0)
|
214
|
+
if r1.success?
|
215
|
+
r0 = r1
|
216
|
+
else
|
217
|
+
r2 = parse_terminal('-', SyntaxNode, AdditiveOp1)
|
218
|
+
if r2.success?
|
219
|
+
r0 = r2
|
220
|
+
else
|
221
|
+
self.index = i0
|
222
|
+
r0 = ParseFailure.new(input, i0)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
node_cache[:additive_op][start_index] = r0
|
227
|
+
|
228
|
+
return r0
|
229
|
+
end
|
230
|
+
|
231
|
+
module Multitive0
|
232
|
+
def operand_1
|
233
|
+
elements[0]
|
234
|
+
end
|
235
|
+
|
236
|
+
def space
|
237
|
+
elements[1]
|
238
|
+
end
|
239
|
+
|
240
|
+
def operator
|
241
|
+
elements[2]
|
242
|
+
end
|
243
|
+
|
244
|
+
def space
|
245
|
+
elements[3]
|
246
|
+
end
|
247
|
+
|
248
|
+
def operand_2
|
249
|
+
elements[4]
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def _nt_multitive
|
254
|
+
start_index = index
|
255
|
+
cached = node_cache[:multitive][index]
|
256
|
+
if cached
|
257
|
+
@index = cached.interval.end
|
258
|
+
return cached
|
259
|
+
end
|
260
|
+
|
261
|
+
i0 = index
|
262
|
+
i1, s1 = index, []
|
263
|
+
r2 = _nt_primary
|
264
|
+
s1 << r2
|
265
|
+
if r2.success?
|
266
|
+
r3 = _nt_space
|
267
|
+
s1 << r3
|
268
|
+
if r3.success?
|
269
|
+
r4 = _nt_multitive_op
|
270
|
+
s1 << r4
|
271
|
+
if r4.success?
|
272
|
+
r5 = _nt_space
|
273
|
+
s1 << r5
|
274
|
+
if r5.success?
|
275
|
+
r6 = _nt_multitive
|
276
|
+
s1 << r6
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
if s1.last.success?
|
282
|
+
r1 = (BinaryOperation).new(input, i1...index, s1)
|
283
|
+
r1.extend(Multitive0)
|
284
|
+
else
|
285
|
+
self.index = i1
|
286
|
+
r1 = ParseFailure.new(input, i1)
|
287
|
+
end
|
288
|
+
if r1.success?
|
289
|
+
r0 = r1
|
290
|
+
else
|
291
|
+
r7 = _nt_primary
|
292
|
+
if r7.success?
|
293
|
+
r0 = r7
|
294
|
+
else
|
295
|
+
self.index = i0
|
296
|
+
r0 = ParseFailure.new(input, i0)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
node_cache[:multitive][start_index] = r0
|
301
|
+
|
302
|
+
return r0
|
303
|
+
end
|
304
|
+
|
305
|
+
module MultitiveOp0
|
306
|
+
def apply(a, b)
|
307
|
+
a * b
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
module MultitiveOp1
|
312
|
+
def apply(a, b)
|
313
|
+
a / b
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def _nt_multitive_op
|
318
|
+
start_index = index
|
319
|
+
cached = node_cache[:multitive_op][index]
|
320
|
+
if cached
|
321
|
+
@index = cached.interval.end
|
322
|
+
return cached
|
323
|
+
end
|
324
|
+
|
325
|
+
i0 = index
|
326
|
+
r1 = parse_terminal('*', SyntaxNode, MultitiveOp0)
|
327
|
+
if r1.success?
|
328
|
+
r0 = r1
|
329
|
+
else
|
330
|
+
r2 = parse_terminal('/', SyntaxNode, MultitiveOp1)
|
331
|
+
if r2.success?
|
332
|
+
r0 = r2
|
333
|
+
else
|
334
|
+
self.index = i0
|
335
|
+
r0 = ParseFailure.new(input, i0)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
node_cache[:multitive_op][start_index] = r0
|
340
|
+
|
341
|
+
return r0
|
342
|
+
end
|
343
|
+
|
344
|
+
module Primary0
|
345
|
+
def space
|
346
|
+
elements[1]
|
347
|
+
end
|
348
|
+
|
349
|
+
def expression
|
350
|
+
elements[2]
|
351
|
+
end
|
352
|
+
|
353
|
+
def space
|
354
|
+
elements[3]
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|
358
|
+
|
359
|
+
module Primary1
|
360
|
+
def eval(env={})
|
361
|
+
expression.eval(env)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
def _nt_primary
|
366
|
+
start_index = index
|
367
|
+
cached = node_cache[:primary][index]
|
368
|
+
if cached
|
369
|
+
@index = cached.interval.end
|
370
|
+
return cached
|
371
|
+
end
|
372
|
+
|
373
|
+
i0 = index
|
374
|
+
r1 = _nt_variable
|
375
|
+
if r1.success?
|
376
|
+
r0 = r1
|
377
|
+
else
|
378
|
+
r2 = _nt_number
|
379
|
+
if r2.success?
|
380
|
+
r0 = r2
|
381
|
+
else
|
382
|
+
i3, s3 = index, []
|
383
|
+
r4 = parse_terminal('(', SyntaxNode)
|
384
|
+
s3 << r4
|
385
|
+
if r4.success?
|
386
|
+
r5 = _nt_space
|
387
|
+
s3 << r5
|
388
|
+
if r5.success?
|
389
|
+
r6 = _nt_expression
|
390
|
+
s3 << r6
|
391
|
+
if r6.success?
|
392
|
+
r7 = _nt_space
|
393
|
+
s3 << r7
|
394
|
+
if r7.success?
|
395
|
+
r8 = parse_terminal(')', SyntaxNode)
|
396
|
+
s3 << r8
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
if s3.last.success?
|
402
|
+
r3 = (SyntaxNode).new(input, i3...index, s3)
|
403
|
+
r3.extend(Primary0)
|
404
|
+
r3.extend(Primary1)
|
405
|
+
else
|
406
|
+
self.index = i3
|
407
|
+
r3 = ParseFailure.new(input, i3)
|
408
|
+
end
|
409
|
+
if r3.success?
|
410
|
+
r0 = r3
|
411
|
+
else
|
412
|
+
self.index = i0
|
413
|
+
r0 = ParseFailure.new(input, i0)
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
node_cache[:primary][start_index] = r0
|
419
|
+
|
420
|
+
return r0
|
421
|
+
end
|
422
|
+
|
423
|
+
module Variable0
|
424
|
+
def eval(env={})
|
425
|
+
env[name]
|
426
|
+
end
|
427
|
+
|
428
|
+
def name
|
429
|
+
text_value
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
def _nt_variable
|
434
|
+
start_index = index
|
435
|
+
cached = node_cache[:variable][index]
|
436
|
+
if cached
|
437
|
+
@index = cached.interval.end
|
438
|
+
return cached
|
439
|
+
end
|
440
|
+
|
441
|
+
s0, i0 = [], index
|
442
|
+
loop do
|
443
|
+
r1 = parse_char_class(/[a-z]/, 'a-z', SyntaxNode)
|
444
|
+
if r1.success?
|
445
|
+
s0 << r1
|
446
|
+
else
|
447
|
+
break
|
448
|
+
end
|
449
|
+
end
|
450
|
+
if s0.empty?
|
451
|
+
self.index = i0
|
452
|
+
r0 = ParseFailure.new(input, i0)
|
453
|
+
else
|
454
|
+
r0 = SyntaxNode.new(input, i0...index, s0)
|
455
|
+
r0.extend(Variable0)
|
456
|
+
end
|
457
|
+
|
458
|
+
node_cache[:variable][start_index] = r0
|
459
|
+
|
460
|
+
return r0
|
461
|
+
end
|
462
|
+
|
463
|
+
module Number0
|
464
|
+
end
|
465
|
+
|
466
|
+
module Number1
|
467
|
+
def eval(env={})
|
468
|
+
text_value.to_i
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
def _nt_number
|
473
|
+
start_index = index
|
474
|
+
cached = node_cache[:number][index]
|
475
|
+
if cached
|
476
|
+
@index = cached.interval.end
|
477
|
+
return cached
|
478
|
+
end
|
479
|
+
|
480
|
+
i0 = index
|
481
|
+
i1, s1 = index, []
|
482
|
+
r2 = parse_char_class(/[1-9]/, '1-9', SyntaxNode)
|
483
|
+
s1 << r2
|
484
|
+
if r2.success?
|
485
|
+
s3, i3 = [], index
|
486
|
+
loop do
|
487
|
+
r4 = parse_char_class(/[0-9]/, '0-9', SyntaxNode)
|
488
|
+
if r4.success?
|
489
|
+
s3 << r4
|
490
|
+
else
|
491
|
+
break
|
492
|
+
end
|
493
|
+
end
|
494
|
+
r3 = SyntaxNode.new(input, i3...index, s3)
|
495
|
+
s1 << r3
|
496
|
+
end
|
497
|
+
if s1.last.success?
|
498
|
+
r1 = (SyntaxNode).new(input, i1...index, s1)
|
499
|
+
r1.extend(Number0)
|
500
|
+
else
|
501
|
+
self.index = i1
|
502
|
+
r1 = ParseFailure.new(input, i1)
|
503
|
+
end
|
504
|
+
if r1.success?
|
505
|
+
r0 = r1
|
506
|
+
r0.extend(Number1)
|
507
|
+
else
|
508
|
+
r5 = parse_terminal('0', SyntaxNode)
|
509
|
+
if r5.success?
|
510
|
+
r0 = r5
|
511
|
+
r0.extend(Number1)
|
512
|
+
else
|
513
|
+
self.index = i0
|
514
|
+
r0 = ParseFailure.new(input, i0)
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
node_cache[:number][start_index] = r0
|
519
|
+
|
520
|
+
return r0
|
521
|
+
end
|
522
|
+
|
523
|
+
def _nt_space
|
524
|
+
start_index = index
|
525
|
+
cached = node_cache[:space][index]
|
526
|
+
if cached
|
527
|
+
@index = cached.interval.end
|
528
|
+
return cached
|
529
|
+
end
|
530
|
+
|
531
|
+
s0, i0 = [], index
|
532
|
+
loop do
|
533
|
+
r1 = parse_terminal(' ', SyntaxNode)
|
534
|
+
if r1.success?
|
535
|
+
s0 << r1
|
536
|
+
else
|
537
|
+
break
|
538
|
+
end
|
539
|
+
end
|
540
|
+
r0 = SyntaxNode.new(input, i0...index, s0)
|
541
|
+
|
542
|
+
node_cache[:space][start_index] = r0
|
543
|
+
|
544
|
+
return r0
|
545
|
+
end
|
546
|
+
|
547
|
+
end
|
548
|
+
|
549
|
+
class ArithmeticParser < Treetop::Runtime::CompiledParser
|
550
|
+
include Arithmetic
|
551
|
+
end
|