13447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein/*
23447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein [The "BSD license"]
33447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein Copyright (c) 2005-2009 Terence Parr
43447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein All rights reserved.
53447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
63447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein Redistribution and use in source and binary forms, with or without
73447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein modification, are permitted provided that the following conditions
83447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein are met:
93447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein 1. Redistributions of source code must retain the above copyright
103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein     notice, this list of conditions and the following disclaimer.
113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein 2. Redistributions in binary form must reproduce the above copyright
123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein     notice, this list of conditions and the following disclaimer in the
133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein     documentation and/or other materials provided with the distribution.
143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein 3. The name of the author may not be used to endorse or promote products
153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein     derived from this software without specific prior written permission.
163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein */
283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinpackage org.antlr.runtime.tree;
293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinimport org.antlr.runtime.Token;
313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinimport org.antlr.runtime.TokenStream;
323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinimport org.antlr.runtime.misc.IntArray;
333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinimport java.util.*;
343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein/** A buffered stream of tree nodes.  Nodes can be from a tree of ANY kind.
363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *
373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  This node stream sucks all nodes out of the tree specified in
383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  the constructor during construction and makes pointers into
393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  the tree using an array of Object pointers. The stream necessarily
403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  includes pointers to DOWN and UP and EOF nodes.
413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *
423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  This stream knows how to mark/release for backtracking.
433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *
443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  This stream is most suitable for tree interpreters that need to
453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  jump around a lot or for tree parsers requiring speed (at cost of memory).
463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  There is some duplicated functionality here with UnBufferedTreeNodeStream
473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  but just in bookkeeping, not tree walking etc...
483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *
493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  TARGET DEVELOPERS:
503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *
513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  This is the old CommonTreeNodeStream that buffered up entire node stream.
523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  No need to implement really as new CommonTreeNodeStream is much better
533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  and covers what we need.
543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *
553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  @see CommonTreeNodeStream
563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein */
573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinpublic class BufferedTreeNodeStream implements TreeNodeStream {
583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public static final int DEFAULT_INITIAL_BUFFER_SIZE = 100;
593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public static final int INITIAL_CALL_STACK_SIZE = 10;
603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein    protected class StreamIterator implements Iterator {
623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int i = 0;
633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public boolean hasNext() {
643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			return i<nodes.size();
653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public Object next() {
683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			int current = i;
693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			i++;
703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if ( current < nodes.size() ) {
713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				return nodes.get(current);
723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			return eof;
743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public void remove() {
773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			throw new RuntimeException("cannot remove nodes from stream");
783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
793447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
803447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
813447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	// all these navigation nodes are shared and hence they
823447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	// cannot contain any line/column info
833447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
843447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected Object down;
853447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected Object up;
863447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected Object eof;
873447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
883447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** The complete mapping from stream index to tree node.
893447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  This buffer includes pointers to DOWN, UP, and EOF nodes.
903447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  It is built upon ctor invocation.  The elements are type
913447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  Object as we don't what the trees look like.
923447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *
933447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  Load upon first need of the buffer so we can set token types
943447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  of interest for reverseIndexing.  Slows us down a wee bit to
953447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  do all of the if p==-1 testing everywhere though.
963447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 */
973447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected List nodes;
983447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
993447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Pull nodes from which tree? */
1003447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected Object root;
1013447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1023447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** IF this tree (root) was created from a token stream, track it. */
1033447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected TokenStream tokens;
1043447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1053447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** What tree adaptor was used to build these trees */
1063447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	TreeAdaptor adaptor;
1073447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1083447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Reuse same DOWN, UP navigation nodes unless this is true */
1093447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected boolean uniqueNavigationNodes = false;
1103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** The index into the nodes list of the current node (next node
1123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  to consume).  If -1, nodes array not filled yet.
1133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 */
1143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected int p = -1;
1153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Track the last mark() call result value for use in rewind(). */
1173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected int lastMarker;
1183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Stack of indexes used for push/pop calls */
1203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected IntArray calls;
1213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public BufferedTreeNodeStream(Object tree) {
1233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		this(new CommonTreeAdaptor(), tree);
1243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
1253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public BufferedTreeNodeStream(TreeAdaptor adaptor, Object tree) {
1273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		this(adaptor, tree, DEFAULT_INITIAL_BUFFER_SIZE);
1283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
1293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public BufferedTreeNodeStream(TreeAdaptor adaptor, Object tree, int initialBufferSize) {
1313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		this.root = tree;
1323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		this.adaptor = adaptor;
1333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		nodes = new ArrayList(initialBufferSize);
1343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		down = adaptor.create(Token.DOWN, "DOWN");
1353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		up = adaptor.create(Token.UP, "UP");
1363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		eof = adaptor.create(Token.EOF, "EOF");
1373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
1383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Walk tree with depth-first-search and fill nodes buffer.
1403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  Don't do DOWN, UP nodes if its a list (t is isNil).
1413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 */
1423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected void fillBuffer() {
1433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		fillBuffer(root);
1443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		//System.out.println("revIndex="+tokenTypeToStreamIndexesMap);
1453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		p = 0; // buffer of nodes intialized now
1463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
1473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void fillBuffer(Object t) {
1493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		boolean nil = adaptor.isNil(t);
1503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( !nil ) {
1513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			nodes.add(t); // add this node
1523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
1533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		// add DOWN node if t has children
1543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int n = adaptor.getChildCount(t);
1553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( !nil && n>0 ) {
1563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			addNavigationNode(Token.DOWN);
1573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
1583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		// and now add all its children
1593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		for (int c=0; c<n; c++) {
1603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			Object child = adaptor.getChild(t,c);
1613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			fillBuffer(child);
1623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
1633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		// add UP node if t has children
1643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( !nil && n>0 ) {
1653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			addNavigationNode(Token.UP);
1663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
1673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
1683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** What is the stream index for node? 0..n-1
1703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  Return -1 if node not found.
1713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 */
1723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected int getNodeIndex(Object node) {
1733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( p==-1 ) {
1743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			fillBuffer();
1753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
1763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		for (int i = 0; i < nodes.size(); i++) {
1773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			Object t = (Object) nodes.get(i);
1783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if ( t==node ) {
1793447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				return i;
1803447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
1813447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
1823447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return -1;
1833447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
1843447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1853447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** As we flatten the tree, we use UP, DOWN nodes to represent
1863447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  the tree structure.  When debugging we need unique nodes
1873447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  so instantiate new ones when uniqueNavigationNodes is true.
1883447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 */
1893447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected void addNavigationNode(final int ttype) {
1903447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		Object navNode = null;
1913447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( ttype==Token.DOWN ) {
1923447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if ( hasUniqueNavigationNodes() ) {
1933447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				navNode = adaptor.create(Token.DOWN, "DOWN");
1943447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
1953447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			else {
1963447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				navNode = down;
1973447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
1983447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
1993447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		else {
2003447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if ( hasUniqueNavigationNodes() ) {
2013447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				navNode = adaptor.create(Token.UP, "UP");
2023447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
2033447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			else {
2043447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				navNode = up;
2053447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
2063447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
2073447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		nodes.add(navNode);
2083447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2093447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public Object get(int i) {
2113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( p==-1 ) {
2123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			fillBuffer();
2133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
2143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return nodes.get(i);
2153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public Object LT(int k) {
2183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( p==-1 ) {
2193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			fillBuffer();
2203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
2213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( k==0 ) {
2223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			return null;
2233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
2243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( k<0 ) {
2253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			return LB(-k);
2263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
2273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		//System.out.print("LT(p="+p+","+k+")=");
2283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( (p+k-1) >= nodes.size() ) {
2293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			return eof;
2303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
2313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return nodes.get(p+k-1);
2323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public Object getCurrentSymbol() { return LT(1); }
2353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein/*
2373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public Object getLastTreeNode() {
2383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int i = index();
2393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( i>=size() ) {
2403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			i--; // if at EOF, have to start one back
2413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
2423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		System.out.println("start last node: "+i+" size=="+nodes.size());
2433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		while ( i>=0 &&
2443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			(adaptor.getType(get(i))==Token.EOF ||
2453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			 adaptor.getType(get(i))==Token.UP ||
2463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			 adaptor.getType(get(i))==Token.DOWN) )
2473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		{
2483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			i--;
2493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
2503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		System.out.println("stop at node: "+i+" "+nodes.get(i));
2513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return nodes.get(i);
2523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein*/
2543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Look backwards k nodes */
2563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected Object LB(int k) {
2573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( k==0 ) {
2583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			return null;
2593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
2603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( (p-k)<0 ) {
2613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			return null;
2623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
2633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return nodes.get(p-k);
2643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public Object getTreeSource() {
2673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return root;
2683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public String getSourceName() {
2713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return getTokenStream().getSourceName();
2723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public TokenStream getTokenStream() {
2753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return tokens;
2763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void setTokenStream(TokenStream tokens) {
2793447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		this.tokens = tokens;
2803447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2813447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2823447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public TreeAdaptor getTreeAdaptor() {
2833447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return adaptor;
2843447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2853447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2863447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void setTreeAdaptor(TreeAdaptor adaptor) {
2873447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		this.adaptor = adaptor;
2883447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2893447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2903447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public boolean hasUniqueNavigationNodes() {
2913447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return uniqueNavigationNodes;
2923447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2933447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2943447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void setUniqueNavigationNodes(boolean uniqueNavigationNodes) {
2953447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		this.uniqueNavigationNodes = uniqueNavigationNodes;
2963447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2973447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2983447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void consume() {
2993447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( p==-1 ) {
3003447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			fillBuffer();
3013447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
3023447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		p++;
3033447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3043447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3053447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public int LA(int i) {
3063447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return adaptor.getType(LT(i));
3073447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3083447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3093447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public int mark() {
3103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( p==-1 ) {
3113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			fillBuffer();
3123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
3133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		lastMarker = index();
3143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return lastMarker;
3153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void release(int marker) {
3183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		// no resources to release
3193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public int index() {
3223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return p;
3233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void rewind(int marker) {
3263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		seek(marker);
3273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void rewind() {
3303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		seek(lastMarker);
3313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void seek(int index) {
3343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( p==-1 ) {
3353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			fillBuffer();
3363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
3373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		p = index;
3383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Make stream jump to a new location, saving old location.
3413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  Switch back with pop().
3423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 */
3433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void push(int index) {
3443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( calls==null ) {
3453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			calls = new IntArray();
3463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
3473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		calls.push(p); // save current index
3483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		seek(index);
3493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Seek back to previous index saved during last push() call.
3523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  Return top of stack (return index).
3533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 */
3543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public int pop() {
3553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int ret = calls.pop();
3563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		seek(ret);
3573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return ret;
3583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void reset() {
3613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		p = 0;
3623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		lastMarker = 0;
3633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein        if (calls != null) {
3643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein            calls.clear();
3653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein        }
3663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein    }
3673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public int size() {
3693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( p==-1 ) {
3703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			fillBuffer();
3713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
3723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return nodes.size();
3733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public Iterator iterator() {
3763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( p==-1 ) {
3773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			fillBuffer();
3783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
3793447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return new StreamIterator();
3803447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3813447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3823447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	// TREE REWRITE INTERFACE
3833447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3843447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void replaceChildren(Object parent, int startChildIndex, int stopChildIndex, Object t) {
3853447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( parent!=null ) {
3863447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			adaptor.replaceChildren(parent, startChildIndex, stopChildIndex, t);
3873447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
3883447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3893447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3903447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Used for testing, just return the token type stream */
3913447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public String toTokenTypeString() {
3923447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( p==-1 ) {
3933447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			fillBuffer();
3943447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
3953447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		StringBuffer buf = new StringBuffer();
3963447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		for (int i = 0; i < nodes.size(); i++) {
3973447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			Object t = (Object) nodes.get(i);
3983447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			buf.append(" ");
3993447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			buf.append(adaptor.getType(t));
4003447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
4013447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return buf.toString();
4023447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
4033447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
4043447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Debugging */
4053447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public String toTokenString(int start, int stop) {
4063447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( p==-1 ) {
4073447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			fillBuffer();
4083447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
4093447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		StringBuffer buf = new StringBuffer();
4103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		for (int i = start; i < nodes.size() && i <= stop; i++) {
4113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			Object t = (Object) nodes.get(i);
4123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			buf.append(" ");
4133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			buf.append(adaptor.getToken(t));
4143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
4153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return buf.toString();
4163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
4173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
4183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public String toString(Object start, Object stop) {
4193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		System.out.println("toString");
4203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( start==null || stop==null ) {
4213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			return null;
4223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
4233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( p==-1 ) {
4243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			fillBuffer();
4253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
4263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		//System.out.println("stop: "+stop);
4273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( start instanceof CommonTree )
4283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			System.out.print("toString: "+((CommonTree)start).getToken()+", ");
4293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		else
4303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			System.out.println(start);
4313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( stop instanceof CommonTree )
4323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			System.out.println(((CommonTree)stop).getToken());
4333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		else
4343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			System.out.println(stop);
4353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		// if we have the token stream, use that to dump text in order
4363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( tokens!=null ) {
4373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			int beginTokenIndex = adaptor.getTokenStartIndex(start);
4383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			int endTokenIndex = adaptor.getTokenStopIndex(stop);
4393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			// if it's a tree, use start/stop index from start node
4403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			// else use token range from start/stop nodes
4413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if ( adaptor.getType(stop)==Token.UP ) {
4423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				endTokenIndex = adaptor.getTokenStopIndex(start);
4433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
4443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			else if ( adaptor.getType(stop)==Token.EOF ) {
4453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				endTokenIndex = size()-2; // don't use EOF
4463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
4473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			return tokens.toString(beginTokenIndex, endTokenIndex);
4483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
4493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		// walk nodes looking for start
4503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		Object t = null;
4513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int i = 0;
4523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		for (; i < nodes.size(); i++) {
4533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			t = nodes.get(i);
4543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if ( t==start ) {
4553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				break;
4563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
4573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
4583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		// now walk until we see stop, filling string buffer with text
4593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		 StringBuffer buf = new StringBuffer();
4603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		t = nodes.get(i);
4613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		while ( t!=stop ) {
4623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			String text = adaptor.getText(t);
4633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if ( text==null ) {
4643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				text = " "+String.valueOf(adaptor.getType(t));
4653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
4663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			buf.append(text);
4673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			i++;
4683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			t = nodes.get(i);
4693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
4703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		// include stop node too
4713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		String text = adaptor.getText(stop);
4723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( text==null ) {
4733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			text = " "+String.valueOf(adaptor.getType(stop));
4743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
4753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(text);
4763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return buf.toString();
4773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
4783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein}
479