• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * [The "BSD licence"]
3  * Copyright (c) 2011 Terence Parr
4  * All rights reserved.
5  *
6  * Conversion to C#:
7  * Copyright (c) 2011 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     using ArgumentNullException = System.ArgumentNullException;
36 
37     /** <summary>
38      *  A tree node that is wrapper for a Token object.  After 3.0 release
39      *  while building tree rewrite stuff, it became clear that computing
40      *  parent and child index is very difficult and cumbersome.  Better to
41      *  spend the space in every tree node.  If you don't want these extra
42      *  fields, it's easy to cut them out in your own BaseTree subclass.
43      *  </summary>
44      */
45     [System.Serializable]
46     public class CommonTree : BaseTree
47     {
48         /** <summary>A single token is the payload</summary> */
49         private IToken _token;
50 
51         /** <summary>
52          *  What token indexes bracket all tokens associated with this node
53          *  and below?
54          *  </summary>
55          */
56         protected int startIndex = -1;
57         protected int stopIndex = -1;
58 
59         /** <summary>Who is the parent node of this node; if null, implies node is root</summary> */
60         CommonTree parent;
61 
62         /** <summary>What index is this node in the child list? Range: 0..n-1</summary> */
63         int childIndex = -1;
64 
CommonTree()65         public CommonTree()
66         {
67         }
68 
CommonTree( CommonTree node )69         public CommonTree( CommonTree node )
70             : base( node )
71         {
72             if (node == null)
73                 throw new ArgumentNullException("node");
74 
75             this.Token = node.Token;
76             this.startIndex = node.startIndex;
77             this.stopIndex = node.stopIndex;
78         }
79 
CommonTree( IToken t )80         public CommonTree( IToken t )
81         {
82             this.Token = t;
83         }
84 
85         #region Properties
86 
87         public override int CharPositionInLine
88         {
89             get
90             {
91                 if ( Token == null || Token.CharPositionInLine == -1 )
92                 {
93                     if ( ChildCount > 0 )
94                         return Children[0].CharPositionInLine;
95 
96                     return 0;
97                 }
98                 return Token.CharPositionInLine;
99             }
100 
101             set
102             {
103                 base.CharPositionInLine = value;
104             }
105         }
106 
107         public override int ChildIndex
108         {
109             get
110             {
111                 return childIndex;
112             }
113 
114             set
115             {
116                 childIndex = value;
117             }
118         }
119 
120         public override bool IsNil
121         {
122             get
123             {
124                 return Token == null;
125             }
126         }
127 
128         public override int Line
129         {
130             get
131             {
132                 if ( Token == null || Token.Line == 0 )
133                 {
134                     if ( ChildCount > 0 )
135                         return Children[0].Line;
136 
137                     return 0;
138                 }
139 
140                 return Token.Line;
141             }
142 
143             set
144             {
145                 base.Line = value;
146             }
147         }
148 
149         public override ITree Parent
150         {
151             get
152             {
153                 return parent;
154             }
155 
156             set
157             {
158                 parent = (CommonTree)value;
159             }
160         }
161 
162         public override string Text
163         {
164             get
165             {
166                 if ( Token == null )
167                     return null;
168 
169                 return Token.Text;
170             }
171 
172             set
173             {
174             }
175         }
176 
177         public IToken Token
178         {
179             get
180             {
181                 return _token;
182             }
183 
184             set
185             {
186                 _token = value;
187             }
188         }
189 
190         public override int TokenStartIndex
191         {
192             get
193             {
194                 if ( startIndex == -1 && Token != null )
195                     return Token.TokenIndex;
196 
197                 return startIndex;
198             }
199 
200             set
201             {
202                 startIndex = value;
203             }
204         }
205 
206         public override int TokenStopIndex
207         {
208             get
209             {
210                 if ( stopIndex == -1 && Token != null )
211                 {
212                     return Token.TokenIndex;
213                 }
214                 return stopIndex;
215             }
216 
217             set
218             {
219                 stopIndex = value;
220             }
221         }
222 
223         public override int Type
224         {
225             get
226             {
227                 if ( Token == null )
228                     return TokenTypes.Invalid;
229 
230                 return Token.Type;
231             }
232 
233             set
234             {
235             }
236         }
237 
238         #endregion
239 
DupNode()240         public override ITree DupNode()
241         {
242             return new CommonTree( this );
243         }
244 
245         /** <summary>
246          *  For every node in this subtree, make sure it's start/stop token's
247          *  are set.  Walk depth first, visit bottom up.  Only updates nodes
248          *  with at least one token index &lt; 0.
249          *  </summary>
250          */
SetUnknownTokenBoundaries()251         public virtual void SetUnknownTokenBoundaries()
252         {
253             if ( Children == null )
254             {
255                 if ( startIndex < 0 || stopIndex < 0 )
256                     startIndex = stopIndex = Token.TokenIndex;
257 
258                 return;
259             }
260 
261             foreach (ITree childTree in Children)
262             {
263                 CommonTree commonTree = childTree as CommonTree;
264                 if (commonTree == null)
265                     continue;
266 
267                 commonTree.SetUnknownTokenBoundaries();
268             }
269 
270             if ( startIndex >= 0 && stopIndex >= 0 )
271                 return; // already set
272 
273             if ( Children.Count > 0 )
274             {
275                 ITree firstChild = Children[0];
276                 ITree lastChild = Children[Children.Count - 1];
277                 startIndex = firstChild.TokenStartIndex;
278                 stopIndex = lastChild.TokenStopIndex;
279             }
280         }
281 
ToString()282         public override string ToString()
283         {
284             if (IsNil)
285                 return "nil";
286 
287             if (Type == TokenTypes.Invalid)
288                 return "<errornode>";
289 
290             if (Token == null)
291                 return string.Empty;
292 
293             return Token.Text;
294         }
295     }
296 }
297