treetop 1.6.3 → 1.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|