| /* |
| * [The "BSD licence"] |
| * Copyright (c) 2005-2008 Terence Parr |
| * All rights reserved. |
| * |
| * Conversion to C#: |
| * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. The name of the author may not be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| namespace Antlr.Runtime.Tree |
| { |
| using System.Collections.Generic; |
| using Antlr.Runtime.Misc; |
| |
| using StringBuilder = System.Text.StringBuilder; |
| using NotSupportedException = System.NotSupportedException; |
| |
| [System.Serializable] |
| public class CommonTreeNodeStream : LookaheadStream<object>, ITreeNodeStream |
| { |
| public const int DEFAULT_INITIAL_BUFFER_SIZE = 100; |
| public const int INITIAL_CALL_STACK_SIZE = 10; |
| |
| /** <summary>Pull nodes from which tree?</summary> */ |
| object _root; |
| |
| /** <summary>If this tree (root) was created from a token stream, track it.</summary> */ |
| protected ITokenStream tokens; |
| |
| /** <summary>What tree adaptor was used to build these trees</summary> */ |
| [System.NonSerialized] |
| ITreeAdaptor _adaptor; |
| |
| /** The tree iterator we are using */ |
| TreeIterator _it; |
| |
| /** <summary>Stack of indexes used for push/pop calls</summary> */ |
| Stack<int> _calls; |
| |
| /** <summary>Tree (nil A B C) trees like flat A B C streams</summary> */ |
| bool _hasNilRoot = false; |
| |
| /** <summary>Tracks tree depth. Level=0 means we're at root node level.</summary> */ |
| int _level = 0; |
| |
| public CommonTreeNodeStream( object tree ) |
| : this( new CommonTreeAdaptor(), tree ) |
| { |
| } |
| |
| public CommonTreeNodeStream( ITreeAdaptor adaptor, object tree ) |
| { |
| this._root = tree; |
| this._adaptor = adaptor; |
| _it = new TreeIterator( adaptor, _root ); |
| } |
| |
| #region Properties |
| |
| public virtual string SourceName |
| { |
| get |
| { |
| if ( TokenStream == null ) |
| return null; |
| |
| return TokenStream.SourceName; |
| } |
| } |
| |
| public virtual ITokenStream TokenStream |
| { |
| get |
| { |
| return tokens; |
| } |
| set |
| { |
| tokens = value; |
| } |
| } |
| |
| public virtual ITreeAdaptor TreeAdaptor |
| { |
| get |
| { |
| return _adaptor; |
| } |
| |
| set |
| { |
| _adaptor = value; |
| } |
| } |
| |
| public virtual object TreeSource |
| { |
| get |
| { |
| return _root; |
| } |
| } |
| |
| public virtual bool UniqueNavigationNodes |
| { |
| get |
| { |
| return false; |
| } |
| |
| set |
| { |
| } |
| } |
| |
| #endregion |
| |
| public virtual void Reset() |
| { |
| base.Clear(); |
| _it.Reset(); |
| _hasNilRoot = false; |
| _level = 0; |
| if ( _calls != null ) |
| _calls.Clear(); |
| } |
| |
| public override object NextElement() |
| { |
| _it.MoveNext(); |
| object t = _it.Current; |
| //System.out.println("pulled "+adaptor.getType(t)); |
| if ( t == _it.up ) |
| { |
| _level--; |
| if ( _level == 0 && _hasNilRoot ) |
| { |
| _it.MoveNext(); |
| return _it.Current; // don't give last UP; get EOF |
| } |
| } |
| else if ( t == _it.down ) |
| { |
| _level++; |
| } |
| |
| if ( _level == 0 && TreeAdaptor.IsNil( t ) ) |
| { |
| // if nil root, scarf nil, DOWN |
| _hasNilRoot = true; |
| _it.MoveNext(); |
| t = _it.Current; // t is now DOWN, so get first real node next |
| _level++; |
| _it.MoveNext(); |
| t = _it.Current; |
| } |
| |
| return t; |
| } |
| |
| public override bool IsEndOfFile(object o) |
| { |
| return TreeAdaptor.GetType(o) == CharStreamConstants.EndOfFile; |
| } |
| |
| public virtual int LA( int i ) |
| { |
| return TreeAdaptor.GetType( LT( i ) ); |
| } |
| |
| /** Make stream jump to a new location, saving old location. |
| * Switch back with pop(). |
| */ |
| public virtual void Push( int index ) |
| { |
| if ( _calls == null ) |
| { |
| _calls = new Stack<int>(); |
| } |
| _calls.Push( _p ); // save current index |
| Seek( index ); |
| } |
| |
| /** Seek back to previous index saved during last push() call. |
| * Return top of stack (return index). |
| */ |
| public virtual int Pop() |
| { |
| int ret = _calls.Pop(); |
| Seek( ret ); |
| return ret; |
| } |
| |
| #region Tree rewrite interface |
| |
| public virtual void ReplaceChildren( object parent, int startChildIndex, int stopChildIndex, object t ) |
| { |
| if ( parent != null ) |
| { |
| TreeAdaptor.ReplaceChildren( parent, startChildIndex, stopChildIndex, t ); |
| } |
| } |
| |
| #endregion |
| |
| public virtual string ToString( object start, object stop ) |
| { |
| // we'll have to walk from start to stop in tree; we're not keeping |
| // a complete node stream buffer |
| return "n/a"; |
| } |
| |
| /** <summary>For debugging; destructive: moves tree iterator to end.</summary> */ |
| public virtual string ToTokenTypeString() |
| { |
| Reset(); |
| StringBuilder buf = new StringBuilder(); |
| object o = LT( 1 ); |
| int type = TreeAdaptor.GetType( o ); |
| while ( type != TokenTypes.EndOfFile ) |
| { |
| buf.Append( " " ); |
| buf.Append( type ); |
| Consume(); |
| o = LT( 1 ); |
| type = TreeAdaptor.GetType( o ); |
| } |
| return buf.ToString(); |
| } |
| } |
| } |