001 /* 002 @license.text@ 003 */ 004 package biz.hammurapi.antlr; 005 006 import java.awt.event.WindowAdapter; 007 import java.awt.event.WindowEvent; 008 import java.io.PrintStream; 009 010 import antlr.CommonAST; 011 import biz.hammurapi.legacy.review.SourceMarker; 012 import biz.hammurapi.util.PoliteVisitor; 013 import biz.hammurapi.util.Visitable; 014 import biz.hammurapi.util.Visitor; 015 016 017 /** 018 * Holds line and column numbers 019 * @author Pavel Vlasov 020 * @version $Revision: 1.8 $ 021 */ 022 public class AST extends CommonAST implements SourceMarker, Visitable { 023 /** 024 * Comment for <code>serialVersionUID</code> 025 */ 026 private static final long serialVersionUID = -3283377943637002016L; 027 private int line; 028 private int column; 029 private boolean childrenQueried=false; 030 private AST parent; 031 private String id; 032 private Token token; 033 private boolean loaded=false; 034 // private LanguageElement owner; 035 036 private Token firstToken; 037 private Token lastToken; 038 039 public void initialize(antlr.Token tok) { 040 super.initialize(tok); 041 line=tok.getLine(); 042 column=tok.getColumn(); 043 this.token=(Token) tok; 044 this.firstToken=this.token; 045 this.lastToken=this.token; 046 } 047 048 public void initialize(antlr.collections.AST node) { 049 super.initialize(node); 050 if (node instanceof AST) { 051 line=((AST) node).getLine(); 052 column=((AST) node).getColumn(); 053 } 054 } 055 056 public int getLine() { 057 queryChildren(); 058 return line; 059 } 060 061 public int getColumn() { 062 queryChildren(); 063 return column; 064 } 065 066 public Token getToken() { 067 return token; 068 } 069 070 /** 071 * Returns leftmost non-zero column among itself and all children 072 */ 073 public int getLeftColumn() { 074 int ret=getColumn(); 075 for (AST child=(AST) getFirstChild(); child!=null; child=(AST) child.getNextSibling()) { 076 int c=child.getLeftColumn(); 077 if (c!=0 && c<ret) ret=c; 078 } 079 return ret; 080 } 081 082 public AST getParent() { 083 return parent; 084 } 085 086 protected void setParent(AST parent) { 087 this.parent=parent; 088 } 089 090 /************************************************************************** 091 * Parent calculation 092 *************************************************************************/ 093 public void addChild(antlr.collections.AST node) { 094 super.addChild(node); 095 if (node instanceof AST) { 096 ((AST) node).parent=this; 097 } 098 } 099 100 public void setFirstChild(antlr.collections.AST c) { 101 super.setFirstChild(c); 102 if (c instanceof AST) { 103 ((AST) c).parent=this; 104 } 105 } 106 107 public void setNextSibling(antlr.collections.AST n) { 108 antlr.collections.AST currentNextSibling=getNextSibling(); 109 if (currentNextSibling instanceof AST) { 110 ((AST) currentNextSibling).setPrevSibling(null); 111 } 112 113 super.setNextSibling(n); 114 115 116 if (n instanceof AST) { 117 ((AST) n).setParent(parent); 118 ((AST) n).setPrevSibling(this); 119 } 120 } 121 122 private AST prevSibling; 123 124 public AST getPrevSibling() { 125 return prevSibling; 126 } 127 128 protected void setPrevSibling(AST prevSibling) { 129 this.prevSibling=prevSibling; 130 } 131 132 /** 133 * Removes AST from tree 134 */ 135 public void remove() { 136 if (parent!=null && parent.getFirstChild()==this) { 137 parent.setFirstChild(getNextSibling()); 138 } 139 140 parent=null; 141 142 if (prevSibling==null) { 143 if (getNextSibling() instanceof AST) { 144 ((AST) getNextSibling()).setPrevSibling(null); 145 } 146 } else { 147 prevSibling.setNextSibling(getNextSibling()); 148 } 149 150 setPrevSibling(null); 151 } 152 153 /** 154 * Reads column and line from children if its own are 0 155 */ 156 private void queryChildren() { 157 if (!childrenQueried) { 158 childrenQueried=true; 159 for (AST child = (AST) getFirstChild(); child != null ; child = (AST) child.getNextSibling()) { 160 if (line==0 && column==0 && child.getLine()!=0) { 161 line=child.getLine(); 162 column=child.getColumn(); 163 } 164 165 Token cft=child.getFirstToken(); 166 if (cft!=null && (firstToken==null || cft.compareTo(firstToken)<0)) { 167 firstToken=cft; 168 } 169 170 Token clt=child.getLastToken(); 171 if (clt!=null && (lastToken==null || clt.compareTo(lastToken)>0)) { 172 lastToken=clt; 173 } 174 } 175 } 176 } 177 178 private String sourceURL; 179 180 public String getSourceURL() { 181 return sourceURL; 182 } 183 184 public void setSourceURL(String sourceURL) { 185 this.sourceURL=sourceURL; 186 } 187 188 /** 189 * Indicates that the node has been processed by superclass and can be ignored 190 * @return Returns the loaded. 191 */ 192 boolean isLoaded() { 193 return loaded; 194 } 195 196 /** 197 * @param loaded The loaded to set. 198 */ 199 void setLoaded(boolean loaded) { 200 this.loaded = loaded; 201 } 202 203 public boolean equals(Object obj) { 204 if (obj==null) { 205 return false; 206 } 207 208 if (obj==this) { 209 return true; 210 } 211 212 if (getClass().equals(obj.getClass())) { 213 return false; 214 } 215 216 AST ast=(AST) obj; 217 218 if (super.equals(ast)) { 219 220 if (ast.getNumberOfChildren()!=getNumberOfChildren()) { 221 return false; 222 } 223 224 for (AST child=(AST) getFirstChild(), otherChild=(AST) ast.getFirstChild(); child!=null && otherChild!=null; child=(AST) child.getNextSibling(), otherChild=(AST) otherChild.getNextSibling()) { 225 if (!child.equals(ast.getFirstChild())) { 226 return false; 227 } 228 } 229 return true; 230 } 231 232 return false; 233 } 234 235 public int hashCode() { 236 int ret=getType(); 237 ret^=getClass().getName().hashCode(); 238 239 if (getText()!=null) { 240 ret^=getText().hashCode(); 241 } 242 for (AST child=(AST) getFirstChild(); child!=null; child=(AST) child.getNextSibling()) { 243 ret^=child.hashCode(); 244 } 245 return ret; 246 } 247 248 public int getSize() { 249 int ret=1; 250 for (AST child=(AST) getFirstChild(); child!=null; child=(AST) child.getNextSibling()) { 251 ret+=child.getSize(); 252 } 253 254 return ret; 255 } 256 257 public Token getFirstToken() { 258 queryChildren(); 259 return firstToken; 260 } 261 262 public Token getLastToken() { 263 queryChildren(); 264 return lastToken; 265 } 266 267 // protected LanguageElement getOwner() { 268 // return owner; 269 // } 270 271 // protected void setOwner(LanguageElement owner) { 272 // this.owner = owner; 273 // } 274 275 public String getId() { 276 return id; 277 } 278 279 private void enumerateChildren() { 280 int i=0; 281 for (AST node=(AST) getFirstChild(); node!=null; node=(AST) node.getNextSibling(), i++) { 282 node.id = id==null ? String.valueOf(i) : id+'.'+i; 283 node.enumerateChildren(); 284 } 285 } 286 287 public void enumerate() { 288 int i=0; 289 for (AST node=this; node!=null; node=(AST) node.getNextSibling(), i++) { 290 node.id=String.valueOf(i); 291 node.enumerateChildren(); 292 } 293 } 294 295 public boolean accept(Visitor visitor) { 296 if (visitor.visit(this)) { 297 if (getFirstChild()!=null) { 298 ((Visitable) getFirstChild()).accept(visitor); 299 } 300 301 if (visitor instanceof PoliteVisitor) { 302 ((PoliteVisitor) visitor).leave(this); 303 } 304 305 if (getNextSibling()!=null) { 306 return ((Visitable) getNextSibling()).accept(visitor); 307 } 308 309 return true; 310 } 311 312 return false; 313 } 314 315 public Integer getSourceId() { 316 return null; 317 } 318 319 public void print(String[] tokenNames, boolean withSiblings) { 320 print(tokenNames, System.out, 0, withSiblings); 321 } 322 323 public void print(String[] tokenNames, PrintStream out, int level, boolean withSiblings) { 324 if (withSiblings) { 325 visitAll(tokenNames, this, level, out); 326 } else { 327 visit(tokenNames, this, level, out); 328 } 329 } 330 331 protected void tabs(PrintStream out, int level) { 332 for (int i = 0; i < level; i++) { 333 out.print(" "); 334 } 335 } 336 337 protected void visit(String[] tokenNames, AST node, int level, PrintStream out) { 338 tabs(out, level); 339 out.print(tokenNames[node.getType()]+" "); 340 out.print(node.getText()==null ? "nil" : node.getText()); 341 out.println(" "+node.getLine()+(node.getColumn()==node.getLeftColumn() ? ":"+node.getColumn() : ":"+node.getColumn()+"("+node.getLeftColumn()+") ")); 342 visitAll(tokenNames, (AST) node.getFirstChild(), level+1, out); 343 } 344 345 protected void visitAll(String[] tokenNames, AST node, int level, PrintStream out) { 346 while (node!=null) { 347 visit(tokenNames, node, level, out); 348 node = (AST) node.getNextSibling(); 349 } 350 } 351 352 public void show(String[] tokenNames) { 353 final ASTFrame frame = new ASTFrame("AST: "+getText(), this, tokenNames); 354 frame.setVisible(true); 355 frame.addWindowListener(new WindowAdapter() { 356 public void windowClosing(WindowEvent e) { 357 frame.setVisible(false); // hide the Frame 358 frame.dispose(); 359 } 360 }); 361 } 362 363 public void showWithSiblings(String title, String[] tokenNames) { 364 AST root=new AST(); 365 root.setText(title); 366 root.setFirstChild(this); 367 final ASTFrame frame = new ASTFrame(title, root, tokenNames); 368 frame.setVisible(true); 369 frame.addWindowListener(new WindowAdapter() { 370 public void windowClosing(WindowEvent e) { 371 frame.setVisible(false); // hide the Frame 372 frame.dispose(); 373 } 374 }); 375 } 376 }