00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 package org.antlr.runtime.tree;
00029
00030 import org.antlr.runtime.Token;
00031 import org.antlr.runtime.TokenStream;
00032 import org.antlr.runtime.misc.IntArray;
00033 import java.util.*;
00034
00057 public class BufferedTreeNodeStream implements TreeNodeStream {
00058 public static final int DEFAULT_INITIAL_BUFFER_SIZE = 100;
00059 public static final int INITIAL_CALL_STACK_SIZE = 10;
00060
00061 protected class StreamIterator implements Iterator {
00062 int i = 0;
00063 public boolean hasNext() {
00064 return i<nodes.size();
00065 }
00066
00067 public Object next() {
00068 int current = i;
00069 i++;
00070 if ( current < nodes.size() ) {
00071 return nodes.get(current);
00072 }
00073 return eof;
00074 }
00075
00076 public void remove() {
00077 throw new RuntimeException("cannot remove nodes from stream");
00078 }
00079 }
00080
00081
00082
00083
00084 protected Object down;
00085 protected Object up;
00086 protected Object eof;
00087
00097 protected List nodes;
00098
00100 protected Object root;
00101
00103 protected TokenStream tokens;
00104
00106 TreeAdaptor adaptor;
00107
00109 protected boolean uniqueNavigationNodes = false;
00110
00114 protected int p = -1;
00115
00117 protected int lastMarker;
00118
00120 protected IntArray calls;
00121
00122 public BufferedTreeNodeStream(Object tree) {
00123 this(new CommonTreeAdaptor(), tree);
00124 }
00125
00126 public BufferedTreeNodeStream(TreeAdaptor adaptor, Object tree) {
00127 this(adaptor, tree, DEFAULT_INITIAL_BUFFER_SIZE);
00128 }
00129
00130 public BufferedTreeNodeStream(TreeAdaptor adaptor, Object tree, int initialBufferSize) {
00131 this.root = tree;
00132 this.adaptor = adaptor;
00133 nodes = new ArrayList(initialBufferSize);
00134 down = adaptor.create(Token.DOWN, "DOWN");
00135 up = adaptor.create(Token.UP, "UP");
00136 eof = adaptor.create(Token.EOF, "EOF");
00137 }
00138
00142 protected void fillBuffer() {
00143 fillBuffer(root);
00144
00145 p = 0;
00146 }
00147
00148 public void fillBuffer(Object t) {
00149 boolean nil = adaptor.isNil(t);
00150 if ( !nil ) {
00151 nodes.add(t);
00152 }
00153
00154 int n = adaptor.getChildCount(t);
00155 if ( !nil && n>0 ) {
00156 addNavigationNode(Token.DOWN);
00157 }
00158
00159 for (int c=0; c<n; c++) {
00160 Object child = adaptor.getChild(t,c);
00161 fillBuffer(child);
00162 }
00163
00164 if ( !nil && n>0 ) {
00165 addNavigationNode(Token.UP);
00166 }
00167 }
00168
00172 protected int getNodeIndex(Object node) {
00173 if ( p==-1 ) {
00174 fillBuffer();
00175 }
00176 for (int i = 0; i < nodes.size(); i++) {
00177 Object t = (Object) nodes.get(i);
00178 if ( t==node ) {
00179 return i;
00180 }
00181 }
00182 return -1;
00183 }
00184
00189 protected void addNavigationNode(final int ttype) {
00190 Object navNode = null;
00191 if ( ttype==Token.DOWN ) {
00192 if ( hasUniqueNavigationNodes() ) {
00193 navNode = adaptor.create(Token.DOWN, "DOWN");
00194 }
00195 else {
00196 navNode = down;
00197 }
00198 }
00199 else {
00200 if ( hasUniqueNavigationNodes() ) {
00201 navNode = adaptor.create(Token.UP, "UP");
00202 }
00203 else {
00204 navNode = up;
00205 }
00206 }
00207 nodes.add(navNode);
00208 }
00209
00210 public Object get(int i) {
00211 if ( p==-1 ) {
00212 fillBuffer();
00213 }
00214 return nodes.get(i);
00215 }
00216
00217 public Object LT(int k) {
00218 if ( p==-1 ) {
00219 fillBuffer();
00220 }
00221 if ( k==0 ) {
00222 return null;
00223 }
00224 if ( k<0 ) {
00225 return LB(-k);
00226 }
00227
00228 if ( (p+k-1) >= nodes.size() ) {
00229 return eof;
00230 }
00231 return nodes.get(p+k-1);
00232 }
00233
00234 public Object getCurrentSymbol() { return LT(1); }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00256 protected Object LB(int k) {
00257 if ( k==0 ) {
00258 return null;
00259 }
00260 if ( (p-k)<0 ) {
00261 return null;
00262 }
00263 return nodes.get(p-k);
00264 }
00265
00266 public Object getTreeSource() {
00267 return root;
00268 }
00269
00270 public String getSourceName() {
00271 return getTokenStream().getSourceName();
00272 }
00273
00274 public TokenStream getTokenStream() {
00275 return tokens;
00276 }
00277
00278 public void setTokenStream(TokenStream tokens) {
00279 this.tokens = tokens;
00280 }
00281
00282 public TreeAdaptor getTreeAdaptor() {
00283 return adaptor;
00284 }
00285
00286 public void setTreeAdaptor(TreeAdaptor adaptor) {
00287 this.adaptor = adaptor;
00288 }
00289
00290 public boolean hasUniqueNavigationNodes() {
00291 return uniqueNavigationNodes;
00292 }
00293
00294 public void setUniqueNavigationNodes(boolean uniqueNavigationNodes) {
00295 this.uniqueNavigationNodes = uniqueNavigationNodes;
00296 }
00297
00298 public void consume() {
00299 if ( p==-1 ) {
00300 fillBuffer();
00301 }
00302 p++;
00303 }
00304
00305 public int LA(int i) {
00306 return adaptor.getType(LT(i));
00307 }
00308
00309 public int mark() {
00310 if ( p==-1 ) {
00311 fillBuffer();
00312 }
00313 lastMarker = index();
00314 return lastMarker;
00315 }
00316
00317 public void release(int marker) {
00318
00319 }
00320
00321 public int index() {
00322 return p;
00323 }
00324
00325 public void rewind(int marker) {
00326 seek(marker);
00327 }
00328
00329 public void rewind() {
00330 seek(lastMarker);
00331 }
00332
00333 public void seek(int index) {
00334 if ( p==-1 ) {
00335 fillBuffer();
00336 }
00337 p = index;
00338 }
00339
00343 public void push(int index) {
00344 if ( calls==null ) {
00345 calls = new IntArray();
00346 }
00347 calls.push(p);
00348 seek(index);
00349 }
00350
00354 public int pop() {
00355 int ret = calls.pop();
00356 seek(ret);
00357 return ret;
00358 }
00359
00360 public void reset() {
00361 p = 0;
00362 lastMarker = 0;
00363 if (calls != null) {
00364 calls.clear();
00365 }
00366 }
00367
00368 public int size() {
00369 if ( p==-1 ) {
00370 fillBuffer();
00371 }
00372 return nodes.size();
00373 }
00374
00375 public Iterator iterator() {
00376 if ( p==-1 ) {
00377 fillBuffer();
00378 }
00379 return new StreamIterator();
00380 }
00381
00382
00383
00384 public void replaceChildren(Object parent, int startChildIndex, int stopChildIndex, Object t) {
00385 if ( parent!=null ) {
00386 adaptor.replaceChildren(parent, startChildIndex, stopChildIndex, t);
00387 }
00388 }
00389
00391 public String toTokenTypeString() {
00392 if ( p==-1 ) {
00393 fillBuffer();
00394 }
00395 StringBuffer buf = new StringBuffer();
00396 for (int i = 0; i < nodes.size(); i++) {
00397 Object t = (Object) nodes.get(i);
00398 buf.append(" ");
00399 buf.append(adaptor.getType(t));
00400 }
00401 return buf.toString();
00402 }
00403
00405 public String toTokenString(int start, int stop) {
00406 if ( p==-1 ) {
00407 fillBuffer();
00408 }
00409 StringBuffer buf = new StringBuffer();
00410 for (int i = start; i < nodes.size() && i <= stop; i++) {
00411 Object t = (Object) nodes.get(i);
00412 buf.append(" ");
00413 buf.append(adaptor.getToken(t));
00414 }
00415 return buf.toString();
00416 }
00417
00418 public String toString(Object start, Object stop) {
00419 System.out.println("toString");
00420 if ( start==null || stop==null ) {
00421 return null;
00422 }
00423 if ( p==-1 ) {
00424 fillBuffer();
00425 }
00426
00427 if ( start instanceof CommonTree )
00428 System.out.print("toString: "+((CommonTree)start).getToken()+", ");
00429 else
00430 System.out.println(start);
00431 if ( stop instanceof CommonTree )
00432 System.out.println(((CommonTree)stop).getToken());
00433 else
00434 System.out.println(stop);
00435
00436 if ( tokens!=null ) {
00437 int beginTokenIndex = adaptor.getTokenStartIndex(start);
00438 int endTokenIndex = adaptor.getTokenStopIndex(stop);
00439
00440
00441 if ( adaptor.getType(stop)==Token.UP ) {
00442 endTokenIndex = adaptor.getTokenStopIndex(start);
00443 }
00444 else if ( adaptor.getType(stop)==Token.EOF ) {
00445 endTokenIndex = size()-2;
00446 }
00447 return tokens.toString(beginTokenIndex, endTokenIndex);
00448 }
00449
00450 Object t = null;
00451 int i = 0;
00452 for (; i < nodes.size(); i++) {
00453 t = nodes.get(i);
00454 if ( t==start ) {
00455 break;
00456 }
00457 }
00458
00459 StringBuffer buf = new StringBuffer();
00460 t = nodes.get(i);
00461 while ( t!=stop ) {
00462 String text = adaptor.getText(t);
00463 if ( text==null ) {
00464 text = " "+String.valueOf(adaptor.getType(t));
00465 }
00466 buf.append(text);
00467 i++;
00468 t = nodes.get(i);
00469 }
00470
00471 String text = adaptor.getText(stop);
00472 if ( text==null ) {
00473 text = " "+String.valueOf(adaptor.getType(stop));
00474 }
00475 buf.append(text);
00476 return buf.toString();
00477 }
00478 }