1 /* 2 * [The "BSD licence"] 3 * Copyright (c) 2005-2008 Terence Parr 4 * All rights reserved. 5 * 6 * Conversion to C#: 7 * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 namespace Antlr.Runtime.Tree { 34 35 /** <summary> 36 * A TreeAdaptor that works with any Tree implementation. It provides 37 * really just factory methods; all the work is done by BaseTreeAdaptor. 38 * If you would like to have different tokens created than ClassicToken 39 * objects, you need to override this and then set the parser tree adaptor to 40 * use your subclass. 41 * </summary> 42 * 43 * <remarks> 44 * To get your parser to build nodes of a different type, override 45 * create(Token), errorNode(), and to be safe, YourTreeClass.dupNode(). 46 * dupNode is called to duplicate nodes during rewrite operations. 47 * </remarks> 48 */ 49 public class CommonTreeAdaptor : BaseTreeAdaptor { 50 /** <summary> 51 * Duplicate a node. This is part of the factory; 52 * override if you want another kind of node to be built. 53 * </summary> 54 * 55 * <remarks> 56 * I could use reflection to prevent having to override this 57 * but reflection is slow. 58 * </remarks> 59 */ DupNode(object t)60 public override object DupNode(object t) { 61 if (t == null) 62 return null; 63 64 return ((ITree)t).DupNode(); 65 } 66 Create(IToken payload)67 public override object Create(IToken payload) { 68 return new CommonTree(payload); 69 } 70 71 /** <summary> 72 * Tell me how to create a token for use with imaginary token nodes. 73 * For example, there is probably no input symbol associated with imaginary 74 * token DECL, but you need to create it as a payload or whatever for 75 * the DECL node as in ^(DECL type ID). 76 * </summary> 77 * 78 * <remarks> 79 * If you care what the token payload objects' type is, you should 80 * override this method and any other createToken variant. 81 * </remarks> 82 */ CreateToken(int tokenType, string text)83 public override IToken CreateToken(int tokenType, string text) { 84 return new CommonToken(tokenType, text); 85 } 86 87 /** <summary> 88 * Tell me how to create a token for use with imaginary token nodes. 89 * For example, there is probably no input symbol associated with imaginary 90 * token DECL, but you need to create it as a payload or whatever for 91 * the DECL node as in ^(DECL type ID). 92 * </summary> 93 * 94 * <remarks> 95 * This is a variant of createToken where the new token is derived from 96 * an actual real input token. Typically this is for converting '{' 97 * tokens to BLOCK etc... You'll see 98 * 99 * r : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ; 100 * 101 * If you care what the token payload objects' type is, you should 102 * override this method and any other createToken variant. 103 * </remarks> 104 */ CreateToken(IToken fromToken)105 public override IToken CreateToken(IToken fromToken) { 106 return new CommonToken(fromToken); 107 } 108 109 /** <summary> 110 * Track start/stop token for subtree root created for a rule. 111 * Only works with Tree nodes. For rules that match nothing, 112 * seems like this will yield start=i and stop=i-1 in a nil node. 113 * Might be useful info so I'll not force to be i..i. 114 * </summary> 115 */ SetTokenBoundaries(object t, IToken startToken, IToken stopToken)116 public override void SetTokenBoundaries(object t, IToken startToken, IToken stopToken) { 117 if (t == null) 118 return; 119 120 int start = 0; 121 int stop = 0; 122 123 if (startToken != null) 124 start = startToken.TokenIndex; 125 126 if (stopToken != null) 127 stop = stopToken.TokenIndex; 128 129 ((ITree)t).TokenStartIndex = start; 130 ((ITree)t).TokenStopIndex = stop; 131 } 132 GetTokenStartIndex(object t)133 public override int GetTokenStartIndex(object t) { 134 if (t == null) 135 return -1; 136 137 return ((ITree)t).TokenStartIndex; 138 } 139 GetTokenStopIndex(object t)140 public override int GetTokenStopIndex(object t) { 141 if (t == null) 142 return -1; 143 144 return ((ITree)t).TokenStopIndex; 145 } 146 GetText(object t)147 public override string GetText(object t) { 148 if (t == null) 149 return null; 150 151 return ((ITree)t).Text; 152 } 153 GetType(object t)154 public override int GetType(object t) { 155 if (t == null) 156 return TokenTypes.Invalid; 157 158 return ((ITree)t).Type; 159 } 160 161 /** <summary> 162 * What is the Token associated with this node? If 163 * you are not using CommonTree, then you must 164 * override this in your own adaptor. 165 * </summary> 166 */ GetToken(object t)167 public override IToken GetToken(object t) { 168 if (t is CommonTree) { 169 return ((CommonTree)t).Token; 170 } 171 return null; // no idea what to do 172 } 173 GetChild(object t, int i)174 public override object GetChild(object t, int i) { 175 if (t == null) 176 return null; 177 178 return ((ITree)t).GetChild(i); 179 } 180 GetChildCount(object t)181 public override int GetChildCount(object t) { 182 if (t == null) 183 return 0; 184 185 return ((ITree)t).ChildCount; 186 } 187 GetParent(object t)188 public override object GetParent(object t) { 189 if (t == null) 190 return null; 191 192 return ((ITree)t).Parent; 193 } 194 SetParent(object t, object parent)195 public override void SetParent(object t, object parent) { 196 if (t != null) 197 ((ITree)t).Parent = (ITree)parent; 198 } 199 GetChildIndex(object t)200 public override int GetChildIndex(object t) { 201 if (t == null) 202 return 0; 203 204 return ((ITree)t).ChildIndex; 205 } 206 SetChildIndex(object t, int index)207 public override void SetChildIndex(object t, int index) { 208 if (t != null) 209 ((ITree)t).ChildIndex = index; 210 } 211 ReplaceChildren(object parent, int startChildIndex, int stopChildIndex, object t)212 public override void ReplaceChildren(object parent, int startChildIndex, int stopChildIndex, object t) { 213 if (parent != null) { 214 ((ITree)parent).ReplaceChildren(startChildIndex, stopChildIndex, t); 215 } 216 } 217 } 218 } 219