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}