aboutsummaryrefslogtreecommitdiff
path: root/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/CommonTreeNodeStream.cs
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/CSharp3/Sources/Antlr3.Runtime/Tree/CommonTreeNodeStream.cs')
-rw-r--r--runtime/CSharp3/Sources/Antlr3.Runtime/Tree/CommonTreeNodeStream.cs88
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 )