antlr3 1.2.3
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.
- data/ANTLR-LICENSE.txt +26 -0
- data/History.txt +66 -0
- data/README.txt +139 -0
- data/bin/antlr4ruby +33 -0
- data/java/RubyTarget.java +524 -0
- data/java/antlr-full-3.2.1.jar +0 -0
- data/lib/antlr3.rb +176 -0
- data/lib/antlr3/constants.rb +88 -0
- data/lib/antlr3/debug.rb +701 -0
- data/lib/antlr3/debug/event-hub.rb +210 -0
- data/lib/antlr3/debug/record-event-listener.rb +25 -0
- data/lib/antlr3/debug/rule-tracer.rb +55 -0
- data/lib/antlr3/debug/socket.rb +360 -0
- data/lib/antlr3/debug/trace-event-listener.rb +92 -0
- data/lib/antlr3/dfa.rb +247 -0
- data/lib/antlr3/dot.rb +174 -0
- data/lib/antlr3/error.rb +657 -0
- data/lib/antlr3/main.rb +561 -0
- data/lib/antlr3/modes/ast-builder.rb +41 -0
- data/lib/antlr3/modes/filter.rb +56 -0
- data/lib/antlr3/profile.rb +322 -0
- data/lib/antlr3/recognizers.rb +1280 -0
- data/lib/antlr3/streams.rb +985 -0
- data/lib/antlr3/streams/interactive.rb +91 -0
- data/lib/antlr3/streams/rewrite.rb +412 -0
- data/lib/antlr3/test/call-stack.rb +57 -0
- data/lib/antlr3/test/config.rb +23 -0
- data/lib/antlr3/test/core-extensions.rb +269 -0
- data/lib/antlr3/test/diff.rb +165 -0
- data/lib/antlr3/test/functional.rb +207 -0
- data/lib/antlr3/test/grammar.rb +371 -0
- data/lib/antlr3/token.rb +592 -0
- data/lib/antlr3/tree.rb +1415 -0
- data/lib/antlr3/tree/debug.rb +163 -0
- data/lib/antlr3/tree/visitor.rb +84 -0
- data/lib/antlr3/tree/wizard.rb +481 -0
- data/lib/antlr3/util.rb +149 -0
- data/lib/antlr3/version.rb +27 -0
- data/samples/ANTLRv3Grammar.g +621 -0
- data/samples/Cpp.g +749 -0
- data/templates/AST.stg +335 -0
- data/templates/ASTDbg.stg +40 -0
- data/templates/ASTParser.stg +153 -0
- data/templates/ASTTreeParser.stg +272 -0
- data/templates/Dbg.stg +192 -0
- data/templates/Ruby.stg +1514 -0
- data/test/functional/ast-output/auto-ast.rb +797 -0
- data/test/functional/ast-output/construction.rb +555 -0
- data/test/functional/ast-output/hetero-nodes.rb +753 -0
- data/test/functional/ast-output/rewrites.rb +1327 -0
- data/test/functional/ast-output/tree-rewrite.rb +1662 -0
- data/test/functional/debugging/debug-mode.rb +689 -0
- data/test/functional/debugging/profile-mode.rb +165 -0
- data/test/functional/debugging/rule-tracing.rb +74 -0
- data/test/functional/delegation/import.rb +379 -0
- data/test/functional/lexer/basic.rb +559 -0
- data/test/functional/lexer/filter-mode.rb +245 -0
- data/test/functional/lexer/nuances.rb +47 -0
- data/test/functional/lexer/properties.rb +104 -0
- data/test/functional/lexer/syn-pred.rb +32 -0
- data/test/functional/lexer/xml.rb +206 -0
- data/test/functional/main/main-scripts.rb +245 -0
- data/test/functional/parser/actions.rb +224 -0
- data/test/functional/parser/backtracking.rb +244 -0
- data/test/functional/parser/basic.rb +282 -0
- data/test/functional/parser/calc.rb +98 -0
- data/test/functional/parser/ll-star.rb +143 -0
- data/test/functional/parser/nuances.rb +165 -0
- data/test/functional/parser/predicates.rb +103 -0
- data/test/functional/parser/properties.rb +242 -0
- data/test/functional/parser/rule-methods.rb +132 -0
- data/test/functional/parser/scopes.rb +274 -0
- data/test/functional/token-rewrite/basic.rb +318 -0
- data/test/functional/token-rewrite/via-parser.rb +100 -0
- data/test/functional/tree-parser/basic.rb +750 -0
- data/test/unit/sample-input/file-stream-1 +2 -0
- data/test/unit/sample-input/teststreams.input2 +2 -0
- data/test/unit/test-dfa.rb +52 -0
- data/test/unit/test-exceptions.rb +44 -0
- data/test/unit/test-recognizers.rb +55 -0
- data/test/unit/test-scheme.rb +62 -0
- data/test/unit/test-streams.rb +459 -0
- data/test/unit/test-tree-wizard.rb +535 -0
- data/test/unit/test-trees.rb +854 -0
- metadata +205 -0
@@ -0,0 +1,854 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'antlr3'
|
5
|
+
require 'test/unit'
|
6
|
+
require 'spec'
|
7
|
+
|
8
|
+
include ANTLR3
|
9
|
+
include ANTLR3::AST
|
10
|
+
|
11
|
+
class TestTreeNodeStream < Test::Unit::TestCase
|
12
|
+
def setup
|
13
|
+
@adaptor = CommonTreeAdaptor.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def new_stream(t)
|
17
|
+
CommonTreeNodeStream.new(t)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_single_node
|
21
|
+
t = CommonTree.new(CommonToken.new { |t| t.type = 101 })
|
22
|
+
stream = new_stream(t)
|
23
|
+
expecting = '101'
|
24
|
+
|
25
|
+
found = nodes_only_string(stream)
|
26
|
+
|
27
|
+
found.should == expecting
|
28
|
+
|
29
|
+
expecting = '101'
|
30
|
+
found = stream.inspect
|
31
|
+
|
32
|
+
found.should == expecting
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_two_children_of_nil_root
|
36
|
+
v = Class.new(CommonTree) do
|
37
|
+
def initialize(token = nil, type = nil, x = nil)
|
38
|
+
@x = x
|
39
|
+
super(token || (CommonToken.new { |t| t.type = type } if type))
|
40
|
+
end
|
41
|
+
def to_s
|
42
|
+
(@token.text rescue '') + '<V>'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
root_0 = @adaptor.create_flat_list!
|
47
|
+
t = v.new(nil, 101, 2)
|
48
|
+
u = v.new CommonToken.create(:type => 102, :text => '102')
|
49
|
+
@adaptor.add_child(root_0, t)
|
50
|
+
@adaptor.add_child(root_0, u)
|
51
|
+
|
52
|
+
assert(root_0.parent.nil?)
|
53
|
+
root_0.child_index.should == -1
|
54
|
+
t.child_index.should == 0
|
55
|
+
u.child_index.should == 1
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_4_nodes
|
60
|
+
t = CommonTree.new CommonToken[101]
|
61
|
+
t.add_child( CommonTree.new CommonToken[102] )
|
62
|
+
t.child(0).add_child(CommonTree.new CommonToken[103])
|
63
|
+
t.add_child(CommonTree.new CommonToken[104])
|
64
|
+
|
65
|
+
stream = new_stream(t)
|
66
|
+
|
67
|
+
expecting = "101 102 103 104"
|
68
|
+
found = nodes_only_string(stream)
|
69
|
+
found.should == expecting
|
70
|
+
|
71
|
+
expecting = "101 2 102 2 103 3 104 3"
|
72
|
+
found = stream.inspect
|
73
|
+
found.should == expecting
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_list
|
77
|
+
root = CommonTree.new(nil)
|
78
|
+
t = CommonTree.new CommonToken[101]
|
79
|
+
t.add_child CommonTree.new(CommonToken[102])
|
80
|
+
t.child(0).add_child(CommonTree.new(CommonToken[103]))
|
81
|
+
t.add_child(CommonTree.new(CommonToken[104]))
|
82
|
+
|
83
|
+
u = CommonTree.new CommonToken[105]
|
84
|
+
|
85
|
+
root.add_child(t)
|
86
|
+
root.add_child(u)
|
87
|
+
|
88
|
+
stream = CommonTreeNodeStream.new(root)
|
89
|
+
|
90
|
+
expecting = '101 102 103 104 105'
|
91
|
+
found = nodes_only_string(stream)
|
92
|
+
found.should == expecting
|
93
|
+
|
94
|
+
expecting = "101 2 102 2 103 3 104 3 105"
|
95
|
+
found = stream.inspect
|
96
|
+
found.should == expecting
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_flat_list
|
100
|
+
root = CommonTree.new(nil)
|
101
|
+
|
102
|
+
root.add_child CommonTree.new(CommonToken[101])
|
103
|
+
root.add_child(CommonTree.new(CommonToken[102]))
|
104
|
+
root.add_child(CommonTree.new(CommonToken[103]))
|
105
|
+
|
106
|
+
stream = CommonTreeNodeStream.new(root)
|
107
|
+
|
108
|
+
expecting = '101 102 103'
|
109
|
+
found = nodes_only_string(stream)
|
110
|
+
found.should == expecting
|
111
|
+
|
112
|
+
expecting = '101 102 103'
|
113
|
+
found = stream.inspect
|
114
|
+
found.should == expecting
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_list_with_one_node
|
118
|
+
root = CommonTree.new(nil)
|
119
|
+
|
120
|
+
root.add_child(CommonTree.new(CommonToken[101]))
|
121
|
+
|
122
|
+
stream = CommonTreeNodeStream.new(root)
|
123
|
+
|
124
|
+
expecting = '101'
|
125
|
+
found = nodes_only_string(stream)
|
126
|
+
found.should == expecting
|
127
|
+
|
128
|
+
expecting = '101'
|
129
|
+
found = stream.inspect
|
130
|
+
found.should == expecting
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_a_over_b
|
134
|
+
t = CommonTree.new(CommonToken[101])
|
135
|
+
t.add_child(CommonTree.new(CommonToken[102]))
|
136
|
+
|
137
|
+
stream = new_stream(t)
|
138
|
+
expecting = '101 102'
|
139
|
+
found = nodes_only_string(stream)
|
140
|
+
found.should == expecting
|
141
|
+
|
142
|
+
expecting = '101 2 102 3'
|
143
|
+
found = stream.inspect
|
144
|
+
found.should == expecting
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_LT
|
148
|
+
# ^(101 ^(102 103) 104)
|
149
|
+
t = CommonTree.new CommonToken[101]
|
150
|
+
t.add_child CommonTree.new(CommonToken[102])
|
151
|
+
t.child(0).add_child(CommonTree.new(CommonToken[103]))
|
152
|
+
t.add_child(CommonTree.new(CommonToken[104]))
|
153
|
+
|
154
|
+
stream = new_stream(t)
|
155
|
+
[101, DOWN, 102, DOWN, 103, UP, 104, UP, EOF].each_with_index do |type, index|
|
156
|
+
stream.look(index + 1).type.should == type
|
157
|
+
end
|
158
|
+
stream.look(100).type.should == EOF
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_mark_rewind_entire
|
162
|
+
# ^(101 ^(102 103 ^(106 107)) 104 105)
|
163
|
+
r0 = new_node new_token(101)
|
164
|
+
r1 = new_node new_token(102)
|
165
|
+
r0.add_child(r1)
|
166
|
+
r1.add_child(new_node new_token(103))
|
167
|
+
r2 = new_node new_token(106)
|
168
|
+
r2.add_child new_node( new_token 107 )
|
169
|
+
r1.add_child r2
|
170
|
+
r0.add_child new_node( new_token 104 )
|
171
|
+
r0.add_child new_node( new_token 105 )
|
172
|
+
|
173
|
+
stream = CommonTreeNodeStream.new(r0)
|
174
|
+
m = stream.mark
|
175
|
+
13.times { stream.look(1); stream.consume } # consume until end
|
176
|
+
|
177
|
+
stream.look(1).type.should == EOF
|
178
|
+
stream.look(-1).type.should == UP
|
179
|
+
stream.rewind(m)
|
180
|
+
|
181
|
+
13.times { stream.look(1); stream.consume } # consume until end
|
182
|
+
|
183
|
+
stream.look(1).type.should == EOF
|
184
|
+
stream.look(-1).type.should == UP
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_mark_rewind_in_middle
|
188
|
+
# ^(101 ^(102 103 ^(106 107)) 104 105)
|
189
|
+
r0 = new_node new_token(101)
|
190
|
+
r1 = new_node new_token(102)
|
191
|
+
r0.add_child r1
|
192
|
+
r1.add_child new_node( new_token 103 )
|
193
|
+
r2 = new_node new_token(106)
|
194
|
+
r2.add_child new_node( new_token 107 )
|
195
|
+
r1.add_child r2
|
196
|
+
r0.add_child new_node( new_token 104 )
|
197
|
+
r0.add_child new_node( new_token 105 )
|
198
|
+
|
199
|
+
stream = CommonTreeNodeStream.new(r0)
|
200
|
+
7.times { stream.consume }
|
201
|
+
|
202
|
+
stream.look(1).type.should == 107
|
203
|
+
m = stream.mark
|
204
|
+
4.times { stream.consume }
|
205
|
+
stream.rewind(m)
|
206
|
+
|
207
|
+
[107, UP, UP, 104].each do |val|
|
208
|
+
stream.look(1).type.should == val
|
209
|
+
stream.consume
|
210
|
+
end
|
211
|
+
# past rewind position now
|
212
|
+
[105, UP].each do |val|
|
213
|
+
stream.look(1).type.should == val
|
214
|
+
stream.consume
|
215
|
+
end
|
216
|
+
stream.look(1).type.should == EOF
|
217
|
+
stream.look(-1).type.should == UP
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_mark_rewind_nested
|
221
|
+
# ^(101 ^(102 103 ^(106 107)) 104 105)
|
222
|
+
r0 = new_node new_token(101)
|
223
|
+
r1 = new_node new_token(102)
|
224
|
+
r0.add_child r1
|
225
|
+
r1.add_child new_node( new_token 103 )
|
226
|
+
r2 = new_node new_token(106)
|
227
|
+
r2.add_child new_node( new_token 107 )
|
228
|
+
r1.add_child r2
|
229
|
+
r0.add_child new_node( new_token 104 )
|
230
|
+
r0.add_child new_node( new_token 105 )
|
231
|
+
|
232
|
+
stream = CommonTreeNodeStream.new(r0)
|
233
|
+
m = stream.mark
|
234
|
+
2.times { stream.consume }
|
235
|
+
m2 = stream.mark
|
236
|
+
4.times { stream.consume }
|
237
|
+
stream.rewind(m2)
|
238
|
+
stream.look(1).type.should == 102
|
239
|
+
stream.consume
|
240
|
+
stream.look(1).type.should == DOWN
|
241
|
+
stream.consume
|
242
|
+
|
243
|
+
stream.rewind(m)
|
244
|
+
[101, DOWN, 102].each do |val|
|
245
|
+
stream.look(1).type.should == val
|
246
|
+
stream.consume
|
247
|
+
end
|
248
|
+
stream.look(1).type.should == DOWN
|
249
|
+
end
|
250
|
+
|
251
|
+
def test_seek
|
252
|
+
# ^(101 ^(102 103 ^(106 107) ) 104 105)
|
253
|
+
# stream has 7 real + 6 nav nodes
|
254
|
+
# Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
|
255
|
+
|
256
|
+
r0 = new_node new_token(101)
|
257
|
+
r1 = new_node new_token(102)
|
258
|
+
r0.add_child r1
|
259
|
+
r1.add_child new_node( new_token 103 )
|
260
|
+
r2 = new_node new_token(106)
|
261
|
+
r2.add_child new_node( new_token 107 )
|
262
|
+
r1.add_child r2
|
263
|
+
r0.add_child new_node( new_token 104 )
|
264
|
+
r0.add_child new_node( new_token 105 )
|
265
|
+
|
266
|
+
stream = CommonTreeNodeStream.new(r0)
|
267
|
+
3.times { stream.consume }
|
268
|
+
stream.seek(7)
|
269
|
+
stream.look(1).type.should == 107
|
270
|
+
3.times { stream.consume }
|
271
|
+
stream.look(1).type.should == 104
|
272
|
+
end
|
273
|
+
|
274
|
+
def test_seek_from_start
|
275
|
+
r0 = new_node new_token(101)
|
276
|
+
r1 = new_node new_token(102)
|
277
|
+
r0.add_child r1
|
278
|
+
r1.add_child new_node( new_token 103 )
|
279
|
+
r2 = new_node new_token(106)
|
280
|
+
r2.add_child new_node( new_token 107 )
|
281
|
+
r1.add_child r2
|
282
|
+
r0.add_child new_node( new_token 104 )
|
283
|
+
r0.add_child new_node( new_token 105 )
|
284
|
+
|
285
|
+
stream = CommonTreeNodeStream.new(r0)
|
286
|
+
stream.seek(7)
|
287
|
+
stream.look(1).type.should == 107
|
288
|
+
3.times { stream.consume }
|
289
|
+
stream.look(1).type.should == 104
|
290
|
+
end
|
291
|
+
|
292
|
+
def nodes_only_string(nodes)
|
293
|
+
buffer = []
|
294
|
+
nodes.size.times do |index|
|
295
|
+
t = nodes.look(index + 1)
|
296
|
+
type = nodes.tree_adaptor.type_of(t)
|
297
|
+
buffer << type.to_s unless type == DOWN or type == UP
|
298
|
+
end
|
299
|
+
return buffer.join(' ')
|
300
|
+
end
|
301
|
+
|
302
|
+
def new_token(type, opts = {})
|
303
|
+
opts[:type] = type
|
304
|
+
CommonToken.create(opts)
|
305
|
+
end
|
306
|
+
def new_node(token)
|
307
|
+
CommonTree.new(token)
|
308
|
+
end
|
309
|
+
|
310
|
+
|
311
|
+
end
|
312
|
+
|
313
|
+
class TestCommonTreeNodeStream < Test::Unit::TestCase
|
314
|
+
def setup
|
315
|
+
# before-each-test code
|
316
|
+
end
|
317
|
+
def teardown
|
318
|
+
# after-each-test code
|
319
|
+
end
|
320
|
+
|
321
|
+
# vvvvvvvv tests vvvvvvvvv
|
322
|
+
|
323
|
+
def test_push_pop
|
324
|
+
r0 = new_node new_token(101)
|
325
|
+
r1 = new_node new_token(102)
|
326
|
+
r1.add_child new_node( new_token 103 )
|
327
|
+
r0.add_child r1
|
328
|
+
r2 = new_node new_token(104)
|
329
|
+
r2.add_child new_node( new_token 105 )
|
330
|
+
r0.add_child r2
|
331
|
+
r3 = new_node new_token(106)
|
332
|
+
r3.add_child new_node( new_token 107 )
|
333
|
+
r0.add_child r3
|
334
|
+
r0.add_child new_node( new_token 108 )
|
335
|
+
r0.add_child new_node( new_token 109 )
|
336
|
+
|
337
|
+
stream = CommonTreeNodeStream.new(r0)
|
338
|
+
expecting = '101 2 102 2 103 3 104 2 105 3 106 2 107 3 108 109 3'
|
339
|
+
found = stream.inspect
|
340
|
+
found.should == expecting
|
341
|
+
|
342
|
+
index_of_102 = 2
|
343
|
+
index_of_107 = 12
|
344
|
+
index_of_107.times { stream.consume }
|
345
|
+
|
346
|
+
stream.look(1).type.should == 107
|
347
|
+
stream.push(index_of_102)
|
348
|
+
stream.look(1).type.should == 102
|
349
|
+
stream.consume
|
350
|
+
stream.look(1).type.should == DOWN
|
351
|
+
stream.consume
|
352
|
+
stream.look(1).type.should == 103
|
353
|
+
stream.consume
|
354
|
+
stream.look(1).type.should == UP
|
355
|
+
stream.pop
|
356
|
+
stream.look(1).type.should == 107
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_nested_push_pop
|
360
|
+
r0 = new_node new_token(101)
|
361
|
+
r1 = new_node new_token(102)
|
362
|
+
r1.add_child new_node( new_token 103 )
|
363
|
+
r0.add_child r1
|
364
|
+
r2 = new_node new_token(104)
|
365
|
+
r2.add_child new_node( new_token 105 )
|
366
|
+
r0.add_child r2
|
367
|
+
r3 = new_node new_token(106)
|
368
|
+
r3.add_child new_node( new_token 107 )
|
369
|
+
r0.add_child r3
|
370
|
+
r0.add_child new_node( new_token 108 )
|
371
|
+
r0.add_child new_node( new_token 109 )
|
372
|
+
|
373
|
+
stream = CommonTreeNodeStream.new(r0)
|
374
|
+
|
375
|
+
index_of_102 = 2
|
376
|
+
index_of_107 = 12
|
377
|
+
|
378
|
+
index_of_107.times { stream.consume }
|
379
|
+
|
380
|
+
stream.look(1).type.should == 107
|
381
|
+
stream.push(index_of_102)
|
382
|
+
[102, DOWN, 103].each do |val|
|
383
|
+
stream.look(1).type.should == val
|
384
|
+
stream.consume
|
385
|
+
end
|
386
|
+
|
387
|
+
index_of_104 = 6
|
388
|
+
stream.push(index_of_104)
|
389
|
+
[104,DOWN,105].each do |val|
|
390
|
+
stream.look(1).type.should == val
|
391
|
+
stream.consume
|
392
|
+
end
|
393
|
+
stream.look(1).type.should == UP
|
394
|
+
stream.pop
|
395
|
+
|
396
|
+
stream.look(1).type.should == UP
|
397
|
+
stream.pop
|
398
|
+
stream.look(1).type.should == 107
|
399
|
+
end
|
400
|
+
|
401
|
+
def test_push_pop_from_eof
|
402
|
+
r0 = new_node new_token(101)
|
403
|
+
r1 = new_node new_token(102)
|
404
|
+
r1.add_child new_node( new_token 103 )
|
405
|
+
r0.add_child r1
|
406
|
+
r2 = new_node new_token(104)
|
407
|
+
r2.add_child new_node( new_token 105 )
|
408
|
+
r0.add_child r2
|
409
|
+
r3 = new_node new_token(106)
|
410
|
+
r3.add_child new_node( new_token 107 )
|
411
|
+
r0.add_child r3
|
412
|
+
r0.add_child new_node( new_token 108 )
|
413
|
+
r0.add_child new_node( new_token 109 )
|
414
|
+
|
415
|
+
stream = CommonTreeNodeStream.new(r0)
|
416
|
+
stream.consume until stream.peek(1) == EOF
|
417
|
+
|
418
|
+
index_of_102 = 2
|
419
|
+
index_of_104 = 6
|
420
|
+
stream.look(1).type.should == EOF
|
421
|
+
|
422
|
+
stream.push(index_of_102)
|
423
|
+
[102, DOWN, 103].each do |val|
|
424
|
+
stream.look(1).type.should == val
|
425
|
+
stream.consume
|
426
|
+
end
|
427
|
+
stream.look(1).type.should == UP
|
428
|
+
|
429
|
+
stream.pop
|
430
|
+
stream.look(1).type.should == EOF
|
431
|
+
|
432
|
+
stream.push(index_of_104)
|
433
|
+
[104, DOWN, 105].each do |val|
|
434
|
+
stream.look(1).type.should == val
|
435
|
+
stream.consume
|
436
|
+
end
|
437
|
+
stream.look(1).type.should == UP
|
438
|
+
|
439
|
+
stream.pop
|
440
|
+
stream.look(1).type.should == EOF
|
441
|
+
end
|
442
|
+
|
443
|
+
|
444
|
+
def new_token(type, opts = {})
|
445
|
+
opts[:type] = type
|
446
|
+
CommonToken.create(opts)
|
447
|
+
end
|
448
|
+
def new_node(token)
|
449
|
+
CommonTree.new(token)
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
|
454
|
+
class TestCommonTree < Test::Unit::TestCase
|
455
|
+
def setup
|
456
|
+
@adaptor = CommonTreeAdaptor.new
|
457
|
+
end
|
458
|
+
def teardown
|
459
|
+
# after-each-test code
|
460
|
+
end
|
461
|
+
|
462
|
+
# vvvvvvvv tests vvvvvvvvv
|
463
|
+
|
464
|
+
def test_single_node
|
465
|
+
t = new_node( new_token 101 )
|
466
|
+
assert_nil t.parent
|
467
|
+
t.child_index.should == -1
|
468
|
+
end
|
469
|
+
|
470
|
+
def test_4_nodes
|
471
|
+
# ^(101 ^(102 103) 104)
|
472
|
+
r0 = new_node( new_token 101 )
|
473
|
+
r0.add_child new_node( new_token 102 )
|
474
|
+
r0.child(0).add_child new_node( new_token 103 )
|
475
|
+
r0.add_child new_node( new_token 104 )
|
476
|
+
|
477
|
+
assert_nil r0.parent
|
478
|
+
r0.child_index.should == -1
|
479
|
+
end
|
480
|
+
|
481
|
+
def test_list
|
482
|
+
# ^(nil 101 102 103)
|
483
|
+
r0 = CommonTree.new(nil)
|
484
|
+
c0 = new_node( new_token 101 )
|
485
|
+
r0.add_child c0
|
486
|
+
c1 = new_node( new_token 102 )
|
487
|
+
r0.add_child c1
|
488
|
+
c2 = new_node( new_token 103 )
|
489
|
+
r0.add_child c2
|
490
|
+
|
491
|
+
assert_nil r0.parent
|
492
|
+
r0.child_index.should == -1
|
493
|
+
c0.parent.should == r0
|
494
|
+
c0.child_index.should == 0
|
495
|
+
c1.parent.should == r0
|
496
|
+
c1.child_index.should == 1
|
497
|
+
c2.parent.should == r0
|
498
|
+
c2.child_index.should == 2
|
499
|
+
end
|
500
|
+
|
501
|
+
def test_list2
|
502
|
+
# ^(nil 101 102 103)
|
503
|
+
root = new_node( new_token 5 )
|
504
|
+
r0 = CommonTree.new(nil)
|
505
|
+
c0 = new_node( new_token 101 )
|
506
|
+
r0.add_child c0
|
507
|
+
c1 = new_node( new_token 102 )
|
508
|
+
r0.add_child c1
|
509
|
+
c2 = new_node( new_token 103 )
|
510
|
+
r0.add_child c2
|
511
|
+
|
512
|
+
root.add_child r0
|
513
|
+
|
514
|
+
assert_nil root.parent
|
515
|
+
root.child_index.should == -1
|
516
|
+
c0.parent.should == root
|
517
|
+
c0.child_index.should == 0
|
518
|
+
c1.parent.should == root # note -- actual python tests all use c0 here, which i think might be wrong
|
519
|
+
c1.child_index.should == 1
|
520
|
+
c2.parent.should == root # note -- actual python tests all use c0 here, which i think might be wrong
|
521
|
+
c2.child_index.should == 2
|
522
|
+
end
|
523
|
+
|
524
|
+
def test_add_list_to_exist_children
|
525
|
+
root = new_node( new_token 5 )
|
526
|
+
root.add_child new_node( new_token 6 )
|
527
|
+
|
528
|
+
r0 = CommonTree.new(nil)
|
529
|
+
c0 = new_node( new_token 101 )
|
530
|
+
r0.add_child c0
|
531
|
+
c1 = new_node( new_token 102 )
|
532
|
+
r0.add_child c1
|
533
|
+
c2 = new_node( new_token 103 )
|
534
|
+
r0.add_child c2
|
535
|
+
# ^(nil c0=101 c1=102 c2=103)
|
536
|
+
|
537
|
+
root.add_child(r0)
|
538
|
+
|
539
|
+
assert_nil root.parent
|
540
|
+
root.child_index.should == -1
|
541
|
+
c0.parent.should == root
|
542
|
+
c0.child_index.should == 1
|
543
|
+
c1.parent.should == root
|
544
|
+
c1.child_index.should == 2
|
545
|
+
c2.parent.should == root
|
546
|
+
c2.child_index.should == 3
|
547
|
+
end
|
548
|
+
|
549
|
+
def test_copy_tree
|
550
|
+
r0 = new_node( new_token 101 )
|
551
|
+
r1 = new_node( new_token 102 )
|
552
|
+
r2 = new_node( new_token 106 )
|
553
|
+
r0.add_child( r1 )
|
554
|
+
r1.add_child( new_node( new_token 103 ) )
|
555
|
+
r2.add_child( new_node( new_token 107 ) )
|
556
|
+
r1.add_child( r2 )
|
557
|
+
r0.add_child( new_node( new_token 104 ) )
|
558
|
+
r0.add_child( new_node( new_token 105 ) )
|
559
|
+
|
560
|
+
dup = @adaptor.copy_tree(r0)
|
561
|
+
assert_nil dup.parent
|
562
|
+
dup.child_index.should == -1
|
563
|
+
dup.sanity_check_parent_and_child_indexes
|
564
|
+
end
|
565
|
+
|
566
|
+
def test_become_root
|
567
|
+
new_root = new_node( new_token 5 )
|
568
|
+
|
569
|
+
old_root = new_node nil
|
570
|
+
old_root.add_child( new_node( new_token 101 ) )
|
571
|
+
old_root.add_child( new_node( new_token 102 ) )
|
572
|
+
old_root.add_child( new_node( new_token 103 ) )
|
573
|
+
|
574
|
+
@adaptor.become_root(new_root, old_root)
|
575
|
+
new_root.sanity_check_parent_and_child_indexes
|
576
|
+
end
|
577
|
+
|
578
|
+
def test_become_root2
|
579
|
+
new_root = new_node( new_token 5 )
|
580
|
+
|
581
|
+
old_root = new_node( new_token 101 )
|
582
|
+
old_root.add_child( new_node( new_token 102 ) )
|
583
|
+
old_root.add_child( new_node( new_token 103 ) )
|
584
|
+
|
585
|
+
@adaptor.become_root(new_root, old_root)
|
586
|
+
new_root.sanity_check_parent_and_child_indexes
|
587
|
+
end
|
588
|
+
|
589
|
+
def test_become_root3
|
590
|
+
new_root = new_node nil
|
591
|
+
new_root.add_child( new_node( new_token 5 ) )
|
592
|
+
|
593
|
+
old_root = new_node nil
|
594
|
+
old_root.add_child( new_node( new_token 101 ) )
|
595
|
+
old_root.add_child( new_node( new_token 102 ) )
|
596
|
+
old_root.add_child( new_node( new_token 103 ) )
|
597
|
+
|
598
|
+
@adaptor.become_root(new_root, old_root)
|
599
|
+
new_root.sanity_check_parent_and_child_indexes
|
600
|
+
end
|
601
|
+
|
602
|
+
def test_become_root5
|
603
|
+
new_root = new_node nil
|
604
|
+
new_root.add_child( new_node( new_token 5 ) )
|
605
|
+
|
606
|
+
old_root = new_node( new_token 101 )
|
607
|
+
old_root.add_child( new_node( new_token 102 ) )
|
608
|
+
old_root.add_child( new_node( new_token 103 ) )
|
609
|
+
|
610
|
+
@adaptor.become_root(new_root, old_root)
|
611
|
+
new_root.sanity_check_parent_and_child_indexes
|
612
|
+
end
|
613
|
+
|
614
|
+
def test_become_root6
|
615
|
+
root_0 = @adaptor.create_flat_list!
|
616
|
+
root_1 = @adaptor.create_flat_list!
|
617
|
+
root_1 = @adaptor.become_root( new_node( new_token 5 ), root_1 )
|
618
|
+
|
619
|
+
@adaptor.add_child( root_1, new_node( new_token 6 ) )
|
620
|
+
@adaptor.add_child( root_0, root_1 )
|
621
|
+
root_0.sanity_check_parent_and_child_indexes
|
622
|
+
end
|
623
|
+
|
624
|
+
def test_replace_with_no_children
|
625
|
+
t = new_node( new_token 101 )
|
626
|
+
new_child = new_node( new_token 5 )
|
627
|
+
error = false
|
628
|
+
assert_raise(IndexError) do
|
629
|
+
t.replace_children(0, 0, new_child)
|
630
|
+
end
|
631
|
+
end
|
632
|
+
|
633
|
+
def test_replace_with_one_children
|
634
|
+
t = new_node( new_token 99, :text => 'a' )
|
635
|
+
c0 = new_node( new_token 99, :text => 'b' )
|
636
|
+
t.add_child(c0)
|
637
|
+
|
638
|
+
new_child = new_node( new_token 99, :text => 'c' )
|
639
|
+
t.replace_children(0,0,new_child)
|
640
|
+
|
641
|
+
t.to_string_tree.should == '(a c)'
|
642
|
+
t.sanity_check_parent_and_child_indexes
|
643
|
+
|
644
|
+
end
|
645
|
+
def test_replace_in_middle
|
646
|
+
t = new_node( new_token 99, :text => 'a' )
|
647
|
+
t.add_child new_node( new_token 99, :text => 'b' )
|
648
|
+
t.add_child new_node( new_token 99, :text => 'c' )
|
649
|
+
t.add_child new_node( new_token 99, :text => 'd' )
|
650
|
+
|
651
|
+
new_child = new_node( new_token 99, :text => 'x' )
|
652
|
+
t.replace_children(1, 1, new_child)
|
653
|
+
t.to_string_tree.should == '(a b x d)'
|
654
|
+
t.sanity_check_parent_and_child_indexes
|
655
|
+
end
|
656
|
+
|
657
|
+
def test_replace_at_left
|
658
|
+
t = new_node( new_token 99, :text => 'a' )
|
659
|
+
t.add_child new_node( new_token 99, :text => 'b' )
|
660
|
+
t.add_child new_node( new_token 99, :text => 'c' )
|
661
|
+
t.add_child new_node( new_token 99, :text => 'd' )
|
662
|
+
|
663
|
+
new_child = new_node( new_token 99, :text => 'x' )
|
664
|
+
t.replace_children(0, 0, new_child)
|
665
|
+
t.to_string_tree.should == '(a x c d)'
|
666
|
+
t.sanity_check_parent_and_child_indexes
|
667
|
+
end
|
668
|
+
|
669
|
+
def test_replace_at_left
|
670
|
+
t = new_node( new_token 99, :text => 'a' )
|
671
|
+
t.add_child new_node( new_token 99, :text => 'b' )
|
672
|
+
t.add_child new_node( new_token 99, :text => 'c' )
|
673
|
+
t.add_child new_node( new_token 99, :text => 'd' )
|
674
|
+
|
675
|
+
new_child = new_node( new_token 99, :text => 'x' )
|
676
|
+
t.replace_children(2, 2, new_child)
|
677
|
+
t.to_string_tree.should == '(a b c x)'
|
678
|
+
t.sanity_check_parent_and_child_indexes
|
679
|
+
end
|
680
|
+
|
681
|
+
def test_replace_one_with_two_at_left
|
682
|
+
t = new_node( new_token 99, :text => 'a' )
|
683
|
+
t.add_child new_node( new_token 99, :text => 'b' )
|
684
|
+
t.add_child new_node( new_token 99, :text => 'c' )
|
685
|
+
t.add_child new_node( new_token 99, :text => 'd' )
|
686
|
+
|
687
|
+
new_children = @adaptor.create_flat_list!
|
688
|
+
new_children.add_child new_node( new_token 99, :text => 'x' )
|
689
|
+
new_children.add_child new_node( new_token 99, :text => 'y' )
|
690
|
+
|
691
|
+
t.replace_children(0, 0, new_children)
|
692
|
+
t.to_string_tree.should == '(a x y c d)'
|
693
|
+
t.sanity_check_parent_and_child_indexes
|
694
|
+
end
|
695
|
+
|
696
|
+
def test_replace_one_with_two_at_right
|
697
|
+
t = new_node( new_token 99, :text => 'a' )
|
698
|
+
t.add_child new_node( new_token 99, :text => 'b' )
|
699
|
+
t.add_child new_node( new_token 99, :text => 'c' )
|
700
|
+
t.add_child new_node( new_token 99, :text => 'd' )
|
701
|
+
|
702
|
+
new_children = @adaptor.create_flat_list!
|
703
|
+
new_children.add_child new_node( new_token 99, :text => 'x' )
|
704
|
+
new_children.add_child new_node( new_token 99, :text => 'y' )
|
705
|
+
|
706
|
+
t.replace_children(2, 2, new_children)
|
707
|
+
t.to_string_tree.should == '(a b c x y)'
|
708
|
+
t.sanity_check_parent_and_child_indexes
|
709
|
+
end
|
710
|
+
|
711
|
+
def test_replace_one_with_two_in_middle
|
712
|
+
t = new_node( new_token 99, :text => 'a' )
|
713
|
+
t.add_child new_node( new_token 99, :text => 'b' )
|
714
|
+
t.add_child new_node( new_token 99, :text => 'c' )
|
715
|
+
t.add_child new_node( new_token 99, :text => 'd' )
|
716
|
+
|
717
|
+
new_children = @adaptor.create_flat_list!
|
718
|
+
new_children.add_child new_node( new_token 99, :text => 'x' )
|
719
|
+
new_children.add_child new_node( new_token 99, :text => 'y' )
|
720
|
+
|
721
|
+
t.replace_children(1, 1, new_children)
|
722
|
+
t.to_string_tree.should == '(a b x y d)'
|
723
|
+
t.sanity_check_parent_and_child_indexes
|
724
|
+
end
|
725
|
+
|
726
|
+
def test_replace_two_with_one_at_left
|
727
|
+
t = new_node( new_token 99, :text => 'a' )
|
728
|
+
t.add_child new_node( new_token 99, :text => 'b' )
|
729
|
+
t.add_child new_node( new_token 99, :text => 'c' )
|
730
|
+
t.add_child new_node( new_token 99, :text => 'd' )
|
731
|
+
|
732
|
+
new_child = new_node( new_token 99, :text => 'x' )
|
733
|
+
|
734
|
+
t.replace_children(0, 1, new_child)
|
735
|
+
t.to_string_tree.should == '(a x d)'
|
736
|
+
t.sanity_check_parent_and_child_indexes
|
737
|
+
end
|
738
|
+
|
739
|
+
def test_replace_two_with_one_at_right
|
740
|
+
t = new_node( new_token 99, :text => 'a' )
|
741
|
+
t.add_child new_node( new_token 99, :text => 'b' )
|
742
|
+
t.add_child new_node( new_token 99, :text => 'c' )
|
743
|
+
t.add_child new_node( new_token 99, :text => 'd' )
|
744
|
+
|
745
|
+
new_child = new_node( new_token 99, :text => 'x' )
|
746
|
+
|
747
|
+
t.replace_children(1, 2, new_child)
|
748
|
+
t.to_string_tree.should == '(a b x)'
|
749
|
+
t.sanity_check_parent_and_child_indexes
|
750
|
+
end
|
751
|
+
|
752
|
+
def test_replace_all_with_one
|
753
|
+
t = new_node( new_token 99, :text => 'a' )
|
754
|
+
t.add_child new_node( new_token 99, :text => 'b' )
|
755
|
+
t.add_child new_node( new_token 99, :text => 'c' )
|
756
|
+
t.add_child new_node( new_token 99, :text => 'd' )
|
757
|
+
|
758
|
+
new_child = new_node( new_token 99, :text => 'x' )
|
759
|
+
|
760
|
+
t.replace_children(0, 2, new_child)
|
761
|
+
t.to_string_tree.should == '(a x)'
|
762
|
+
t.sanity_check_parent_and_child_indexes
|
763
|
+
end
|
764
|
+
|
765
|
+
def test_replace_all_with_two
|
766
|
+
t = new_node( new_token 99, :text => 'a' )
|
767
|
+
t.add_child new_node( new_token 99, :text => 'b' )
|
768
|
+
t.add_child new_node( new_token 99, :text => 'c' )
|
769
|
+
t.add_child new_node( new_token 99, :text => 'd' )
|
770
|
+
|
771
|
+
new_children = @adaptor.create_flat_list!
|
772
|
+
new_children.add_child new_node( new_token 99, :text => 'x' )
|
773
|
+
new_children.add_child new_node( new_token 99, :text => 'y' )
|
774
|
+
|
775
|
+
t.replace_children(0, 1, new_children)
|
776
|
+
t.to_string_tree.should == '(a x y d)'
|
777
|
+
t.sanity_check_parent_and_child_indexes
|
778
|
+
end
|
779
|
+
|
780
|
+
def new_token(type, opts = {})
|
781
|
+
opts[:type] = type
|
782
|
+
CommonToken.create(opts)
|
783
|
+
end
|
784
|
+
def new_node(token)
|
785
|
+
CommonTree.new(token)
|
786
|
+
end
|
787
|
+
end
|
788
|
+
|
789
|
+
|
790
|
+
class TestTreeContext < Test::Unit::TestCase
|
791
|
+
TOKEN_NAMES = %w(
|
792
|
+
<invalid> <EOR> <DOWN> <UP> VEC ASSIGN PRINT
|
793
|
+
PLUS MULT DOT ID INT WS '[' ',' ']'
|
794
|
+
)
|
795
|
+
def setup
|
796
|
+
# before-each-test code
|
797
|
+
end
|
798
|
+
def teardown
|
799
|
+
# after-each-test code
|
800
|
+
end
|
801
|
+
|
802
|
+
# vvvvvvvv tests vvvvvvvvv
|
803
|
+
|
804
|
+
def test_simple_parent
|
805
|
+
tree = "(nil (ASSIGN ID[x] INT[3]) (PRINT (MULT ID[x] (VEC INT[1] INT[2] INT[3]))))"
|
806
|
+
adaptor = CommonTreeAdaptor.new
|
807
|
+
wiz = Wizard.new(adaptor, TOKEN_NAMES)
|
808
|
+
t = wiz.create(tree)
|
809
|
+
|
810
|
+
labels = {}
|
811
|
+
|
812
|
+
valid = wiz.parse(t,
|
813
|
+
"(nil (ASSIGN ID[x] INT[3]) (PRINT (MULT ID (VEC INT %x:INT INT))))",
|
814
|
+
labels
|
815
|
+
)
|
816
|
+
assert(valid)
|
817
|
+
node = labels['x']
|
818
|
+
|
819
|
+
TreeParser.in_context?(adaptor, TOKEN_NAMES, node, "VEC").should be_true
|
820
|
+
end
|
821
|
+
|
822
|
+
def test_no_parent
|
823
|
+
tree = '(PRINT (MULT ID[x] (VEC INT[1] INT[2] INT[3])))'
|
824
|
+
adaptor = CommonTreeAdaptor.new
|
825
|
+
wiz = Wizard.new(adaptor, TOKEN_NAMES)
|
826
|
+
t = wiz.create(tree)
|
827
|
+
|
828
|
+
labels = {}
|
829
|
+
valid = wiz.parse(t,
|
830
|
+
"(%x:PRINT (MULT ID (VEC INT INT INT)))",
|
831
|
+
labels
|
832
|
+
)
|
833
|
+
assert(valid)
|
834
|
+
node = labels['x']
|
835
|
+
assert_equal false,
|
836
|
+
TreeParser.in_context?(adaptor, TOKEN_NAMES, node, "VEC")
|
837
|
+
end
|
838
|
+
|
839
|
+
def test_parent_with_wildcard
|
840
|
+
tree = "(nil (ASSIGN ID[x] INT[3]) (PRINT (MULT ID[x] (VEC INT[1] INT[2] INT[3]))))"
|
841
|
+
adaptor = CommonTreeAdaptor.new
|
842
|
+
wiz = Wizard.new(adaptor, TOKEN_NAMES)
|
843
|
+
t = wiz.create(tree)
|
844
|
+
|
845
|
+
labels = {}
|
846
|
+
assert wiz.parse(t,
|
847
|
+
"(nil (ASSIGN ID[x] INT[3]) (PRINT (MULT ID (VEC INT %x:INT INT))))",
|
848
|
+
labels)
|
849
|
+
node = labels['x']
|
850
|
+
|
851
|
+
assert_equal true,
|
852
|
+
TreeParser.in_context?(adaptor, TOKEN_NAMES, node, 'VEC ...')
|
853
|
+
end
|
854
|
+
end
|