treetop 1.6.3 → 1.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/lib/treetop/compiler/metagrammar.rb +150 -72
- data/lib/treetop/compiler/metagrammar.treetop +57 -3
- data/lib/treetop/compiler/node_classes/anything_symbol.rb +1 -1
- data/lib/treetop/compiler/node_classes/character_class.rb +1 -1
- data/lib/treetop/compiler/node_classes/choice.rb +5 -5
- data/lib/treetop/compiler/node_classes/nonterminal.rb +2 -2
- data/lib/treetop/compiler/node_classes/parsing_expression.rb +8 -2
- data/lib/treetop/compiler/node_classes/predicate.rb +1 -1
- data/lib/treetop/compiler/node_classes/repetition.rb +7 -7
- data/lib/treetop/compiler/node_classes/sequence.rb +1 -1
- data/lib/treetop/compiler/node_classes/terminal.rb +7 -1
- data/lib/treetop/runtime/syntax_node.rb +20 -13
- data/lib/treetop/version.rb +1 -1
- data/spec/compiler/choice_spec.rb +19 -10
- data/spec/compiler/grammar_compiler_spec.rb +1 -1
- data/spec/compiler/parenthesized_expression_spec.rb +12 -0
- data/spec/compiler/terminal_spec.rb +3 -3
- data/spec/compiler/tt_compiler_spec.rb +3 -3
- data/spec/compiler/zero_or_more_spec.rb +2 -0
- data/treetop.gemspec +3 -7
- metadata +2 -6
- data/examples/inner_outer.rb +0 -51
- data/examples/inner_outer.tt +0 -14
- data/examples/numerals.rb +0 -210
- data/examples/numerals.tt +0 -21
@@ -84,6 +84,10 @@ module Treetop
|
|
84
84
|
super.elements.map {|elt| elt.alternative}
|
85
85
|
end
|
86
86
|
|
87
|
+
def parent_modules
|
88
|
+
[]
|
89
|
+
end
|
90
|
+
|
87
91
|
def inline_modules
|
88
92
|
(alternatives.map {|alt| alt.inline_modules }).flatten
|
89
93
|
end
|
@@ -100,10 +104,14 @@ module Treetop
|
|
100
104
|
sequence_body.tail
|
101
105
|
end
|
102
106
|
|
107
|
+
def parent_modules
|
108
|
+
node_class_declarations.inline_modules
|
109
|
+
end
|
110
|
+
|
103
111
|
def inline_modules
|
104
112
|
(sequence_elements.map {|elt| elt.inline_modules}).flatten +
|
105
113
|
[sequence_element_accessor_module] +
|
106
|
-
|
114
|
+
parent_modules
|
107
115
|
end
|
108
116
|
|
109
117
|
def inline_module_name
|
@@ -150,6 +158,10 @@ module Treetop
|
|
150
158
|
atomic
|
151
159
|
end
|
152
160
|
|
161
|
+
def parent_modules
|
162
|
+
[]
|
163
|
+
end
|
164
|
+
|
153
165
|
def inline_modules
|
154
166
|
atomic.inline_modules
|
155
167
|
end
|
@@ -166,6 +178,9 @@ module Treetop
|
|
166
178
|
def prefixed_expression
|
167
179
|
atomic
|
168
180
|
end
|
181
|
+
def parent_modules
|
182
|
+
[]
|
183
|
+
end
|
169
184
|
def inline_modules
|
170
185
|
[]
|
171
186
|
end
|
@@ -173,6 +188,7 @@ module Treetop
|
|
173
188
|
/
|
174
189
|
atomic suffix node_class_declarations {
|
175
190
|
def compile(address, builder, parent_expression=nil)
|
191
|
+
STDERR.puts "Extraneous module ignored after suffix: #{input[interval].inspect}" if node_class_declarations.inline_modules.size > 0 && atomic.inline_modules.size > 0
|
176
192
|
suffix.compile(address, builder, self)
|
177
193
|
end
|
178
194
|
|
@@ -184,8 +200,12 @@ module Treetop
|
|
184
200
|
node_class_declarations.node_class_name
|
185
201
|
end
|
186
202
|
|
203
|
+
def parent_modules
|
204
|
+
node_class_declarations.inline_modules
|
205
|
+
end
|
206
|
+
|
187
207
|
def inline_modules
|
188
|
-
atomic.inline_modules +
|
208
|
+
atomic.inline_modules + parent_modules
|
189
209
|
end
|
190
210
|
|
191
211
|
def inline_module_name
|
@@ -195,6 +215,7 @@ module Treetop
|
|
195
215
|
/
|
196
216
|
atomic node_class_declarations {
|
197
217
|
def compile(address, builder, parent_expression=nil)
|
218
|
+
STDERR.puts "Extraneous module ignored with nested atomic: #{input[interval].inspect}" if node_class_declarations.inline_modules.size > 0 && atomic.inline_modules.size > 0
|
198
219
|
atomic.compile(address, builder, self)
|
199
220
|
end
|
200
221
|
|
@@ -202,8 +223,12 @@ module Treetop
|
|
202
223
|
node_class_declarations.node_class_name
|
203
224
|
end
|
204
225
|
|
226
|
+
def parent_modules
|
227
|
+
node_class_declarations.inline_modules
|
228
|
+
end
|
229
|
+
|
205
230
|
def inline_modules
|
206
|
-
atomic.inline_modules +
|
231
|
+
atomic.inline_modules + parent_modules
|
207
232
|
end
|
208
233
|
|
209
234
|
def inline_module_name
|
@@ -222,6 +247,10 @@ module Treetop
|
|
222
247
|
sequence_primary.compile(lexical_address, builder)
|
223
248
|
end
|
224
249
|
|
250
|
+
def parent_modules
|
251
|
+
[]
|
252
|
+
end
|
253
|
+
|
225
254
|
def inline_modules
|
226
255
|
sequence_primary.inline_modules
|
227
256
|
end
|
@@ -238,6 +267,10 @@ module Treetop
|
|
238
267
|
sequence_primary.compile(lexical_address, builder)
|
239
268
|
end
|
240
269
|
|
270
|
+
def parent_modules
|
271
|
+
[]
|
272
|
+
end
|
273
|
+
|
241
274
|
def inline_modules
|
242
275
|
sequence_primary.inline_modules
|
243
276
|
end
|
@@ -282,6 +315,10 @@ module Treetop
|
|
282
315
|
elements[1]
|
283
316
|
end
|
284
317
|
|
318
|
+
def parent_modules
|
319
|
+
[]
|
320
|
+
end
|
321
|
+
|
285
322
|
def inline_modules
|
286
323
|
atomic.inline_modules
|
287
324
|
end
|
@@ -298,6 +335,9 @@ module Treetop
|
|
298
335
|
def prefixed_expression
|
299
336
|
atomic
|
300
337
|
end
|
338
|
+
def parent_modules
|
339
|
+
[]
|
340
|
+
end
|
301
341
|
def inline_modules
|
302
342
|
[]
|
303
343
|
end
|
@@ -312,6 +352,10 @@ module Treetop
|
|
312
352
|
nil
|
313
353
|
end
|
314
354
|
|
355
|
+
def parent_modules
|
356
|
+
[]
|
357
|
+
end
|
358
|
+
|
315
359
|
def inline_modules
|
316
360
|
atomic.inline_modules
|
317
361
|
end
|
@@ -338,6 +382,7 @@ module Treetop
|
|
338
382
|
node_class_expression.node_class_name
|
339
383
|
end
|
340
384
|
|
385
|
+
# !!!! cjh !!!!!
|
341
386
|
def inline_modules
|
342
387
|
trailing_inline_module.inline_modules
|
343
388
|
end
|
@@ -374,6 +419,9 @@ module Treetop
|
|
374
419
|
|
375
420
|
rule parenthesized_expression
|
376
421
|
'(' space? parsing_expression space? ')' <ParenthesizedExpression> {
|
422
|
+
def parent_modules
|
423
|
+
[]
|
424
|
+
end
|
377
425
|
def inline_modules
|
378
426
|
parsing_expression.inline_modules
|
379
427
|
end
|
@@ -439,6 +487,9 @@ module Treetop
|
|
439
487
|
|
440
488
|
rule trailing_inline_module
|
441
489
|
space inline_module {
|
490
|
+
def parent_modules
|
491
|
+
[]
|
492
|
+
end
|
442
493
|
def inline_modules
|
443
494
|
[inline_module]
|
444
495
|
end
|
@@ -449,6 +500,9 @@ module Treetop
|
|
449
500
|
}
|
450
501
|
/
|
451
502
|
'' {
|
503
|
+
def parent_modules
|
504
|
+
[]
|
505
|
+
end
|
452
506
|
def inline_modules
|
453
507
|
[]
|
454
508
|
end
|
@@ -6,7 +6,7 @@ module Treetop
|
|
6
6
|
builder.if__ "index < input_length" do
|
7
7
|
if address == 0 || decorated?
|
8
8
|
assign_result "instantiate_node(#{node_class_name},input, index...(index + 1))"
|
9
|
-
extend_result_with_inline_module
|
9
|
+
extend_result_with_inline_module parent_expression
|
10
10
|
else
|
11
11
|
assign_lazily_instantiated_node
|
12
12
|
end
|
@@ -7,7 +7,7 @@ module Treetop
|
|
7
7
|
builder.if__ "has_terminal?(@regexps[gr = #{grounded_regexp(text_value)}] ||= Regexp.new(gr), :regexp, index)" do
|
8
8
|
if address == 0 || decorated?
|
9
9
|
assign_result "instantiate_node(#{node_class_name},input, index...(index + 1))"
|
10
|
-
extend_result_with_inline_module
|
10
|
+
extend_result_with_inline_module parent_expression
|
11
11
|
else
|
12
12
|
assign_lazily_instantiated_node
|
13
13
|
end
|
@@ -5,11 +5,11 @@ module Treetop
|
|
5
5
|
super
|
6
6
|
begin_comment(self)
|
7
7
|
use_vars :result, :start_index
|
8
|
-
compile_alternatives(alternatives)
|
8
|
+
compile_alternatives(alternatives, parent_expression)
|
9
9
|
end_comment(self)
|
10
10
|
end
|
11
|
-
|
12
|
-
def compile_alternatives(alternatives)
|
11
|
+
|
12
|
+
def compile_alternatives(alternatives, parent_expression)
|
13
13
|
obtain_new_subexpression_address
|
14
14
|
alternatives.first.compile(subexpression_address, builder)
|
15
15
|
builder.if__ subexpression_success? do
|
@@ -17,14 +17,14 @@ module Treetop
|
|
17
17
|
builder << "#{subexpression_result_var} = SyntaxNode.new(input, (index-1)...index) if #{subexpression_result_var} == true"
|
18
18
|
assign_result subexpression_result_var
|
19
19
|
extend_result_with_declared_module
|
20
|
-
extend_result_with_inline_module
|
20
|
+
extend_result_with_inline_module parent_expression
|
21
21
|
end
|
22
22
|
builder.else_ do
|
23
23
|
if alternatives.size == 1
|
24
24
|
reset_index
|
25
25
|
assign_failure start_index_var
|
26
26
|
else
|
27
|
-
compile_alternatives(alternatives[1..-1])
|
27
|
+
compile_alternatives(alternatives[1..-1], parent_expression)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -6,8 +6,8 @@ module Treetop
|
|
6
6
|
use_vars :result
|
7
7
|
assign_result text_value == 'super' ? 'super' : "_nt_#{text_value}"
|
8
8
|
extend_result_with_declared_module
|
9
|
-
extend_result_with_inline_module
|
9
|
+
extend_result_with_inline_module parent_expression
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
13
|
-
end
|
13
|
+
end
|
@@ -78,8 +78,14 @@ module Treetop
|
|
78
78
|
extend_result declared_module_name if declared_module_name
|
79
79
|
end
|
80
80
|
|
81
|
-
def extend_result_with_inline_module
|
82
|
-
|
81
|
+
def extend_result_with_inline_module parent_expression = nil
|
82
|
+
# debugger if parent_expression && !parent_expression.respond_to?(:parent_modules)
|
83
|
+
if parent_expression && parent_expression.parent_modules.size > 0
|
84
|
+
parent_expression.parent_modules.each do |inline|
|
85
|
+
extend_result inline.module_name
|
86
|
+
end
|
87
|
+
end
|
88
|
+
extend_result inline_module_name if inline_module_name
|
83
89
|
end
|
84
90
|
|
85
91
|
def reset_index
|
@@ -28,9 +28,9 @@ module Treetop
|
|
28
28
|
parent_expression.inline_module_name
|
29
29
|
end
|
30
30
|
|
31
|
-
def assign_and_extend_result
|
31
|
+
def assign_and_extend_result parent_expression
|
32
32
|
assign_result "instantiate_node(#{node_class_name},input, #{start_index_var}...index, #{accumulator_var})"
|
33
|
-
extend_result_with_inline_module
|
33
|
+
extend_result_with_inline_module parent_expression
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -38,7 +38,7 @@ module Treetop
|
|
38
38
|
class ZeroOrMore < Repetition
|
39
39
|
def compile(address, builder, parent_expression)
|
40
40
|
super
|
41
|
-
assign_and_extend_result
|
41
|
+
assign_and_extend_result parent_expression
|
42
42
|
end_comment(parent_expression)
|
43
43
|
end
|
44
44
|
|
@@ -55,7 +55,7 @@ module Treetop
|
|
55
55
|
assign_failure start_index_var
|
56
56
|
end
|
57
57
|
builder.else_ do
|
58
|
-
assign_and_extend_result
|
58
|
+
assign_and_extend_result parent_expression
|
59
59
|
end
|
60
60
|
end_comment(parent_expression)
|
61
61
|
end
|
@@ -81,11 +81,11 @@ module Treetop
|
|
81
81
|
end
|
82
82
|
builder.else_ do
|
83
83
|
clean_unsaturated
|
84
|
-
assign_and_extend_result
|
84
|
+
assign_and_extend_result parent_expression
|
85
85
|
end
|
86
86
|
else
|
87
87
|
clean_unsaturated
|
88
|
-
assign_and_extend_result
|
88
|
+
assign_and_extend_result parent_expression
|
89
89
|
end
|
90
90
|
|
91
91
|
end_comment(parent_expression)
|
@@ -95,7 +95,7 @@ module Treetop
|
|
95
95
|
def clean_unsaturated
|
96
96
|
if !max.empty? && max.text_value.to_i > 0
|
97
97
|
builder.if_ "#{accumulator_var}.size < #{max.text_value}" do
|
98
|
-
builder << 'terminal_failures.pop' # Ignore the last failure.
|
98
|
+
builder << '@terminal_failures.pop' # Ignore the last failure.
|
99
99
|
end
|
100
100
|
end
|
101
101
|
end
|
@@ -9,7 +9,7 @@ module Treetop
|
|
9
9
|
builder.if__ "#{accumulator_var}.last" do
|
10
10
|
assign_result "instantiate_node(#{node_class_name},input, #{start_index_var}...index, #{accumulator_var})"
|
11
11
|
extend_result sequence_element_accessor_module_name if sequence_element_accessor_module_name
|
12
|
-
extend_result_with_inline_module
|
12
|
+
extend_result_with_inline_module parent_expression
|
13
13
|
end
|
14
14
|
builder.else_ do
|
15
15
|
reset_index
|
@@ -25,7 +25,13 @@ module Treetop
|
|
25
25
|
builder.if__ "(match_len = has_terminal?(#{str}, #{mode}, index))" do
|
26
26
|
if address == 0 || decorated? || mode != 'false' || string_length > 1
|
27
27
|
assign_result "instantiate_node(#{node_class_name},input, index...(index + match_len))"
|
28
|
-
|
28
|
+
# debugger if parent_expression and parent_expression.inline_modules.size > 0
|
29
|
+
# extend_result_with_inline_module parent_expression
|
30
|
+
if parent_expression
|
31
|
+
parent_expression.inline_modules.each do |inline|
|
32
|
+
extend_result inline.module_name
|
33
|
+
end
|
34
|
+
end
|
29
35
|
else
|
30
36
|
assign_lazily_instantiated_node
|
31
37
|
end
|
@@ -60,7 +60,7 @@ module Treetop
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
def
|
63
|
+
def inspect_self(indent="")
|
64
64
|
em = extension_modules
|
65
65
|
interesting_methods = methods-[em.last ? em.last.methods : nil]-self.class.instance_methods
|
66
66
|
im = interesting_methods.size > 0 ? " (#{interesting_methods.join(",")})" : ""
|
@@ -72,18 +72,25 @@ module Treetop
|
|
72
72
|
em.map{|m| "+"+m.to_s.sub(/.*:/,'')}*"" +
|
73
73
|
" offset=#{interval.first}" +
|
74
74
|
", #{tv.inspect}" +
|
75
|
-
im
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
75
|
+
im
|
76
|
+
end
|
77
|
+
|
78
|
+
def inspect_children(indent="")
|
79
|
+
return '' unless elements && elements.size > 0
|
80
|
+
":" +
|
81
|
+
elements.map do |e|
|
82
|
+
begin
|
83
|
+
"\n"+e.inspect(indent+" ")
|
84
|
+
rescue # Defend against inspect not taking a parameter
|
85
|
+
"\n"+indent+" "+e.inspect
|
86
|
+
end
|
87
|
+
end.
|
88
|
+
join("")
|
89
|
+
end
|
90
|
+
|
91
|
+
def inspect(indent="")
|
92
|
+
inspect_self(indent) +
|
93
|
+
inspect_children(indent)
|
87
94
|
end
|
88
95
|
|
89
96
|
@@dot_id_counter = 0
|
data/lib/treetop/version.rb
CHANGED
@@ -2,22 +2,31 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module ChoiceSpec
|
4
4
|
describe "A choice between terminal symbols" do
|
5
|
-
testing_expression '"foo" { def foo_method; end } / "bar" { def bar_method; end } / "baz" { def baz_method; end }'
|
5
|
+
testing_expression '("foo" { def foo_method; end } / "bar" { def bar_method; end } / "baz" { def baz_method; end }) {def bat_method; end}'
|
6
6
|
|
7
7
|
it "successfully parses input matching any of the alternatives, returning a node that responds to methods defined in its respective inline module" do
|
8
8
|
result = parse('foo')
|
9
9
|
result.should_not be_nil
|
10
10
|
result.should respond_to(:foo_method)
|
11
|
-
|
11
|
+
result.should_not respond_to(:bar_method)
|
12
|
+
result.should_not respond_to(:baz_method)
|
13
|
+
result.should respond_to(:bat_method)
|
14
|
+
|
12
15
|
result = parse('bar')
|
13
16
|
result.should_not be_nil
|
17
|
+
result.should_not respond_to(:foo_method)
|
14
18
|
result.should respond_to(:bar_method)
|
15
|
-
|
19
|
+
result.should_not respond_to(:baz_method)
|
20
|
+
result.should respond_to(:bat_method)
|
21
|
+
|
16
22
|
result = parse('baz')
|
17
23
|
result.should_not be_nil
|
24
|
+
result.should_not respond_to(:foo_method)
|
25
|
+
result.should_not respond_to(:bar_method)
|
18
26
|
result.should respond_to(:baz_method)
|
27
|
+
result.should respond_to(:bat_method)
|
19
28
|
end
|
20
|
-
|
29
|
+
|
21
30
|
it "upon parsing a string matching the second alternative, records the failure of the first terminal" do
|
22
31
|
result = parse('bar')
|
23
32
|
terminal_failures = parser.terminal_failures
|
@@ -26,18 +35,18 @@ module ChoiceSpec
|
|
26
35
|
failure.expected_string.should == '"foo"'
|
27
36
|
failure.index.should == 0
|
28
37
|
end
|
29
|
-
|
38
|
+
|
30
39
|
it "upon parsing a string matching the third alternative, records the failure of the first two terminals" do
|
31
40
|
result = parse('baz')
|
32
|
-
|
41
|
+
|
33
42
|
terminal_failures = parser.terminal_failures
|
34
|
-
|
43
|
+
|
35
44
|
terminal_failures.size.should == 2
|
36
45
|
|
37
46
|
failure_1 = terminal_failures[0]
|
38
47
|
failure_1.expected_string == 'foo'
|
39
48
|
failure_1.index.should == 0
|
40
|
-
|
49
|
+
|
41
50
|
failure_2 = terminal_failures[1]
|
42
51
|
failure_2.expected_string == 'bar'
|
43
52
|
failure_2.index.should == 0
|
@@ -53,7 +62,7 @@ module ChoiceSpec
|
|
53
62
|
end
|
54
63
|
end
|
55
64
|
|
56
|
-
describe "A choice between terminals followed by a block" do
|
65
|
+
describe "A choice between terminals followed by a block" do
|
57
66
|
testing_expression "('a'/ 'bb' / [c]) { def a_method; end }"
|
58
67
|
|
59
68
|
it "extends a match of any of its subexpressions with a module created from the block" do
|
@@ -68,7 +77,7 @@ module ChoiceSpec
|
|
68
77
|
end
|
69
78
|
end
|
70
79
|
|
71
|
-
describe "a choice followed by a declared module" do
|
80
|
+
describe "a choice followed by a declared module" do
|
72
81
|
testing_expression "('a'/ 'bb' / [c]) <ChoiceSpec::TestModule>"
|
73
82
|
|
74
83
|
it "extends a match of any of its subexpressions with a module created from the block" do
|