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/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 BaseRecognizer to the task of tree-pattern
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 BaseRecognizer API.
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 < BaseRecognizer
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
- #def set_child(index, tree)
260
- # self.children[index] = tree
261
- #end
234
+ def root?
235
+ parent.nil?
236
+ end
237
+ alias detached? root?
262
238
 
263
- #alias []= set_child
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
- #def to_a
274
- # child_arrays = children.map { |child| child.to_a }
275
- # [token, *child_arrays]
276
- #end
249
+ def leaf?
250
+ children.nil? or children.empty?
251
+ end
277
252
 
278
- #include Enumerable
279
- #
280
- #def each_child
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
- if equal?( child_tree.children )
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
- to_s.each_line do | line |
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 = flat_list? ? ['', ''] : ["(#{self}", ')']
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!( token_type, from_token, text = nil )
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!( token_type, text )
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!( input, start, stop, exc )
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!( payload )
878
+ def create_with_payload( payload )
886
879
  return CommonTree.new( payload )
887
880
  end
888
-
889
- def create!( *args )
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( '' )
@@ -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