• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     using System.Collections.Generic;
36     using Antlr.Runtime.Misc;
37 
38     using StringBuilder = System.Text.StringBuilder;
39     using NotSupportedException = System.NotSupportedException;
40 
41     [System.Serializable]
42     public class CommonTreeNodeStream : LookaheadStream<object>, ITreeNodeStream
43     {
44         public const int DEFAULT_INITIAL_BUFFER_SIZE = 100;
45         public const int INITIAL_CALL_STACK_SIZE = 10;
46 
47         /** <summary>Pull nodes from which tree?</summary> */
48         object _root;
49 
50         /** <summary>If this tree (root) was created from a token stream, track it.</summary> */
51         protected ITokenStream tokens;
52 
53         /** <summary>What tree adaptor was used to build these trees</summary> */
54         [System.NonSerialized]
55         ITreeAdaptor _adaptor;
56 
57         /** The tree iterator we are using */
58         TreeIterator _it;
59 
60         /** <summary>Stack of indexes used for push/pop calls</summary> */
61         Stack<int> _calls;
62 
63         /** <summary>Tree (nil A B C) trees like flat A B C streams</summary> */
64         bool _hasNilRoot = false;
65 
66         /** <summary>Tracks tree depth.  Level=0 means we're at root node level.</summary> */
67         int _level = 0;
68 
CommonTreeNodeStream( object tree )69         public CommonTreeNodeStream( object tree )
70             : this( new CommonTreeAdaptor(), tree )
71         {
72         }
73 
CommonTreeNodeStream( ITreeAdaptor adaptor, object tree )74         public CommonTreeNodeStream( ITreeAdaptor adaptor, object tree )
75         {
76             this._root = tree;
77             this._adaptor = adaptor;
78             _it = new TreeIterator( adaptor, _root );
79         }
80 
81         #region Properties
82 
83         public virtual string SourceName
84         {
85             get
86             {
87                 if ( TokenStream == null )
88                     return null;
89 
90                 return TokenStream.SourceName;
91             }
92         }
93 
94         public virtual ITokenStream TokenStream
95         {
96             get
97             {
98                 return tokens;
99             }
100             set
101             {
102                 tokens = value;
103             }
104         }
105 
106         public virtual ITreeAdaptor TreeAdaptor
107         {
108             get
109             {
110                 return _adaptor;
111             }
112 
113             set
114             {
115                 _adaptor = value;
116             }
117         }
118 
119         public virtual object TreeSource
120         {
121             get
122             {
123                 return _root;
124             }
125         }
126 
127         public virtual bool UniqueNavigationNodes
128         {
129             get
130             {
131                 return false;
132             }
133 
134             set
135             {
136             }
137         }
138 
139         #endregion
140 
Reset()141         public virtual void Reset()
142         {
143             base.Clear();
144             _it.Reset();
145             _hasNilRoot = false;
146             _level = 0;
147             if ( _calls != null )
148                 _calls.Clear();
149         }
150 
NextElement()151         public override object NextElement()
152         {
153             _it.MoveNext();
154             object t = _it.Current;
155             //System.out.println("pulled "+adaptor.getType(t));
156             if ( t == _it.up )
157             {
158                 _level--;
159                 if ( _level == 0 && _hasNilRoot )
160                 {
161                     _it.MoveNext();
162                     return _it.Current; // don't give last UP; get EOF
163                 }
164             }
165             else if ( t == _it.down )
166             {
167                 _level++;
168             }
169 
170             if ( _level == 0 && TreeAdaptor.IsNil( t ) )
171             {
172                 // if nil root, scarf nil, DOWN
173                 _hasNilRoot = true;
174                 _it.MoveNext();
175                 t = _it.Current; // t is now DOWN, so get first real node next
176                 _level++;
177                 _it.MoveNext();
178                 t = _it.Current;
179             }
180 
181             return t;
182         }
183 
IsEndOfFile(object o)184         public override bool IsEndOfFile(object o)
185         {
186             return TreeAdaptor.GetType(o) == CharStreamConstants.EndOfFile;
187         }
188 
LA( int i )189         public virtual int LA( int i )
190         {
191             return TreeAdaptor.GetType( LT( i ) );
192         }
193 
194         /** Make stream jump to a new location, saving old location.
195          *  Switch back with pop().
196          */
Push( int index )197         public virtual void Push( int index )
198         {
199             if ( _calls == null )
200             {
201                 _calls = new Stack<int>();
202             }
203             _calls.Push( _p ); // save current index
204             Seek( index );
205         }
206 
207         /** Seek back to previous index saved during last push() call.
208          *  Return top of stack (return index).
209          */
Pop()210         public virtual int Pop()
211         {
212             int ret = _calls.Pop();
213             Seek( ret );
214             return ret;
215         }
216 
217         #region Tree rewrite interface
218 
ReplaceChildren( object parent, int startChildIndex, int stopChildIndex, object t )219         public virtual void ReplaceChildren( object parent, int startChildIndex, int stopChildIndex, object t )
220         {
221             if ( parent != null )
222             {
223                 TreeAdaptor.ReplaceChildren( parent, startChildIndex, stopChildIndex, t );
224             }
225         }
226 
227         #endregion
228 
ToString( object start, object stop )229         public virtual string ToString( object start, object stop )
230         {
231             // we'll have to walk from start to stop in tree; we're not keeping
232             // a complete node stream buffer
233             return "n/a";
234         }
235 
236         /** <summary>For debugging; destructive: moves tree iterator to end.</summary> */
ToTokenTypeString()237         public virtual string ToTokenTypeString()
238         {
239             Reset();
240             StringBuilder buf = new StringBuilder();
241             object o = LT( 1 );
242             int type = TreeAdaptor.GetType( o );
243             while ( type != TokenTypes.EndOfFile )
244             {
245                 buf.Append( " " );
246                 buf.Append( type );
247                 Consume();
248                 o = LT( 1 );
249                 type = TreeAdaptor.GetType( o );
250             }
251             return buf.ToString();
252         }
253     }
254 }
255