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 java.util.ArrayList;
00031 import java.util.List;
00032
00039 public abstract class BaseTree implements Tree {
00040 protected List children;
00041
00042 public BaseTree() {
00043 }
00044
00049 public BaseTree(Tree node) {
00050 }
00051
00052 public Tree getChild(int i) {
00053 if ( children==null || i>=children.size() ) {
00054 return null;
00055 }
00056 return (BaseTree)children.get(i);
00057 }
00058
00062 public List getChildren() {
00063 return children;
00064 }
00065
00066 public Tree getFirstChildWithType(int type) {
00067 for (int i = 0; children!=null && i < children.size(); i++) {
00068 Tree t = (Tree) children.get(i);
00069 if ( t.getType()==type ) {
00070 return t;
00071 }
00072 }
00073 return null;
00074 }
00075
00076 public int getChildCount() {
00077 if ( children==null ) {
00078 return 0;
00079 }
00080 return children.size();
00081 }
00082
00089 public void addChild(Tree t) {
00090
00091
00092 if ( t==null ) {
00093 return;
00094 }
00095 BaseTree childTree = (BaseTree)t;
00096 if ( childTree.isNil() ) {
00097 if ( this.children!=null && this.children == childTree.children ) {
00098 throw new RuntimeException("attempt to add child list to itself");
00099 }
00100
00101 if ( childTree.children!=null ) {
00102 if ( this.children!=null ) {
00103 int n = childTree.children.size();
00104 for (int i = 0; i < n; i++) {
00105 Tree c = (Tree)childTree.children.get(i);
00106 this.children.add(c);
00107
00108 c.setParent(this);
00109 c.setChildIndex(children.size()-1);
00110 }
00111 }
00112 else {
00113
00114
00115 this.children = childTree.children;
00116 this.freshenParentAndChildIndexes();
00117 }
00118 }
00119 }
00120 else {
00121 if ( children==null ) {
00122 children = createChildrenList();
00123 }
00124 children.add(t);
00125 childTree.setParent(this);
00126 childTree.setChildIndex(children.size()-1);
00127 }
00128
00129 }
00130
00132 public void addChildren(List kids) {
00133 for (int i = 0; i < kids.size(); i++) {
00134 Tree t = (Tree) kids.get(i);
00135 addChild(t);
00136 }
00137 }
00138
00139 public void setChild(int i, Tree t) {
00140 if ( t==null ) {
00141 return;
00142 }
00143 if ( t.isNil() ) {
00144 throw new IllegalArgumentException("Can't set single child to a list");
00145 }
00146 if ( children==null ) {
00147 children = createChildrenList();
00148 }
00149 children.set(i, t);
00150 t.setParent(this);
00151 t.setChildIndex(i);
00152 }
00153
00154 public Object deleteChild(int i) {
00155 if ( children==null ) {
00156 return null;
00157 }
00158 BaseTree killed = (BaseTree)children.remove(i);
00159
00160 this.freshenParentAndChildIndexes(i);
00161 return killed;
00162 }
00163
00169 public void replaceChildren(int startChildIndex, int stopChildIndex, Object t) {
00170
00171
00172
00173
00174
00175 if ( children==null ) {
00176 throw new IllegalArgumentException("indexes invalid; no children in list");
00177 }
00178 int replacingHowMany = stopChildIndex - startChildIndex + 1;
00179 int replacingWithHowMany;
00180 BaseTree newTree = (BaseTree)t;
00181 List newChildren = null;
00182
00183 if ( newTree.isNil() ) {
00184 newChildren = newTree.children;
00185 }
00186 else {
00187 newChildren = new ArrayList(1);
00188 newChildren.add(newTree);
00189 }
00190 replacingWithHowMany = newChildren.size();
00191 int numNewChildren = newChildren.size();
00192 int delta = replacingHowMany - replacingWithHowMany;
00193
00194 if ( delta == 0 ) {
00195 int j = 0;
00196 for (int i=startChildIndex; i<=stopChildIndex; i++) {
00197 BaseTree child = (BaseTree)newChildren.get(j);
00198 children.set(i, child);
00199 child.setParent(this);
00200 child.setChildIndex(i);
00201 j++;
00202 }
00203 }
00204 else if ( delta > 0 ) {
00205
00206 for (int j=0; j<numNewChildren; j++) {
00207 children.set(startChildIndex+j, newChildren.get(j));
00208 }
00209 int indexToDelete = startChildIndex+numNewChildren;
00210 for (int c=indexToDelete; c<=stopChildIndex; c++) {
00211
00212 BaseTree killed = (BaseTree)children.remove(indexToDelete);
00213 }
00214 freshenParentAndChildIndexes(startChildIndex);
00215 }
00216 else {
00217
00218 for (int j=0; j<replacingHowMany; j++) {
00219 children.set(startChildIndex+j, newChildren.get(j));
00220 }
00221 int numToInsert = replacingWithHowMany-replacingHowMany;
00222 for (int j=replacingHowMany; j<replacingWithHowMany; j++) {
00223 children.add(startChildIndex+j, newChildren.get(j));
00224 }
00225 freshenParentAndChildIndexes(startChildIndex);
00226 }
00227
00228 }
00229
00231 protected List createChildrenList() {
00232 return new ArrayList();
00233 }
00234
00235 public boolean isNil() {
00236 return false;
00237 }
00238
00240 public void freshenParentAndChildIndexes() {
00241 freshenParentAndChildIndexes(0);
00242 }
00243
00244 public void freshenParentAndChildIndexes(int offset) {
00245 int n = getChildCount();
00246 for (int c = offset; c < n; c++) {
00247 Tree child = (Tree)getChild(c);
00248 child.setChildIndex(c);
00249 child.setParent(this);
00250 }
00251 }
00252
00253 public void sanityCheckParentAndChildIndexes() {
00254 sanityCheckParentAndChildIndexes(null, -1);
00255 }
00256
00257 public void sanityCheckParentAndChildIndexes(Tree parent, int i) {
00258 if ( parent!=this.getParent() ) {
00259 throw new IllegalStateException("parents don't match; expected "+parent+" found "+this.getParent());
00260 }
00261 if ( i!=this.getChildIndex() ) {
00262 throw new IllegalStateException("child indexes don't match; expected "+i+" found "+this.getChildIndex());
00263 }
00264 int n = this.getChildCount();
00265 for (int c = 0; c < n; c++) {
00266 CommonTree child = (CommonTree)this.getChild(c);
00267 child.sanityCheckParentAndChildIndexes(this, c);
00268 }
00269 }
00270
00272 public int getChildIndex() {
00273 return 0;
00274 }
00275 public void setChildIndex(int index) {
00276 }
00277
00279 public Tree getParent() {
00280 return null;
00281 }
00282 public void setParent(Tree t) {
00283 }
00284
00286 public String toStringTree() {
00287 if ( children==null || children.size()==0 ) {
00288 return this.toString();
00289 }
00290 StringBuffer buf = new StringBuffer();
00291 if ( !isNil() ) {
00292 buf.append("(");
00293 buf.append(this.toString());
00294 buf.append(' ');
00295 }
00296 for (int i = 0; children!=null && i < children.size(); i++) {
00297 BaseTree t = (BaseTree) children.get(i);
00298 if ( i>0 ) {
00299 buf.append(' ');
00300 }
00301 buf.append(t.toStringTree());
00302 }
00303 if ( !isNil() ) {
00304 buf.append(")");
00305 }
00306 return buf.toString();
00307 }
00308
00309 public int getLine() {
00310 return 0;
00311 }
00312
00313 public int getCharPositionInLine() {
00314 return 0;
00315 }
00316
00318 public abstract String toString();
00319 }