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