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