001: package org.antlr.runtime.tree;
002:
003: import org.antlr.runtime.CommonToken;
004: import org.antlr.runtime.Token;
005:
006: /** A TreeAdaptor that works with any Tree implementation. It provides
007: * really just factory methods; all the work is done by BaseTreeAdaptor.
008: * If you would like to have different tokens created than ClassicToken
009: * objects, you need to override this and then set the parser tree adaptor to
010: * use your subclass.
011: *
012: * To get your parser to build nodes of a different type, override
013: * create(Token).
014: */
015: public class CommonTreeAdaptor extends BaseTreeAdaptor {
016: /** Duplicate a node. This is part of the factory;
017: * override if you want another kind of node to be built.
018: *
019: * I could use reflection to prevent having to override this
020: * but reflection is slow.
021: */
022: public Object dupNode(Object t) {
023: if (t == null) {
024: return null;
025: }
026: return ((Tree) t).dupNode();
027: }
028:
029: public Object create(Token payload) {
030: return new CommonTree(payload);
031: }
032:
033: /** Tell me how to create a token for use with imaginary token nodes.
034: * For example, there is probably no input symbol associated with imaginary
035: * token DECL, but you need to create it as a payload or whatever for
036: * the DECL node as in ^(DECL type ID).
037: *
038: * If you care what the token payload objects' type is, you should
039: * override this method and any other createToken variant.
040: */
041: public Token createToken(int tokenType, String text) {
042: return new CommonToken(tokenType, text);
043: }
044:
045: /** Tell me how to create a token for use with imaginary token nodes.
046: * For example, there is probably no input symbol associated with imaginary
047: * token DECL, but you need to create it as a payload or whatever for
048: * the DECL node as in ^(DECL type ID).
049: *
050: * This is a variant of createToken where the new token is derived from
051: * an actual real input token. Typically this is for converting '{'
052: * tokens to BLOCK etc... You'll see
053: *
054: * r : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;
055: *
056: * If you care what the token payload objects' type is, you should
057: * override this method and any other createToken variant.
058: */
059: public Token createToken(Token fromToken) {
060: return new CommonToken(fromToken);
061: }
062:
063: /** Track start/stop token for subtree root created for a rule.
064: * Only works with Tree nodes. For rules that match nothing,
065: * seems like this will yield start=i and stop=i-1 in a nil node.
066: * Might be useful info so I'll not force to be i..i.
067: */
068: public void setTokenBoundaries(Object t, Token startToken,
069: Token stopToken) {
070: if (t == null) {
071: return;
072: }
073: int start = 0;
074: int stop = 0;
075: if (startToken != null) {
076: start = startToken.getTokenIndex();
077: }
078: if (stopToken != null) {
079: stop = stopToken.getTokenIndex();
080: }
081: ((Tree) t).setTokenStartIndex(start);
082: ((Tree) t).setTokenStopIndex(stop);
083: }
084:
085: public int getTokenStartIndex(Object t) {
086: if (t == null) {
087: return -1;
088: }
089: return ((Tree) t).getTokenStartIndex();
090: }
091:
092: public int getTokenStopIndex(Object t) {
093: if (t == null) {
094: return -1;
095: }
096: return ((Tree) t).getTokenStopIndex();
097: }
098:
099: public String getText(Object t) {
100: if (t == null) {
101: return null;
102: }
103: return ((Tree) t).getText();
104: }
105:
106: public int getType(Object t) {
107: if (t == null) {
108: return Token.INVALID_TOKEN_TYPE;
109: }
110: return ((Tree) t).getType();
111: }
112:
113: /** What is the Token associated with this node? If
114: * you are not using CommonTree, then you must
115: * override this in your own adaptor.
116: */
117: public Token getToken(Object t) {
118: if (t instanceof CommonTree) {
119: return ((CommonTree) t).getToken();
120: }
121: return null; // no idea what to do
122: }
123:
124: public Object getChild(Object t, int i) {
125: if (t == null) {
126: return null;
127: }
128: return ((Tree) t).getChild(i);
129: }
130:
131: public int getChildCount(Object t) {
132: if (t == null) {
133: return 0;
134: }
135: return ((Tree) t).getChildCount();
136: }
137:
138: }
|