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