1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/*
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[The "BSD licence"]
3324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverCopyright (c) 2005-2006 Terence Parr
4324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverAll rights reserved.
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
6324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverRedistribution and use in source and binary forms, with or without
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodification, are permitted provided that the following conditions
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverare met:
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver1. Redistributions of source code must retain the above copyright
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernotice, this list of conditions and the following disclaimer.
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver2. Redistributions in binary form must reproduce the above copyright
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernotice, this list of conditions and the following disclaimer in the
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverdocumentation and/or other materials provided with the distribution.
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver3. The name of the author may not be used to endorse or promote products
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverderived from this software without specific prior written permission.
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
17324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver*/
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpackage org.antlr.runtime.tree {
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	import org.antlr.runtime.TokenConstants;
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	import org.antlr.runtime.TokenStream;
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** A buffered stream of tree nodes.  Nodes can be from a tree of ANY kind.
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This node stream sucks all nodes out of the tree specified in
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  the constructor during construction and makes pointers into
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  the tree using an array of Object pointers. The stream necessarily
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  includes pointers to DOWN and UP and EOF nodes.
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This stream knows how to mark/release for backtracking.
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This stream is most suitable for tree interpreters that need to
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  jump around a lot or for tree parsers requiring speed (at cost of memory).
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  There is some duplicated functionality here with UnBufferedTreeNodeStream
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  but just in bookkeeping, not tree walking etc...
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  @see UnBufferedTreeNodeStream
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public class CommonTreeNodeStream implements TreeNodeStream {
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public static const DEFAULT_INITIAL_BUFFER_SIZE:int = 100;
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public static const INITIAL_CALL_STACK_SIZE:int = 10;
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// all these navigation nodes are shared and hence they
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// cannot contain any line/column info
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var down:Object;
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var up:Object;
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var eof:Object;
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** The complete mapping from stream index to tree node.
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  This buffer includes pointers to DOWN, UP, and EOF nodes.
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  It is built upon ctor invocation.  The elements are type
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  Object as we don't what the trees look like.
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  Load upon first need of the buffer so we can set token types
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  of interest for reverseIndexing.  Slows us down a wee bit to
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  do all of the if p==-1 testing everywhere though.
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var nodes:Array;
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Pull nodes from which tree? */
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var root:Object;
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** IF this tree (root) was created from a token stream, track it. */
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var tokens:TokenStream;
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** What tree adaptor was used to build these trees */
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		internal var adaptor:TreeAdaptor;
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Reuse same DOWN, UP navigation nodes unless this is true */
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var uniqueNavigationNodes:Boolean = false;
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** The index into the nodes list of the current node (next node
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  to consume).  If -1, nodes array not filled yet.
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var p:int = -1;
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Track the last mark() call result value for use in rewind(). */
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var lastMarker:int;
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Stack of indexes used for push/pop calls */
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected var calls:Array;
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function CommonTreeNodeStream(tree:Object, adaptor:TreeAdaptor = null, initialBufferSize:int = DEFAULT_INITIAL_BUFFER_SIZE) {
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		    if (tree == null) {
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		        // return uninitalized for static resuse function
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		        return;
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		    }
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this.root = tree;
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this.adaptor = adaptor == null ? new CommonTreeAdaptor() : adaptor;
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			nodes = new Array();
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			down = this.adaptor.createFromType(TokenConstants.DOWN, "DOWN");
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			up = this.adaptor.createFromType(TokenConstants.UP, "UP");
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			eof = this.adaptor.createFromType(TokenConstants.EOF, "EOF");
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** Reuse an existing node stream's buffer of nodes.  Do not point at a
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  node stream that can change.  Must have static node list.  start/stop
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  are indexes into the parent.nodes stream.  We avoid making a new
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  list of nodes like this.
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static function reuse(parent:CommonTreeNodeStream, start:int, stop:int):CommonTreeNodeStream {
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            var stream:CommonTreeNodeStream = new CommonTreeNodeStream(null);
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stream.root = parent.root;
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stream.adaptor = parent.adaptor;
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stream.nodes = parent.nodes.slice(start, stop);
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stream.down = parent.down;
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stream.up = parent.up;
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stream.eof = parent.eof;
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return stream;
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Walk tree with depth-first-search and fill nodes buffer.
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  Don't do DOWN, UP nodes if its a list (t is isNil).
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected function fillBuffer():void {
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			fillBufferTo(root);
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//System.out.println("revIndex="+tokenTypeToStreamIndexesMap);
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			p = 0; // buffer of nodes intialized now
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function fillBufferTo(t:Object):void {
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var nil:Boolean = adaptor.isNil(t);
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( !nil ) {
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				nodes.push(t); // add this node
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// add DOWN node if t has children
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var n:int = adaptor.getChildCount(t);
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( !nil && n>0 ) {
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				addNavigationNode(TokenConstants.DOWN);
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// and now add all its children
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (var c:int=0; c<n; c++) {
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				var child:Object = adaptor.getChild(t,c);
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				fillBufferTo(child);
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// add UP node if t has children
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( !nil && n>0 ) {
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				addNavigationNode(TokenConstants.UP);
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** What is the stream index for node? 0..n-1
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  Return -1 if node not found.
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected function getNodeIndex(node:Object):int {
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( p==-1 ) {
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				fillBuffer();
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (var i:int = 0; i < nodes.length; i++) {
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				var t:Object = nodes[i];
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( t===node ) {
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					return i;
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return -1;
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** As we flatten the tree, we use UP, DOWN nodes to represent
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  the tree structure.  When debugging we need unique nodes
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  so instantiate new ones when uniqueNavigationNodes is true.
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected function addNavigationNode(ttype:int):void {
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var navNode:Object = null;
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( ttype==TokenConstants.DOWN ) {
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( hasUniqueNavigationNodes) {
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					navNode = adaptor.createFromType(TokenConstants.DOWN, "DOWN");
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				else {
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					navNode = down;
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else {
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( hasUniqueNavigationNodes ) {
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					navNode = adaptor.createFromType(TokenConstants.UP, "UP");
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				else {
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					navNode = up;
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			nodes.push(navNode);
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function getNode(i:int):Object {
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( p==-1 ) {
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				fillBuffer();
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return nodes[i];
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function LT(k:int):Object {
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( p==-1 ) {
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				fillBuffer();
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( k==0 ) {
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return null;
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( k<0 ) {
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return LB(-k);
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//System.out.print("LT(p="+p+","+k+")=");
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( (p+k-1) >= nodes.length ) {
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return eof;
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return nodes[p+k-1];
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get currentSymbol():Object { return LT(1); }
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Look backwards k nodes */
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		protected function LB(k:int):Object {
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( k==0 ) {
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return null;
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( (p-k)<0 ) {
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return null;
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return nodes[p-k];
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get treeSource():Object {
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return root;
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get sourceName():String {
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return tokenStream.sourceName;
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get tokenStream():TokenStream {
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return tokens;
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function set tokenStream(tokens:TokenStream):void {
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this.tokens = tokens;
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get treeAdaptor():TreeAdaptor {
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return adaptor;
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function set treeAdaptor(adaptor:TreeAdaptor):void {
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this.adaptor = adaptor;
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get hasUniqueNavigationNodes():Boolean {
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return uniqueNavigationNodes;
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function set hasUniqueNavigationNodes(uniqueNavigationNodes:Boolean):void {
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this.uniqueNavigationNodes = uniqueNavigationNodes;
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function consume():void {
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( p==-1 ) {
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				fillBuffer();
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			p++;
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function LA(i:int):int {
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return adaptor.getType(LT(i));
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function mark():int {
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( p==-1 ) {
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				fillBuffer();
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lastMarker = index;
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return lastMarker;
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function release(marker:int):void {
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// no resources to release
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get index():int {
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return p;
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function rewindTo(marker:int):void {
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			seek(marker);
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function rewind():void {
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			seek(lastMarker);
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function seek(index:int):void {
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( p==-1 ) {
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				fillBuffer();
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			p = index;
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Make stream jump to a new location, saving old location.
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  Switch back with pop().
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function push(index:int):void {
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( calls==null ) {
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				calls = new Array();
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			calls.push(p); // save current index
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			seek(index);
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Seek back to previous index saved during last push() call.
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  Return top of stack (return index).
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function pop():int {
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var ret:int = calls.pop();
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			seek(ret);
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return ret;
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function reset():void {
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			p = 0;
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lastMarker = 0;
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        if (calls != null) {
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	            calls = new Array();
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	        }
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	    }
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function get size():int {
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( p==-1 ) {
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				fillBuffer();
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return nodes.length;
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// TREE REWRITE INTERFACE
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function replaceChildren(parent:Object, startChildIndex:int, stopChildIndex:int, t:Object):void {
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( parent!=null ) {
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				adaptor.replaceChildren(parent, startChildIndex, stopChildIndex, t);
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Used for testing, just return the token type stream */
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function toString():String {
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( p==-1 ) {
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				fillBuffer();
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var buf:String = "";
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (var i:int = 0; i < nodes.length; i++) {
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				var t:Object = nodes[i];
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf += " ";
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf += (adaptor.getType(t));
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return buf.toString();
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    	/** Debugging */
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    	public function toTokenString(start:int, stop:int):String {
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		if ( p==-1 ) {
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    			fillBuffer();
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		}
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		var buf:String = "";
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		for (var i:int = start; i < nodes.length && i <= stop; i++) {
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    			var t:Object = nodes[i];
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    			buf += " ";
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    			buf += adaptor.getToken(t);
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		}
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    		return buf;
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    	}
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public function toStringWithRange(start:Object, stop:Object):String {
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( start==null || stop==null ) {
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return null;
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( p==-1 ) {
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				fillBuffer();
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			trace("stop: "+stop);
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( start is CommonTree )
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				trace("toString: "+CommonTree(start).token+", ");
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				trace(start);
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( stop is CommonTree )
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				trace(CommonTree(stop).token);
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				trace(stop);
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// if we have the token stream, use that to dump text in order
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( tokens!=null ) {
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				var beginTokenIndex:int = adaptor.getTokenStartIndex(start);
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				var endTokenIndex:int = adaptor.getTokenStopIndex(stop);
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// if it's a tree, use start/stop index from start node
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// else use token range from start/stop nodes
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( adaptor.getType(stop)==TokenConstants.UP ) {
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					endTokenIndex = adaptor.getTokenStopIndex(start);
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				else if ( adaptor.getType(stop)==TokenConstants.EOF ) {
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					endTokenIndex = size-2; // don't use EOF
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return tokens.toStringWithRange(beginTokenIndex, endTokenIndex);
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// walk nodes looking for start
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var t:Object = null;
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			var i:int = 0;
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (; i < nodes.length; i++) {
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				t = nodes[i];
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( t==start ) {
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					break;
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// now walk until we see stop, filling string buffer with text
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 var buf:String = "";
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			t = nodes[i];
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			while ( t!=stop ) {
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				var text:String = adaptor.getText(t);
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( text==null ) {
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					text = " "+ adaptor.getType(t);
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf += text;
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				i++;
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				t = nodes[i];
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// include stop node too
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			text = adaptor.getText(stop);
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( text==null ) {
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				text = " " + adaptor.getType(stop);
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			buf += text;
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return buf.toString();
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}