• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  [The "BSD license"]
3  Copyright (c) 2005-2009 Terence Parr
4  All rights reserved.
5 
6  Redistribution and use in source and binary forms, with or without
7  modification, are permitted provided that the following conditions
8  are met:
9  1. Redistributions of source code must retain the above copyright
10      notice, this list of conditions and the following disclaimer.
11  2. Redistributions in binary form must reproduce the above copyright
12      notice, this list of conditions and the following disclaimer in the
13      documentation and/or other materials provided with the distribution.
14  3. The name of the author may not be used to endorse or promote products
15      derived from this software without specific prior written permission.
16 
17  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 package org.antlr.runtime.tree;
29 
30 import org.antlr.runtime.CommonToken;
31 import org.antlr.runtime.Token;
32 
33 /** A TreeAdaptor that works with any Tree implementation.  It provides
34  *  really just factory methods; all the work is done by BaseTreeAdaptor.
35  *  If you would like to have different tokens created than ClassicToken
36  *  objects, you need to override this and then set the parser tree adaptor to
37  *  use your subclass.
38  *
39  *  To get your parser to build nodes of a different type, override
40  *  create(Token), errorNode(), and to be safe, YourTreeClass.dupNode().
41  *  dupNode is called to duplicate nodes during rewrite operations.
42  */
43 public class CommonTreeAdaptor extends BaseTreeAdaptor {
44 	/** Duplicate a node.  This is part of the factory;
45 	 *	override if you want another kind of node to be built.
46 	 *
47 	 *  I could use reflection to prevent having to override this
48 	 *  but reflection is slow.
49 	 */
dupNode(Object t)50 	public Object dupNode(Object t) {
51 		if ( t==null ) return null;
52 		return ((Tree)t).dupNode();
53 	}
54 
create(Token payload)55 	public Object create(Token payload) {
56 		return new CommonTree(payload);
57 	}
58 
59 	/** Tell me how to create a token for use with imaginary token nodes.
60 	 *  For example, there is probably no input symbol associated with imaginary
61 	 *  token DECL, but you need to create it as a payload or whatever for
62 	 *  the DECL node as in ^(DECL type ID).
63 	 *
64 	 *  If you care what the token payload objects' type is, you should
65 	 *  override this method and any other createToken variant.
66 	 */
createToken(int tokenType, String text)67 	public Token createToken(int tokenType, String text) {
68 		return new CommonToken(tokenType, text);
69 	}
70 
71 	/** Tell me how to create a token for use with imaginary token nodes.
72 	 *  For example, there is probably no input symbol associated with imaginary
73 	 *  token DECL, but you need to create it as a payload or whatever for
74 	 *  the DECL node as in ^(DECL type ID).
75 	 *
76 	 *  This is a variant of createToken where the new token is derived from
77 	 *  an actual real input token.  Typically this is for converting '{'
78 	 *  tokens to BLOCK etc...  You'll see
79 	 *
80 	 *    r : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;
81 	 *
82 	 *  If you care what the token payload objects' type is, you should
83 	 *  override this method and any other createToken variant.
84 	 */
createToken(Token fromToken)85 	public Token createToken(Token fromToken) {
86 		return new CommonToken(fromToken);
87 	}
88 
89 	/** Track start/stop token for subtree root created for a rule.
90 	 *  Only works with Tree nodes.  For rules that match nothing,
91 	 *  seems like this will yield start=i and stop=i-1 in a nil node.
92 	 *  Might be useful info so I'll not force to be i..i.
93 	 */
setTokenBoundaries(Object t, Token startToken, Token stopToken)94 	public void setTokenBoundaries(Object t, Token startToken, Token stopToken) {
95 		if ( t==null ) return;
96 		int start = 0;
97 		int stop = 0;
98 		if ( startToken!=null ) start = startToken.getTokenIndex();
99 		if ( stopToken!=null ) stop = stopToken.getTokenIndex();
100 		((Tree)t).setTokenStartIndex(start);
101 		((Tree)t).setTokenStopIndex(stop);
102 	}
103 
getTokenStartIndex(Object t)104 	public int getTokenStartIndex(Object t) {
105 		if ( t==null ) return -1;
106 		return ((Tree)t).getTokenStartIndex();
107 	}
108 
getTokenStopIndex(Object t)109 	public int getTokenStopIndex(Object t) {
110 		if ( t==null ) return -1;
111 		return ((Tree)t).getTokenStopIndex();
112 	}
113 
getText(Object t)114 	public String getText(Object t) {
115 		if ( t==null ) return null;
116 		return ((Tree)t).getText();
117 	}
118 
getType(Object t)119     public int getType(Object t) {
120 		if ( t==null ) return Token.INVALID_TOKEN_TYPE;
121 		return ((Tree)t).getType();
122 	}
123 
124 	/** What is the Token associated with this node?  If
125 	 *  you are not using CommonTree, then you must
126 	 *  override this in your own adaptor.
127 	 */
getToken(Object t)128 	public Token getToken(Object t) {
129 		if ( t instanceof CommonTree ) {
130 			return ((CommonTree)t).getToken();
131 		}
132 		return null; // no idea what to do
133 	}
134 
getChild(Object t, int i)135 	public Object getChild(Object t, int i) {
136 		if ( t==null ) return null;
137         return ((Tree)t).getChild(i);
138     }
139 
getChildCount(Object t)140     public int getChildCount(Object t) {
141 		if ( t==null ) return 0;
142         return ((Tree)t).getChildCount();
143     }
144 
getParent(Object t)145 	public Object getParent(Object t) {
146 		if ( t==null ) return null;
147         return ((Tree)t).getParent();
148 	}
149 
setParent(Object t, Object parent)150 	public void setParent(Object t, Object parent) {
151         if ( t!=null ) ((Tree)t).setParent((Tree)parent);
152 	}
153 
getChildIndex(Object t)154 	public int getChildIndex(Object t) {
155         if ( t==null ) return 0;
156 		return ((Tree)t).getChildIndex();
157 	}
158 
setChildIndex(Object t, int index)159 	public void setChildIndex(Object t, int index) {
160         if ( t!=null ) ((Tree)t).setChildIndex(index);
161 	}
162 
replaceChildren(Object parent, int startChildIndex, int stopChildIndex, Object t)163 	public void replaceChildren(Object parent, int startChildIndex, int stopChildIndex, Object t) {
164 		if ( parent!=null ) {
165 			((Tree)parent).replaceChildren(startChildIndex, stopChildIndex, t);
166 		}
167 	}
168 }
169