1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# encoding: utf-8
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin LICENSE
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[The "BSD licence"]
7324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverCopyright (c) 2009-2010 Kyle Yetter
8324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverAll rights reserved.
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
10324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverRedistribution and use in source and binary forms, with or without
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodification, are permitted provided that the following conditions
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverare met:
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1. Redistributions of source code must retain the above copyright
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    notice, this list of conditions and the following disclaimer.
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2. Redistributions in binary form must reproduce the above copyright
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    notice, this list of conditions and the following disclaimer in the
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    documentation and/or other materials provided with the distribution.
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 3. The name of the author may not be used to endorse or promote products
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    derived from this software without specific prior written permission.
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
22324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3'
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule ANTLR3
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
41324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverName space containing all of the entities pertaining to tree construction and
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertree parsing.
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule AST
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverautoload :Wizard, 'antlr3/tree/wizard'
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverautoload :Visitor, 'antlr3/tree/visitor'
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver####################################################################################################
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################ Tree Parser ###########################################
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver####################################################################################################
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::TreeParser
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver= TreeParser
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
59324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTreeParser is the default base class of ANTLR-generated tree parsers. The class
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertailors the functionality provided by Recognizer to the task of tree-pattern
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrecognition.
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver== About Tree Parsers
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
65324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR generates three basic types of recognizers:
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* lexers
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* parsers
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* tree parsers
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
70324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverFurthermore, it is capable of generating several different flavors of parser,
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverincluding parsers that take token input and use it to build Abstract Syntax
72324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTrees (ASTs), tree structures that reflect the high-level syntactic and semantic
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstructures defined by the language.
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
75324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverYou can take the information encapsulated by the AST and process it directly in
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvera program. However, ANTLR also provides a means to create a recognizer which is
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvercapable of walking through the AST, verifying its structure and performing
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvercustom actions along the way -- tree parsers.
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
80324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTree parsers are created from tree grammars. ANTLR-generated tree parsers
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclosely mirror the general structure of regular parsers and lexers.
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
83324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverFor more in-depth coverage of the topic, check out the ANTLR documentation
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver(http://www.antlr.org).
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver== The Tree Parser API
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
88324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverLike Parser, the class does not stray too far from the Recognizer API.
89324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverMainly, it customizes a few methods specifically to deal with tree nodes
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver(instead of basic tokens), and adds some helper methods for working with trees.
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
92324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverLike all ANTLR recognizers, tree parsers contained a shared state structure and
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveran input stream, which should be a TreeNodeStream. ANTLR intends to keep its
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertree features flexible and customizable, and thus it does not make any
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverassumptions about the class of the actual nodes it processes. One consequence of
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverthis flexibility is that tree parsers also require an extra tree adaptor object,
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverthe purpose of which is to provide a homogeneous interface for handling tree
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconstruction and analysis of your tree nodes.
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
100324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSee Tree and TreeAdaptor for more information.
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TreeParser < Recognizer
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def self.main( argv = ARGV, options = {} )
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if ::Hash === argv then argv, options = ARGV, argv end
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    main = ANTLR3::Main::WalkerMain.new( self, options )
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    block_given? ? yield( main ) : main.execute( argv )
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def initialize( input, options = {} )
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super( options )
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @input = input
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias tree_node_stream input
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias tree_node_stream= input=
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def source_name
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @input.source_name
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def missing_symbol( error, expected_token_type, follow )
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    name = token_name( expected_token_type ).to_s
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    text = "<missing " << name << '>'
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tk = create_token do |t|
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      t.text = text
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      t.type = expected_token_type
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( CommonTree.new( tk ) )
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def match_any( ignore = nil )
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @state.error_recovery = false
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    look, adaptor = @input.look, @input.tree_adaptor
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if adaptor.child_count( look ) == 0
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @input.consume
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      return
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    level = 0
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    while type = @input.peek and type != EOF
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      #token_type == EOF or ( token_type == UP && level == 0 )
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @input.consume
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      case type
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      when DOWN then level += 1
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      when UP
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        level -= 1
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        level.zero? and break
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def mismatch( input, type, follow = nil )
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    raise MismatchedTreeNode.new( type, input )
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def error_header( e )
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    <<-END.strip!
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    #{ grammar_file_name }: node from #{ 
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      e.approximate_line_info? ? 'after ' : ''
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    } line #{ e.line }:#{ e.column }
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    END
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def error_message( e )
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    adaptor = e.input.adaptor
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    e.token = adaptor.token( e.node )
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    e.token ||= create_token do | tok |
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      tok.type = adaptor.type_of( e.node )
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      tok.text = adaptor.text_of( e.node )
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return super( e )
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def trace_in( rule_name, rule_index )
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super( rule_name, rule_index, @input.look )
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def trace_out( rule_name, rule_index )
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super( rule_name, rule_index, @input.look )
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver####################################################################################################
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################ Tree Nodes ############################################
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver####################################################################################################
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::Tree
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver= ANTLR Abstract Syntax Trees
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
194324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverAs ANTLR is concerned, an Abstract Syntax Tree (AST) node is an object that
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverwraps a token, a list of child trees, and some information about the collective
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversource text embodied within the tree and its children.
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
198324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverThe Tree module, like the Token and Stream modules, emulates an abstract base
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass for AST classes; it specifies the attributes that are expected of basic
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertree nodes as well as the methods trees need to implement.
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver== Terminology
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
204324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverWhile much of this terminology is probably familiar to most developers, the
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverfollowing brief glossary is intended to clarify terminology used in code
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverthroughout the AST library:
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[payload] either a token value contained within a node or +nil+
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[flat list (nil tree)] a tree node without a token payload, but with more 
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                       than one children -- functions like an array of 
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                       tree nodes
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[root] a top-level tree node, i.e. a node that does not have a parent
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[leaf] a node that does not have any children
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[siblings] all other nodes sharing the same parent as some node
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[ancestors] the list of successive parents from a tree node to the root node
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[error node] a special node used to represent an erroneous series of tokens
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver             from an input stream
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule Tree
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  #attr_accessor :parent
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_accessor :start_index
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_accessor :stop_index
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_accessor :child_index
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_reader :type
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_reader :text
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_reader :line
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_reader :column
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  #attr_reader :children
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_reader :token
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def root?
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parent.nil?
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias detached? root?
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def root
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    cursor = self
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    until cursor.root?
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      yield( parent_node = cursor.parent )
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      cursor = parent_node
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( cursor )
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  #
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def leaf?
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    children.nil? or children.empty?
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def has_child?( node )
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    children and children.include?( node )
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def depth
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    root? ? 0 : parent.depth + 1
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def siblings
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    root? and return []
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parent.children.reject { | c | c.equal?( self ) }
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def each_ancestor
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    block_given? or return( enum_for( :each_ancestor ) )
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    cursor = self
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    until cursor.root?
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      yield( parent_node = cursor.parent )
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      cursor = parent_node
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( self )
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def ancestors
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    each_ancestor.to_a
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def walk
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    block_given? or return( enum_for( :walk ) )
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stack = []
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    cursor = self
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    while true
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      begin
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        yield( cursor )
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        stack.push( cursor.children.dup ) unless cursor.empty?
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      rescue StopIteration
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # skips adding children to prune the node
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      ensure
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        break if stack.empty?
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        cursor = stack.last.shift
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        stack.pop if stack.last.empty?
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return self
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::BaseTree
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
305324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA base implementation of an Abstract Syntax Tree Node. It mainly defines the
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermethods and attributes required to implement the parent-node-children
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrelationship that characterize a tree; it does not provide any logic concerning
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvera node's token <i>payload</i>.
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass BaseTree < ::Array
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_accessor :parent
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  extend ClassMacros
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include Tree
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def initialize( node = nil )
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super()
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @parent = nil
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @child_index = 0
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def children() self end
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias child at
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias child_count length
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def first_with_type( tree_type )
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    find { | child | child.type == tree_type }
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def add_child( child_tree )
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    child_tree.nil? and return
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if child_tree.flat_list?
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      self.equal?( child_tree.children ) and
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise ArgumentError, "attempt to add child list to itself"
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      child_tree.each_with_index do | child, index |
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        child.parent = self
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        child.child_index = length + index
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      concat( child_tree )
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      child_tree.child_index = length
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      child_tree.parent = self
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      self << child_tree
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( self )
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def detach
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @parent = nil
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @child_index = -1
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( self )
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias add_children concat
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias each_child each
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def set_child( index, tree )
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return if tree.nil?
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.flat_list? and raise ArgumentError, "Can't set single child to a list"
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.parent = self
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.child_index = index
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self[ index ] = tree
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def delete_child( index )
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    killed = delete_at( index ) and freshen( index )
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return killed
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def replace_children( start, stop, new_tree )
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    start >= length or stop >= length and
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      raise IndexError, ( <<-END ).gsub!( /^\s+\| /,'' )
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      | indices span beyond the number of children:
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      |  children.length = #{ length }
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      |  start = #{ start_index.inspect }
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      |  stop  = #{ stop_index.inspect }
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      END
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    new_children = new_tree.flat_list? ? new_tree : [ new_tree ]
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self[ start .. stop ] = new_children
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    freshen( start_index )
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return self
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def flat_list?
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    false
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def freshen( offset = 0 )
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    for i in offset ... length
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      node = self[ i ]
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      node.child_index = i
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      node.parent = self
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def sanity_check( parent = nil, i = -1 )
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parent == @parent or
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      raise TreeInconsistency.failed_parent_check!( parent, @parent )
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    i == @child_index or
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      raise TreeInconsistency.failed_index_check!( i, @child_index )
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    each_with_index do | child, index |
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      child.sanity_check( self, index )
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def inspect
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    empty? and return to_s
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    buffer = ''
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    buffer << '(' << to_s << ' ' unless flat_list?
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    buffer << map { | c | c.inspect }.join( ' ' )
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    buffer << ')' unless flat_list?
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( buffer )
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def walk
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    block_given? or return( enum_for( :walk ) )
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stack = []
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    cursor = self
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    while true
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      begin
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        yield( cursor )
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        stack.push( Array[ *cursor ] ) unless cursor.empty?
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      rescue StopIteration
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # skips adding children to prune the node
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      ensure
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        break if stack.empty?
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        cursor = stack.last.shift
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        stack.pop if stack.last.empty?
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return self
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def prune
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    raise StopIteration
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  abstract :to_s
441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  #protected :sanity_check, :freshen
442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def root?() @parent.nil? end
444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias leaf? empty?
445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::CommonTree
449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
450324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverThe default Tree class implementation used by ANTLR tree-related code.
451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
452324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA CommonTree object is a tree node that wraps a token <i>payload</i> (or a +nil+
453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervalue) and contains zero or more child tree nodes. Additionally, it tracks
454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverinformation about the range of data collectively spanned by the tree node: 
455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* the token stream start and stop indexes of tokens contained throughout 
457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  the tree 
458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* that start and stop positions of the character input stream from which 
459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  the tokens were defined
460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
461324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTracking this information simplifies tasks like extracting a block of code or
462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrewriting the input stream. However, depending on the purpose of the
463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverapplication, building trees with all of this extra information may be
464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverunnecessary. In such a case, a more bare-bones tree class could be written
465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver(optionally using the BaseTree class or the Token module). Define a customized
466324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTreeAdaptor class to handle tree construction and manipulation for the
467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvercustomized node class, and recognizers will be able to build, rewrite, and parse
468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverthe customized lighter-weight trees.
469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass CommonTree < BaseTree
473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def initialize( payload = nil )
474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super()
475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @start_index = -1
476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @stop_index = -1
477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @child_index = -1
478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    case payload
479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when CommonTree then   # copy-constructor style init
480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @token       = payload.token
481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @start_index = payload.start_index
482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @stop_index  = payload.stop_index
483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when nil, Token then @token = payload
484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else raise ArgumentError,
485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      "Invalid argument type: %s (%p)" % [ payload.class, payload ]
486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def initialize_copy( orig )
490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super
491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    clear
492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @parent = nil
493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def copy_node
496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return self.class.new( @token )
497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def flat_list?
500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @token.nil?
501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def type
504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @token ? @token.type : 0
505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def text
508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @token.text rescue nil
509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def line
512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if @token.nil? or @token.line == 0
513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      return ( empty? ? 0 : first.line )
514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return @token.line
516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def column
519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if @token.nil? or @token.column == -1
520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      return( empty? ? 0 : first.column )
521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return @token.column
523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def start_index
526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @start_index == -1 and @token and return @token.index
527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return @start_index
528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def stop_index
531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @stop_index == -1 and @token and return @token.index
532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return @stop_index
533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias token_start_index= start_index=
536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias token_stop_index= stop_index=
537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias token_start_index start_index
538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias token_stop_index stop_index
539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def name
541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @token.name rescue 'INVALID'
542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def token_range
545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    unknown_boundaries? and infer_boundaries
546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @start_index .. @stop_index
547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def source_range
550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    unknown_boundaries? and infer_boundaries
551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tokens = map do | node |
552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      tk = node.token and tk.index >= 0 ? tk : nil
553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tokens.compact!
555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    first, last = tokens.minmax_by { |t| t.index }
556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    first.start .. last.stop
557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def infer_boundaries
560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if empty? and @start_index < 0 || @stop_index < 0
561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @start_index = @stop_index = @token.index rescue -1
562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      return
563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    for child in self do child.infer_boundaries end
565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return if @start_index >= 0 and @stop_index >= 0
566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @start_index = first.start_index
568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @stop_index  = last.stop_index
569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return nil
570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def unknown_boundaries?
573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @start_index < 0 or @stop_index < 0
574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def to_s
577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    flat_list? ? 'nil' : @token.text.to_s
578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def pretty_print( printer )
581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    text = @token ? @token.text : 'nil'
582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    text =~ /\s+/ and
583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      text = text.dump
584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if empty?
586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      printer.text( text )
587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      endpoints = @token ? [ "(#{ text }", ')' ] : [ '', '' ]
589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      printer.group( 1, *endpoints ) do
590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for child in self
591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          printer.breakable
592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          printer.pp( child )
593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        end
594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::CommonErrorNode
601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
602324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverRepresents a series of erroneous tokens from a token stream input
603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass CommonErrorNode < CommonTree
607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include ANTLR3::Error
608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include ANTLR3::Constants
609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_accessor :input, :start, :stop, :error
611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def initialize( input, start, stop, error )
613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super( nil )
614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stop = start if stop.nil? or
615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      ( stop.token_index < start.token_index and stop.type != EOF )
616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @input = input
617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @start = start
618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @stop = stop
619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @error = error
620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def flat_list?
623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return false
624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def type
627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    INVALID_TOKEN_TYPE
628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def text
631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    case @start
632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when Token
633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      i = @start.token_index
634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      j = ( @stop.type == EOF ) ? @input.size : @stop.token_index
635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @input.to_s( i, j )            # <- the bad text
636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when Tree
637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @input.to_s( @start, @stop )   # <- the bad text
638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      "<unknown>"
640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def to_s
644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    case @error
645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when MissingToken
646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      "<missing type: #{ @error.missing_type }>"
647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when UnwantedToken
648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      "<extraneous: #{ @error.token.inspect }, resync = #{ text }>"
649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when MismatchedToken
650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      "<mismatched token: #{ @error.token.inspect }, resync = #{ text }>"
651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when NoViableAlternative
652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      "<unexpected: #{ @error.token.inspect }, resync = #{ text }>"
653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else "<error: #{ text }>"
654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
659324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverConstants::INVALID_NODE = CommonTree.new( ANTLR3::INVALID_TOKEN )
660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver####################################################################################################
662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver########################################### Tree Adaptors ##########################################
663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver####################################################################################################
664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::TreeAdaptor
666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
667324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSince a tree can be represented by a multitude of formats, ANTLR's tree-related
668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvercode mandates the use of Tree Adaptor objects to build and manipulate any actual
669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertrees. Using an adaptor object permits a single recognizer to work with any
670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernumber of different tree structures without adding rigid interface requirements
671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveron customized tree structures. For example, if you want to represent trees using
672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversimple arrays of arrays, you just need to design an appropriate tree adaptor and
673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverprovide it to the parser.
674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
675324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTree adaptors are tasked with:
676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* copying and creating tree nodes and tokens
678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* defining parent-child relationships between nodes
679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* cleaning up / normalizing a full tree structure after construction
680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* reading and writing the attributes ANTLR expects of tree nodes
681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver* providing node access and iteration
682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule TreeAdaptor
686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include TokenFactory
687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include Constants
688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include Error
689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def add_child( tree, child )
691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.add_child( child ) if tree and child
692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def child_count( tree )
695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.child_count
696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def child_index( tree )
699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.child_index rescue 0
700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def child_of( tree, index )
703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.nil? ? nil : tree.child( index )
704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def copy_node( tree_node )
707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree_node and tree_node.dup
708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def copy_tree( tree, parent = nil )
711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree or return nil
712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    new_tree = copy_node( tree )
713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    set_child_index( new_tree, child_index( tree ) )
714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    set_parent( new_tree, parent )
715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    each_child( tree ) do | child |
716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      new_sub_tree = copy_tree( child, new_tree )
717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      add_child( new_tree, new_sub_tree )
718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return new_tree
720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def delete_child( tree, index )
723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.delete_child( index )
724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def each_child( tree )
728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    block_given? or return enum_for( :each_child, tree )
729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    for i in 0 ... child_count( tree )
730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      yield( child_of( tree, i ) )
731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return tree
733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def each_ancestor( tree, include_tree = true )
736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    block_given? or return enum_for( :each_ancestor, tree, include_tree )
737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if include_tree
738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      begin yield( tree ) end while tree = parent_of( tree )
739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      while tree = parent_of( tree ) do yield( tree ) end
741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def flat_list?( tree )
745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.flat_list?
746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def empty?( tree )
749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    child_count( tree ).zero?
750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def parent( tree )
753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.parent
754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def replace_children( parent, start, stop, replacement )
757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parent and parent.replace_children( start, stop, replacement )
758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def rule_post_processing( root )
761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if root and root.flat_list?
762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      case root.child_count
763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      when 0 then root = nil
764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      when 1
765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        root = root.child( 0 ).detach
766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return root
769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def set_child_index( tree, index )
772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.child_index = index
773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def set_parent( tree, parent )
776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.parent = parent
777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def set_token_boundaries( tree, start_token = nil, stop_token = nil )
780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return unless tree
781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    start = stop = 0
782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    start_token and start = start_token.index
783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stop_token  and stop  = stop_token.index
784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.start_index = start
785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.stop_index = stop
786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return tree
787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def text_of( tree )
790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.text rescue nil
791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def token( tree )
794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    CommonTree === tree ? tree.token : nil
795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def token_start_index( tree )
798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree ? tree.token_start_index : -1
799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def token_stop_index( tree )
802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree ? tree.token_stop_index : -1
803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def type_name( tree )
806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.name rescue 'INVALID'
807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def type_of( tree )
810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.type rescue INVALID_TOKEN_TYPE
811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def unique_id( node )
814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    node.hash
815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::CommonTreeAdaptor
820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
821324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverThe default tree adaptor used by ANTLR-generated tree code. It, of course,
822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverbuilds and manipulates CommonTree nodes.
823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
824324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass CommonTreeAdaptor
827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  extend ClassMacros
828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include TreeAdaptor
829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include ANTLR3::Constants
830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def initialize( token_class = ANTLR3::CommonToken )
832324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @token_class = token_class
833324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def create_flat_list
836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return create_with_payload( nil )
837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
838324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias create_flat_list! create_flat_list
839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def become_root( new_root, old_root )
841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    new_root = create( new_root ) if new_root.is_a?( Token )
842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    old_root or return( new_root )
843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
844324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    new_root = create_with_payload( new_root ) unless CommonTree === new_root
845324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if new_root.flat_list?
846324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      count = new_root.child_count
847324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      if count == 1
848324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        new_root = new_root.child( 0 )
849324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      elsif count > 1
850324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise TreeInconsistency.multiple_roots!
851324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
852324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
853324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
854324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    new_root.add_child( old_root )
855324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return new_root
856324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
857324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
858324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def create_from_token( token_type, from_token, text = nil )
859324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    from_token = from_token.dup
860324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    from_token.type = token_type
861324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    from_token.text = text.to_s if text
862324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree = create_with_payload( from_token )
863324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return tree
864324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
865324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
866324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def create_from_type( token_type, text )
867324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    from_token = create_token( token_type, DEFAULT_CHANNEL, text )
868324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    create_with_payload( from_token )
869324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
870324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
871324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def create_error_node( input, start, stop, exc )
872324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    CommonErrorNode.new( input, start, stop, exc )
873324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
874324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
875324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def create_with_payload( payload )
876324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return CommonTree.new( payload )
877324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
878324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
879324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def create( *args )
880324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    n = args.length
881324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if n == 1 and args.first.is_a?( Token ) then create_with_payload( args[ 0 ] )
882324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    elsif n == 2 and Integer === args.first and String === args[ 1 ]
883324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      create_from_type( *args )
884324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    elsif n >= 2 and Integer === args.first
885324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      create_from_token( *args )
886324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
887324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      sig = args.map { |f| f.class }.join( ', ' )
888324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      raise TypeError, "No create method with this signature found: (#{ sig })"
889324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
890324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
891324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
892324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  creation_methods = %w(
893324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    create_from_token create_from_type
894324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    create_error_node create_with_payload
895324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    create
896324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  )
897324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
898324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  for method_name in creation_methods
899324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    bang_method = method_name + '!'
900324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    alias_method( bang_method, method_name )
901324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    deprecate( bang_method, "use method ##{ method_name } instead" )
902324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
903324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
904324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def rule_post_processing( root )
905324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if root and root.flat_list?
906324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      if root.empty? then root = nil
907324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      elsif root.child_count == 1 then root = root.first.detach
908324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
909324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
910324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return root
911324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
912324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
913324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def empty?( tree )
914324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.empty?
915324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
916324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
917324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def each_child( tree )
918324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    block_given? or return enum_for( :each_child, tree )
919324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tree.each do | child |
920324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      yield( child )
921324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
922324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
923324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
924324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
925324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
926324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
927324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver####################################################################################################
928324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver########################################### Tree Streams ###########################################
929324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver####################################################################################################
930324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
931324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::TreeNodeStream
932324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
933324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTreeNodeStreams flatten two-dimensional tree structures into one-dimensional
934324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruversequences. They preserve the two-dimensional structure of the tree by inserting
935324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverspecial +UP+ and +DOWN+ nodes.
936324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
937324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverConsider a hypothetical tree:
938324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
939324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  [A]
940324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver   +--[B]
941324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver   |   +--[C]
942324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver   |   `--[D]
943324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver   `--[E]
944324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver       `--[F]
945324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
946324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA tree node stream would serialize the tree into the following sequence:
947324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
948324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  A DOWN B DOWN C D UP E DOWN F UP UP EOF
949324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
950324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOther than serializing a tree into a sequence of nodes, a tree node stream
951324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveroperates similarly to other streams. They are commonly used by tree parsers as
952324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverthe main form of input. #peek, like token streams, returns the type of the token
953324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverof the next node. #look returns the next full tree node.
954324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
955324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
956324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
957324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule TreeNodeStream
958324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  extend ClassMacros
959324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include Stream
960324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include Constants
961324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
962324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  abstract :at
963324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  abstract :look
964324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  abstract :tree_source
965324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  abstract :token_stream
966324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  abstract :tree_adaptor
967324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  abstract :unique_navigation_nodes=
968324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  abstract :to_s
969324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  abstract :replace_children
970324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
971324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
972324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::CommonTreeNodeStream
973324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
974324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverAn implementation of TreeNodeStream tailed for streams based on CommonTree
975324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverobjects. CommonTreeNodeStreams are the default input streams for tree parsers.
976324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
977324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
978324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
979324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass CommonTreeNodeStream
980324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include TreeNodeStream
981324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
982324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_accessor :token_stream
983324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_reader :adaptor, :position
984324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
985324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def initialize( *args )
986324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    options = args.last.is_a?( ::Hash ) ? args.pop : {}
987324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    case n = args.length
988324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when 1
989324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @root = args.first
990324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @token_stream = @adaptor = @nodes = @down = @up = @eof = nil
991324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when 2
992324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @adaptor, @root = args
993324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @token_stream = @nodes = @down = @up = @eof = nil
994324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when 3
995324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      parent, start, stop = *args
996324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @adaptor = parent.adaptor
997324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @root = parent.root
998324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @nodes = parent.nodes[ start ... stop ]
999324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @down = parent.down
1000324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @up = parent.up
1001324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @eof = parent.eof
1002324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @token_stream = parent.token_stream
1003324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when 0
1004324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      raise ArgumentError, "wrong number of arguments (0 for 1)"
1005324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else raise ArgumentError, "wrong number of arguments (#{ n } for 3)"
1006324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
1007324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @adaptor ||= options.fetch( :adaptor ) { CommonTreeAdaptor.new }
1008324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @token_stream ||= options[ :token_stream ]
1009324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @down  ||= options.fetch( :down ) { @adaptor.create_from_type( DOWN, 'DOWN' ) }
1010324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @up    ||= options.fetch( :up )   { @adaptor.create_from_type( UP, 'UP' ) }
1011324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @eof   ||= options.fetch( :eof )  { @adaptor.create_from_type( EOF, 'EOF' ) }
1012324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @nodes ||= []
1013324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
1014324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @unique_navigation_nodes = options.fetch( :unique_navigation_nodes, false )
1015324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position = -1
1016324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @last_marker = nil
1017324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @calls = []
1018324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1019324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1020324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def fill_buffer( tree = @root )
1021324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @nodes << tree unless nil_tree = @adaptor.flat_list?( tree )
1022324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    unless @adaptor.empty?( tree )
1023324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      add_navigation_node( DOWN ) unless nil_tree
1024324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @adaptor.each_child( tree ) { | c | fill_buffer( c ) }
1025324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      add_navigation_node( UP ) unless nil_tree
1026324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
1027324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position = 0 if tree == @root
1028324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( self )
1029324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1030324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1031324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def node_index( node )
1032324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position == -1 and fill_buffer
1033324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return @nodes.index( node )
1034324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1035324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1036324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def add_navigation_node( type )
1037324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    navigation_node =
1038324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      case type
1039324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      when DOWN
1040324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        has_unique_navigation_nodes? ? @adaptor.create_from_type( DOWN, 'DOWN' ) : @down
1041324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      else
1042324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        has_unique_navigation_nodes? ? @adaptor.create_from_type( UP, 'UP' ) : @up
1043324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
1044324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @nodes << navigation_node
1045324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1046324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1047324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def at( index )
1048324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position == -1 and fill_buffer
1049324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @nodes.at( index )
1050324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1051324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1052324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def look( k = 1 )
1053324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position == -1 and fill_buffer
1054324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    k == 0 and return nil
1055324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    k < 0 and return self.look_behind( -k )
1056324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
1057324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    absolute = @position + k - 1
1058324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @nodes.fetch( absolute, @eof )
1059324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1060324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1061324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def current_symbol
1062324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    look
1063324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1064324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1065324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def look_behind( k = 1 )
1066324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    k == 0 and return nil
1067324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    absolute = @position - k
1068324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( absolute < 0 ? nil : @nodes.fetch( absolute, @eof ) )
1069324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1070324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1071324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def tree_source
1072324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @root
1073324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1074324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1075324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def source_name
1076324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self.token_stream.source_name
1077324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1078324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1079324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def tree_adaptor
1080324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @adaptor
1081324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1082324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1083324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def has_unique_navigation_nodes?
1084324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return @unique_navigation_nodes
1085324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1086324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_writer :unique_navigation_nodes
1087324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1088324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def consume
1089324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position == -1 and fill_buffer
1090324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    node = @nodes.fetch( @position, @eof )
1091324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position += 1
1092324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( node )
1093324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1094324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1095324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def peek( i = 1 )
1096324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @adaptor.type_of look( i )
1097324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1098324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1099324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias >> peek
1100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def <<( k )
1101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self >> -k
1102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def mark
1105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position == -1 and fill_buffer
1106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @last_marker = @position
1107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return @last_marker
1108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def release( marker = nil )
1111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # do nothing?
1112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias index position
1115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def rewind( marker = @last_marker, release = true )
1117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    seek( marker )
1118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def seek( index )
1121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position == -1 and fill_buffer
1122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position = index
1123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def push( index )
1126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @calls << @position
1127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    seek( index )
1128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def pop
1131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pos = @calls.pop and seek( pos )
1132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return pos
1133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def reset
1136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position = 0
1137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @last_marker = 0
1138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @calls = []
1139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def replace_children( parent, start, stop, replacement )
1142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parent and @adaptor.replace_children( parent, start, stop, replacement )
1143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def size
1146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position == -1 and fill_buffer
1147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return @nodes.length
1148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def inspect
1151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position == -1 and fill_buffer
1152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @nodes.map { |nd| @adaptor.type_name( nd ) }.join( ' ' )
1153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def extract_text( start = nil, stop = nil )
1156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    start.nil? || stop.nil? and return nil
1157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position == -1 and fill_buffer
1158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
1159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if @token_stream
1160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      from = @adaptor.token_start_index( start )
1161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      to = 
1162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        case @adaptor.type_of( stop )
1163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        when UP then @adaptor.token_stop_index( start )
1164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        when EOF then to = @nodes.length - 2
1165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else @adaptor.token_stop_index( stop )
1166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        end
1167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      return @token_stream.extract_text( from, to )
1168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
1169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
1170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    buffer = ''
1171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    for node in @nodes
1172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      if node == start ... node == stop  # <-- hey look, it's the flip flop operator
1173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        buffer << @adaptor.text_of( node ) #|| ' ' << @adaptor.type_of( node ).to_s )
1174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
1175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
1176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( buffer )
1177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def each
1180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position == -1 and fill_buffer
1181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    block_given? or return enum_for( :each )
1182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    for node in @nodes do yield( node ) end
1183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    self
1184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include Enumerable
1187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def to_a
1189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return @nodes.dup
1190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def extract_text( start = nil, stop = nil )
1193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @position == -1 and fill_buffer
1194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    start ||= @nodes.first
1195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stop  ||= @nodes.last
1196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
1197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if @token_stream
1198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      case @adaptor.type_of( stop )
1199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      when UP
1200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        stop_index = @adaptor.token_stop_index( start )
1201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      when EOF
1202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return extract_text( start, @nodes[ - 2 ] )
1203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      else
1204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        stop_index = @adaptor.token_stop_index( stop )
1205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
1206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
1207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      start_index = @adaptor.token_start_index( start )
1208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      return @token_stream.extract_text( start_index, stop_index )
1209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
1210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      start_index = @nodes.index( start ) || @nodes.length
1211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      stop_index  = @nodes.index( stop )  || @nodes.length
1212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      return( 
1213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @nodes[ start_index .. stop_index ].map do | n |
1214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          @adaptor.text_of( n ) or " " + @adaptor.type_of( n ).to_s
1215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        end.join( '' )
1216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      )
1217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
1218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias to_s extract_text
1221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#private
1223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#  
1224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#  def linear_node_index( node )
1225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#    @position == -1 and fill_buffer
1226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#    @nodes.each_with_index do |n, i|
1227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#      node == n and return(i)
1228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#    end
1229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#    return -1
1230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#  end
1231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
1232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::RewriteRuleElementStream
1234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1235324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSpecial type of stream that is used internally by tree-building and tree-
1236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrewriting parsers.
1237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
1239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteRuleElementStream # < Array
1241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  extend ClassMacros
1242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include Error
1243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def initialize( adaptor, element_description, elements = nil )
1245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @cursor = 0
1246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @single_element = nil
1247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @elements = nil
1248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @dirty = false
1249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @element_description = element_description
1250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @adaptor = adaptor
1251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if elements.instance_of?( Array )
1252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @elements = elements
1253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
1254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      add( elements )
1255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
1256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def reset
1259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @cursor = 0
1260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @dirty = true
1261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def add( el )
1264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( nil ) unless el
1265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    case
1266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when ! el then return( nil )
1267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when @elements then @elements << el
1268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when @single_element.nil? then @single_element = el
1269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
1270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @elements = [ @single_element, el ]
1271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @single_element = nil
1272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      return( @elements )
1273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
1274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def next_tree
1277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if @dirty or @cursor >= length && length == 1
1278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      return dup( __next__ )
1279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
1280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    __next__
1281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  abstract :dup
1284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def to_tree( el )
1286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return el
1287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def has_next?
1290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( @single_element && @cursor < 1 or
1291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver           @elements && @cursor < @elements.length )
1292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def size
1295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @single_element and return 1
1296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @elements and return @elements.length
1297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return 0
1298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias length size
1301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverprivate
1303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def __next__
1305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    l = length
1306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    case
1307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when l.zero?
1308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      raise Error::RewriteEmptyStream.new( @element_description )
1309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when @cursor >= l
1310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      l == 1 and return to_tree( @single_element )
1311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      raise RewriteCardinalityError.new( @element_description )
1312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when @single_element
1313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @cursor += 1
1314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      return( to_tree( @single_element ) )
1315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
1316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      out = to_tree( @elements.at( @cursor ) )
1317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @cursor += 1
1318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      return( out )
1319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
1320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
1322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::RewriteRuleTokenStream
1325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1326324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSpecial type of stream that is used internally by tree-building and tree-
1327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrewriting parsers.
1328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
1330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteRuleTokenStream < RewriteRuleElementStream
1331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def next_node
1332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return @adaptor.create_with_payload( __next__ )
1333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias :next :__next__
1336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  public :next
1337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def dup( el )
1339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    raise TypeError, "dup can't be called for a token stream"
1340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
1342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::RewriteRuleSubtreeStream
1344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1345324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSpecial type of stream that is used internally by tree-building and tree-
1346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrewriting parsers.
1347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
1349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteRuleSubtreeStream < RewriteRuleElementStream
1351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def next_node
1352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if @dirty or @cursor >= length && length == 1
1353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      return @adaptor.copy_node( __next__ )
1354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
1355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return __next__
1356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def dup( el )
1359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @adaptor.copy_tree( el )
1360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
1362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::AST::RewriteRuleNodeStream
1364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1365324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverSpecial type of stream that is used internally by tree-building and tree-
1366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrewriting parsers.
1367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
1369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteRuleNodeStream < RewriteRuleElementStream
1371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  alias next_node __next__
1372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  public :next_node
1373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def to_tree( el )
1374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @adaptor.copy_node( el )
1375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
1377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def dup( el )
1378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    raise TypeError, "dup can't be called for a node stream"
1379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
1380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
1381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
1382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverinclude AST
1384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
1385