antlr3 1.6.0 → 1.6.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +8 -0
- data/Manifest.txt +94 -0
- data/README.txt +1 -1
- data/Rakefile +58 -0
- data/bin/antlr4ruby +101 -7
- data/java/antlr-full-3.2.1.jar +0 -0
- data/lib/antlr3.rb +38 -10
- data/lib/antlr3/constants.rb +13 -5
- data/lib/antlr3/debug.rb +57 -57
- data/lib/antlr3/dfa.rb +138 -68
- data/lib/antlr3/dot.rb +32 -32
- data/lib/antlr3/error.rb +85 -78
- data/lib/antlr3/main.rb +191 -187
- data/lib/antlr3/profile.rb +71 -70
- data/lib/antlr3/recognizers.rb +261 -226
- data/lib/antlr3/streams.rb +85 -84
- data/lib/antlr3/streams/interactive.rb +20 -27
- data/lib/antlr3/streams/rewrite.rb +89 -89
- data/lib/antlr3/task.rb +42 -33
- data/lib/antlr3/template.rb +2 -2
- data/lib/antlr3/template/group-lexer.rb +1 -1
- data/lib/antlr3/token.rb +76 -68
- data/lib/antlr3/tree.rb +125 -121
- data/lib/antlr3/tree/visitor.rb +1 -1
- data/lib/antlr3/tree/wizard.rb +1 -1
- data/lib/antlr3/util.rb +32 -33
- data/lib/antlr3/version.rb +3 -3
- data/templates/Ruby.stg +1 -1
- data/test/unit/test-streams.rb +11 -10
- data/test/unit/test-template.rb +206 -204
- metadata +4 -2
data/lib/antlr3/tree.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
=begin LICENSE
|
5
5
|
|
6
6
|
[The "BSD licence"]
|
7
|
-
Copyright (c) 2009 Kyle Yetter
|
7
|
+
Copyright (c) 2009-2010 Kyle Yetter
|
8
8
|
All rights reserved.
|
9
9
|
|
10
10
|
Redistribution and use in source and binary forms, with or without
|
@@ -57,7 +57,7 @@ autoload :Visitor, 'antlr3/tree/visitor'
|
|
57
57
|
= TreeParser
|
58
58
|
|
59
59
|
TreeParser is the default base class of ANTLR-generated tree parsers. The class
|
60
|
-
tailors the functionality provided by
|
60
|
+
tailors the functionality provided by Recognizer to the task of tree-pattern
|
61
61
|
recognition.
|
62
62
|
|
63
63
|
== About Tree Parsers
|
@@ -85,7 +85,7 @@ For more in-depth coverage of the topic, check out the ANTLR documentation
|
|
85
85
|
|
86
86
|
== The Tree Parser API
|
87
87
|
|
88
|
-
Like Parser, the class does not stray too far from the
|
88
|
+
Like Parser, the class does not stray too far from the Recognizer API.
|
89
89
|
Mainly, it customizes a few methods specifically to deal with tree nodes
|
90
90
|
(instead of basic tokens), and adds some helper methods for working with trees.
|
91
91
|
|
@@ -101,10 +101,10 @@ See Tree and TreeAdaptor for more information.
|
|
101
101
|
|
102
102
|
=end
|
103
103
|
|
104
|
-
class TreeParser <
|
104
|
+
class TreeParser < Recognizer
|
105
105
|
def self.main( argv = ARGV, options = {} )
|
106
106
|
if ::Hash === argv then argv, options = ARGV, argv end
|
107
|
-
main = ANTLR3::Main::WalkerMain.new(self, options)
|
107
|
+
main = ANTLR3::Main::WalkerMain.new( self, options )
|
108
108
|
block_given? ? yield( main ) : main.execute( argv )
|
109
109
|
end
|
110
110
|
|
@@ -121,7 +121,7 @@ class TreeParser < BaseRecognizer
|
|
121
121
|
end
|
122
122
|
|
123
123
|
def missing_symbol( error, expected_token_type, follow )
|
124
|
-
name = token_name(expected_token_type).to_s
|
124
|
+
name = token_name( expected_token_type ).to_s
|
125
125
|
text = "<missing " << name << '>'
|
126
126
|
tk = create_token do |t|
|
127
127
|
t.text = text
|
@@ -152,13 +152,13 @@ class TreeParser < BaseRecognizer
|
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
|
-
def mismatch(input, type, follow = nil)
|
155
|
+
def mismatch( input, type, follow = nil )
|
156
156
|
raise MismatchedTreeNode.new( type, input )
|
157
157
|
end
|
158
158
|
|
159
159
|
def error_header( e )
|
160
160
|
<<-END.strip!
|
161
|
-
#{ grammar_file_name }: node from #{
|
161
|
+
#{ grammar_file_name }: node from #{
|
162
162
|
e.approximate_line_info? ? 'after ' : ''
|
163
163
|
} line #{ e.line }:#{ e.column }
|
164
164
|
END
|
@@ -230,85 +230,72 @@ module Tree
|
|
230
230
|
#attr_reader :children
|
231
231
|
attr_reader :token
|
232
232
|
|
233
|
-
#def [](index, length = nil) # getChild(index)
|
234
|
-
# length.nil? ? self.children[index] : self.children[index, length]
|
235
|
-
#end
|
236
|
-
#
|
237
|
-
#alias child []
|
238
|
-
#
|
239
|
-
#def child_count # getChildCount
|
240
|
-
# self.children.length
|
241
|
-
#end
|
242
|
-
#
|
243
|
-
#def push(node, *nodes)
|
244
|
-
# self.children.push(node, *nodes)
|
245
|
-
#end
|
246
|
-
#
|
247
|
-
#alias << push
|
248
|
-
#
|
249
|
-
#def shift
|
250
|
-
# self.children.shift
|
251
|
-
#end
|
252
|
-
#
|
253
|
-
#def unshift(node, *nodes)
|
254
|
-
# self.children.unshift(node, *nodes)
|
255
|
-
#end
|
256
|
-
#
|
257
|
-
#alias add_child shift
|
258
233
|
|
259
|
-
|
260
|
-
|
261
|
-
|
234
|
+
def root?
|
235
|
+
parent.nil?
|
236
|
+
end
|
237
|
+
alias detached? root?
|
262
238
|
|
263
|
-
|
239
|
+
def root
|
240
|
+
cursor = self
|
241
|
+
until cursor.root?
|
242
|
+
yield( parent_node = cursor.parent )
|
243
|
+
cursor = parent_node
|
244
|
+
end
|
245
|
+
return( cursor )
|
246
|
+
end
|
264
247
|
|
265
|
-
#def delete_child(index)
|
266
|
-
# self.children.delete(index)
|
267
|
-
#end
|
268
|
-
#
|
269
|
-
#def replace_children(start, stop, trees)
|
270
|
-
# self.children[start..stop] = trees
|
271
|
-
#end
|
272
248
|
#
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
#end
|
249
|
+
def leaf?
|
250
|
+
children.nil? or children.empty?
|
251
|
+
end
|
277
252
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
# block_given? or return enum_for(__method__)
|
282
|
-
# self.children.each { |child| yield(child) }
|
283
|
-
#end
|
284
|
-
#
|
285
|
-
#def each_ancestor
|
286
|
-
# block_given? or return enum_for(__method__)
|
287
|
-
# self.ancestors.each { |anc| yield(anc) }
|
288
|
-
#end
|
253
|
+
def has_child?( node )
|
254
|
+
children and children.include?( node )
|
255
|
+
end
|
289
256
|
|
257
|
+
def depth
|
258
|
+
root? ? 0 : parent.depth + 1
|
259
|
+
end
|
290
260
|
|
291
|
-
|
261
|
+
def siblings
|
262
|
+
root? and return []
|
263
|
+
parent.children.reject { | c | c.equal?( self ) }
|
264
|
+
end
|
265
|
+
|
266
|
+
def each_ancestor
|
267
|
+
block_given? or return( enum_for( :each_ancestor ) )
|
268
|
+
cursor = self
|
269
|
+
until cursor.root?
|
270
|
+
yield( parent_node = cursor.parent )
|
271
|
+
cursor = parent_node
|
272
|
+
end
|
273
|
+
return( self )
|
274
|
+
end
|
275
|
+
|
276
|
+
def ancestors
|
277
|
+
each_ancestor.to_a
|
278
|
+
end
|
279
|
+
|
280
|
+
def walk
|
281
|
+
block_given? or return( enum_for( :walk ) )
|
282
|
+
stack = []
|
283
|
+
cursor = self
|
284
|
+
while true
|
285
|
+
begin
|
286
|
+
yield( cursor )
|
287
|
+
stack.push( cursor.children.dup ) unless cursor.empty?
|
288
|
+
rescue StopIteration
|
289
|
+
# skips adding children to prune the node
|
290
|
+
ensure
|
291
|
+
break if stack.empty?
|
292
|
+
cursor = stack.last.shift
|
293
|
+
stack.pop if stack.last.empty?
|
294
|
+
end
|
295
|
+
end
|
296
|
+
return self
|
297
|
+
end
|
292
298
|
|
293
|
-
#alias :each :walk
|
294
|
-
#
|
295
|
-
#def root?
|
296
|
-
# parent.nil?
|
297
|
-
#end
|
298
|
-
#
|
299
|
-
#def leaf?
|
300
|
-
# children.empty?
|
301
|
-
#end
|
302
|
-
|
303
|
-
#def ancestors
|
304
|
-
# a = []
|
305
|
-
# cursor = self
|
306
|
-
# until cursor.root?
|
307
|
-
# a.push(cursor.parent)
|
308
|
-
# cursor = cursor.parent
|
309
|
-
# end
|
310
|
-
# return a
|
311
|
-
#end
|
312
299
|
end
|
313
300
|
|
314
301
|
|
@@ -344,9 +331,8 @@ class BaseTree < ::Array
|
|
344
331
|
def add_child( child_tree )
|
345
332
|
child_tree.nil? and return
|
346
333
|
if child_tree.flat_list?
|
347
|
-
|
334
|
+
self.equal?( child_tree.children ) and
|
348
335
|
raise ArgumentError, "attempt to add child list to itself"
|
349
|
-
end
|
350
336
|
child_tree.each_with_index do | child, index |
|
351
337
|
child.parent = self
|
352
338
|
child.child_index = length + index
|
@@ -367,6 +353,9 @@ class BaseTree < ::Array
|
|
367
353
|
end
|
368
354
|
|
369
355
|
alias add_children concat
|
356
|
+
alias each_child each
|
357
|
+
|
358
|
+
|
370
359
|
|
371
360
|
def set_child( index, tree )
|
372
361
|
return if tree.nil?
|
@@ -383,15 +372,15 @@ class BaseTree < ::Array
|
|
383
372
|
|
384
373
|
def replace_children( start, stop, new_tree )
|
385
374
|
start >= length or stop >= length and
|
386
|
-
raise IndexError, (<<-END).gsub!(/^\s+\| /,'')
|
375
|
+
raise IndexError, ( <<-END ).gsub!( /^\s+\| /,'' )
|
387
376
|
| indices span beyond the number of children:
|
388
|
-
| children.length = #{length}
|
389
|
-
| start = #{start_index.inspect}
|
390
|
-
| stop = #{stop_index.inspect}
|
377
|
+
| children.length = #{ length }
|
378
|
+
| start = #{ start_index.inspect }
|
379
|
+
| stop = #{ stop_index.inspect }
|
391
380
|
END
|
392
381
|
new_children = new_tree.flat_list? ? new_tree : [ new_tree ]
|
393
382
|
self[ start .. stop ] = new_children
|
394
|
-
freshen(start_index)
|
383
|
+
freshen( start_index )
|
395
384
|
return self
|
396
385
|
end
|
397
386
|
|
@@ -451,6 +440,12 @@ class BaseTree < ::Array
|
|
451
440
|
|
452
441
|
abstract :to_s
|
453
442
|
#protected :sanity_check, :freshen
|
443
|
+
|
444
|
+
def root?() @parent.nil? end
|
445
|
+
alias leaf? empty?
|
446
|
+
|
447
|
+
|
448
|
+
|
454
449
|
end
|
455
450
|
|
456
451
|
|
@@ -586,22 +581,19 @@ class CommonTree < BaseTree
|
|
586
581
|
flat_list? ? 'nil' : @token.text.to_s
|
587
582
|
end
|
588
583
|
|
589
|
-
def pretty_print(printer)
|
584
|
+
def pretty_print( printer )
|
585
|
+
text = @token ? @token.text : 'nil'
|
586
|
+
text =~ /\s+/ and
|
587
|
+
text = text.dump
|
588
|
+
|
590
589
|
if empty?
|
591
|
-
|
592
|
-
nl = line.chomp!
|
593
|
-
printer.text( line )
|
594
|
-
if nl
|
595
|
-
printer.text( printer.newline )
|
596
|
-
printer.text( printer.genspace[ printer.indent ] )
|
597
|
-
end
|
598
|
-
end
|
590
|
+
printer.text( text )
|
599
591
|
else
|
600
|
-
endpoints =
|
601
|
-
printer.group(1, *endpoints) do
|
592
|
+
endpoints = @token ? [ "(#{ text }", ')' ] : [ '', '' ]
|
593
|
+
printer.group( 1, *endpoints ) do
|
602
594
|
for child in self
|
603
595
|
printer.breakable
|
604
|
-
printer.pp(child)
|
596
|
+
printer.pp( child )
|
605
597
|
end
|
606
598
|
end
|
607
599
|
end
|
@@ -622,9 +614,9 @@ class CommonErrorNode < CommonTree
|
|
622
614
|
attr_accessor :input, :start, :stop, :error
|
623
615
|
|
624
616
|
def initialize( input, start, stop, error )
|
625
|
-
super(nil)
|
617
|
+
super( nil )
|
626
618
|
stop = start if stop.nil? or
|
627
|
-
(stop.token_index < start.token_index and stop.type != EOF)
|
619
|
+
( stop.token_index < start.token_index and stop.type != EOF )
|
628
620
|
@input = input
|
629
621
|
@start = start
|
630
622
|
@stop = stop
|
@@ -643,7 +635,7 @@ class CommonErrorNode < CommonTree
|
|
643
635
|
case @start
|
644
636
|
when Token
|
645
637
|
i = @start.token_index
|
646
|
-
j = (@stop.type == EOF) ? @input.size : @stop.token_index
|
638
|
+
j = ( @stop.type == EOF ) ? @input.size : @stop.token_index
|
647
639
|
@input.to_s( i, j ) # <- the bad text
|
648
640
|
when Tree
|
649
641
|
@input.to_s( @start, @stop ) # <- the bad text
|
@@ -655,13 +647,13 @@ class CommonErrorNode < CommonTree
|
|
655
647
|
def to_s
|
656
648
|
case @error
|
657
649
|
when MissingToken
|
658
|
-
"<missing type: #{@error.missing_type}>"
|
650
|
+
"<missing type: #{ @error.missing_type }>"
|
659
651
|
when UnwantedToken
|
660
|
-
"<extraneous: #{@error.token.inspect}, resync = #{ text }>"
|
652
|
+
"<extraneous: #{ @error.token.inspect }, resync = #{ text }>"
|
661
653
|
when MismatchedToken
|
662
|
-
"<mismatched token: #{@error.token.inspect}, resync = #{ text }>"
|
654
|
+
"<mismatched token: #{ @error.token.inspect }, resync = #{ text }>"
|
663
655
|
when NoViableAlternative
|
664
|
-
"<unexpected: #{@error.token.inspect}, resync = #{ text }>"
|
656
|
+
"<unexpected: #{ @error.token.inspect }, resync = #{ text }>"
|
665
657
|
else "<error: #{ text }>"
|
666
658
|
end
|
667
659
|
end
|
@@ -843,9 +835,10 @@ class CommonTreeAdaptor
|
|
843
835
|
@token_class = token_class
|
844
836
|
end
|
845
837
|
|
846
|
-
def create_flat_list
|
838
|
+
def create_flat_list
|
847
839
|
return create_with_payload!( nil )
|
848
840
|
end
|
841
|
+
alias create_flat_list! create_flat_list
|
849
842
|
|
850
843
|
def become_root( new_root, old_root )
|
851
844
|
new_root = create!( new_root ) if new_root.is_a?( Token )
|
@@ -865,7 +858,7 @@ class CommonTreeAdaptor
|
|
865
858
|
return new_root
|
866
859
|
end
|
867
860
|
|
868
|
-
def create_from_token
|
861
|
+
def create_from_token( token_type, from_token, text = nil )
|
869
862
|
from_token = from_token.dup
|
870
863
|
from_token.type = token_type
|
871
864
|
from_token.text = text.to_s if text
|
@@ -873,32 +866,43 @@ class CommonTreeAdaptor
|
|
873
866
|
return tree
|
874
867
|
end
|
875
868
|
|
876
|
-
def create_from_type
|
869
|
+
def create_from_type( token_type, text )
|
877
870
|
from_token = create_token( token_type, DEFAULT_CHANNEL, text )
|
878
871
|
create_with_payload!( from_token )
|
879
872
|
end
|
880
873
|
|
881
|
-
def create_error_node
|
874
|
+
def create_error_node( input, start, stop, exc )
|
882
875
|
CommonErrorNode.new( input, start, stop, exc )
|
883
876
|
end
|
884
877
|
|
885
|
-
def create_with_payload
|
878
|
+
def create_with_payload( payload )
|
886
879
|
return CommonTree.new( payload )
|
887
880
|
end
|
888
|
-
|
889
|
-
def create
|
881
|
+
|
882
|
+
def create( *args )
|
890
883
|
n = args.length
|
891
|
-
if n == 1 and args.first.is_a?( Token ) then create_with_payload!( args[0] )
|
892
|
-
elsif n == 2 and Integer === args.first and String === args[1]
|
893
|
-
create_from_type!(*args)
|
884
|
+
if n == 1 and args.first.is_a?( Token ) then create_with_payload!( args[ 0 ] )
|
885
|
+
elsif n == 2 and Integer === args.first and String === args[ 1 ]
|
886
|
+
create_from_type!( *args )
|
894
887
|
elsif n >= 2 and Integer === args.first
|
895
888
|
create_from_token!( *args )
|
896
889
|
else
|
897
|
-
sig = args.map { |f| f.class }.join(', ')
|
890
|
+
sig = args.map { |f| f.class }.join( ', ' )
|
898
891
|
raise TypeError, "No create method with this signature found: (#{ sig })"
|
899
892
|
end
|
900
893
|
end
|
901
894
|
|
895
|
+
# TODO: deprecate create...! methods -- they don't make sense
|
896
|
+
|
897
|
+
# aliases in preparation for deprecation to avoid breaking
|
898
|
+
# backward compatibility
|
899
|
+
|
900
|
+
alias create_from_token! create_from_token
|
901
|
+
alias create_from_type! create_from_type
|
902
|
+
alias create_error_node! create_error_node
|
903
|
+
alias create_with_payload! create_with_payload
|
904
|
+
alias create! create
|
905
|
+
|
902
906
|
def rule_post_processing( root )
|
903
907
|
if root and root.flat_list?
|
904
908
|
if root.empty? then root = nil
|
@@ -980,7 +984,7 @@ class CommonTreeNodeStream
|
|
980
984
|
attr_accessor :token_stream
|
981
985
|
attr_reader :adaptor, :position
|
982
986
|
|
983
|
-
def initialize(*args)
|
987
|
+
def initialize( *args )
|
984
988
|
options = args.last.is_a?( ::Hash ) ? args.pop : {}
|
985
989
|
case n = args.length
|
986
990
|
when 1
|
@@ -1093,7 +1097,7 @@ class CommonTreeNodeStream
|
|
1093
1097
|
end
|
1094
1098
|
|
1095
1099
|
alias >> peek
|
1096
|
-
def <<(k)
|
1100
|
+
def <<( k )
|
1097
1101
|
self >> -k
|
1098
1102
|
end
|
1099
1103
|
|
@@ -1135,7 +1139,7 @@ class CommonTreeNodeStream
|
|
1135
1139
|
end
|
1136
1140
|
|
1137
1141
|
def replace_children( parent, start, stop, replacement )
|
1138
|
-
parent and @adaptor.replace_children(parent, start, stop, replacement)
|
1142
|
+
parent and @adaptor.replace_children( parent, start, stop, replacement )
|
1139
1143
|
end
|
1140
1144
|
|
1141
1145
|
def size
|
@@ -1145,7 +1149,7 @@ class CommonTreeNodeStream
|
|
1145
1149
|
|
1146
1150
|
def inspect
|
1147
1151
|
@position == -1 and fill_buffer
|
1148
|
-
@nodes.map { |nd| @adaptor.type_name( nd ) }.join(' ')
|
1152
|
+
@nodes.map { |nd| @adaptor.type_name( nd ) }.join( ' ' )
|
1149
1153
|
end
|
1150
1154
|
|
1151
1155
|
def extract_text( start = nil, stop = nil )
|
@@ -1205,7 +1209,7 @@ class CommonTreeNodeStream
|
|
1205
1209
|
else
|
1206
1210
|
start_index = @nodes.index( start ) || @nodes.length
|
1207
1211
|
stop_index = @nodes.index( stop ) || @nodes.length
|
1208
|
-
return(
|
1212
|
+
return(
|
1209
1213
|
@nodes[ start_index .. stop_index ].map do | n |
|
1210
1214
|
@adaptor.text_of( n ) or " " + @adaptor.type_of( n ).to_s
|
1211
1215
|
end.join( '' )
|