diff options
Diffstat (limited to 'runtime/CSharp3/Sources/Antlr3.Runtime/Tree/CommonTreeNodeStream.cs')
-rw-r--r-- | runtime/CSharp3/Sources/Antlr3.Runtime/Tree/CommonTreeNodeStream.cs | 88 |
1 files changed, 73 insertions, 15 deletions
diff --git a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/CommonTreeNodeStream.cs b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/CommonTreeNodeStream.cs index 45c46be..f9cb0a7 100644 --- a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/CommonTreeNodeStream.cs +++ b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/CommonTreeNodeStream.cs @@ -1,10 +1,10 @@ /* - * [The "BSD licence"] - * Copyright (c) 2005-2008 Terence Parr + * [The "BSD license"] + * Copyright (c) 2011 Terence Parr * All rights reserved. * * Conversion to C#: - * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc. + * Copyright (c) 2011 Sam Harwell, Pixel Mine, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,35 +36,45 @@ namespace Antlr.Runtime.Tree using Antlr.Runtime.Misc; using StringBuilder = System.Text.StringBuilder; - using NotSupportedException = System.NotSupportedException; [System.Serializable] - public class CommonTreeNodeStream : LookaheadStream<object>, ITreeNodeStream + public class CommonTreeNodeStream : LookaheadStream<object>, ITreeNodeStream, IPositionTrackingStream { 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; + private readonly 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; + private ITreeAdaptor _adaptor; /** The tree iterator we are using */ - TreeIterator _it; + private readonly TreeIterator _it; /** <summary>Stack of indexes used for push/pop calls</summary> */ - Stack<int> _calls; + private Stack<int> _calls; /** <summary>Tree (nil A B C) trees like flat A B C streams</summary> */ - bool _hasNilRoot = false; + private bool _hasNilRoot = false; /** <summary>Tracks tree depth. Level=0 means we're at root node level.</summary> */ - int _level = 0; + private int _level = 0; + + /** + * Tracks the last node before the start of {@link #data} which contains + * position information to provide information for error reporting. This is + * tracked in addition to {@link #prevElement} which may or may not contain + * position information. + * + * @see #hasPositionInformation + * @see RecognitionException#extractInformationFromTreeNodeStream + */ + private object _previousLocationElement; public CommonTreeNodeStream( object tree ) : this( new CommonTreeAdaptor(), tree ) @@ -97,6 +107,7 @@ namespace Antlr.Runtime.Tree { return tokens; } + set { tokens = value; @@ -138,12 +149,13 @@ namespace Antlr.Runtime.Tree #endregion - public virtual void Reset() + public override void Reset() { - base.Clear(); + base.Reset(); _it.Reset(); _hasNilRoot = false; _level = 0; + _previousLocationElement = null; if ( _calls != null ) _calls.Clear(); } @@ -181,6 +193,15 @@ namespace Antlr.Runtime.Tree return t; } + public override object Dequeue() + { + object result = base.Dequeue(); + if (_p == 0 && HasPositionInformation(PreviousElement)) + _previousLocationElement = PreviousElement; + + return result; + } + public override bool IsEndOfFile(object o) { return TreeAdaptor.GetType(o) == CharStreamConstants.EndOfFile; @@ -197,9 +218,8 @@ namespace Antlr.Runtime.Tree public virtual void Push( int index ) { if ( _calls == null ) - { _calls = new Stack<int>(); - } + _calls.Push( _p ); // save current index Seek( index ); } @@ -214,6 +234,44 @@ namespace Antlr.Runtime.Tree return ret; } + /** + * Returns an element containing position information. If {@code allowApproximateLocation} is {@code false}, then + * this method will return the {@code LT(1)} element if it contains position information, and otherwise return {@code null}. + * If {@code allowApproximateLocation} is {@code true}, then this method will return the last known element containing position information. + * + * @see #hasPositionInformation + */ + public object GetKnownPositionElement(bool allowApproximateLocation) + { + object node = _data[_p]; + if (HasPositionInformation(node)) + return node; + + if (!allowApproximateLocation) + return null; + + for (int index = _p - 1; index >= 0; index--) + { + node = _data[index]; + if (HasPositionInformation(node)) + return node; + } + + return _previousLocationElement; + } + + public bool HasPositionInformation(object node) + { + IToken token = TreeAdaptor.GetToken(node); + if (token == null) + return false; + + if (token.Line <= 0) + return false; + + return true; + } + #region Tree rewrite interface public virtual void ReplaceChildren( object parent, int startChildIndex, int stopChildIndex, object t ) |