aboutsummaryrefslogtreecommitdiff
path: root/runtime/CSharp3/Sources/Antlr3.Runtime/Tree
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/CSharp3/Sources/Antlr3.Runtime/Tree')
-rw-r--r--runtime/CSharp3/Sources/Antlr3.Runtime/Tree/BaseTree.cs47
-rw-r--r--runtime/CSharp3/Sources/Antlr3.Runtime/Tree/CommonTreeNodeStream.cs88
-rw-r--r--runtime/CSharp3/Sources/Antlr3.Runtime/Tree/IPositionTrackingStream.cs59
-rw-r--r--runtime/CSharp3/Sources/Antlr3.Runtime/Tree/ITreeNodeStream.cs64
-rw-r--r--runtime/CSharp3/Sources/Antlr3.Runtime/Tree/RewriteRuleElementStream.cs5
-rw-r--r--runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeFilter.cs4
-rw-r--r--runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeParser.cs4
-rw-r--r--runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeRewriter.cs8
8 files changed, 219 insertions, 60 deletions
diff --git a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/BaseTree.cs b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/BaseTree.cs
index 79f3d97..9327860 100644
--- a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/BaseTree.cs
+++ b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/BaseTree.cs
@@ -1,10 +1,10 @@
/*
- * [The "BSD licence"]
+ * [The "BSD license"]
* Copyright (c) 2011 Terence Parr
* All rights reserved.
*
* Conversion to C#:
- * Copyright (c) 2011 Sam Harwell, Pixel Mine, Inc.
+ * Copyright (c) 2011 Sam Harwell, Tunnel Vision Laboratories, LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -286,6 +286,30 @@ namespace Antlr.Runtime.Tree
t.ChildIndex = i;
}
+ /** Insert child t at child position i (0..n-1) by shifting children
+ * i+1..n-1 to the right one position. Set parent / indexes properly
+ * but does NOT collapse nil-rooted t's that come in here like addChild.
+ */
+ public virtual void InsertChild(int i, ITree t)
+ {
+ if (i < 0)
+ throw new ArgumentOutOfRangeException("i");
+ if (i > ChildCount)
+ throw new ArgumentException();
+
+ if (i == ChildCount)
+ {
+ AddChild(t);
+ return;
+ }
+
+ Children.Insert(i, t);
+
+ // walk others to increment their child indexes
+ // set index, parent of this one too
+ this.FreshenParentAndChildIndexes(i);
+ }
+
public virtual object DeleteChild( int i )
{
if (i < 0)
@@ -428,6 +452,25 @@ namespace Antlr.Runtime.Tree
}
}
+ public virtual void FreshenParentAndChildIndexesDeeply()
+ {
+ FreshenParentAndChildIndexesDeeply(0);
+ }
+
+ public virtual void FreshenParentAndChildIndexesDeeply(int offset)
+ {
+ int n = ChildCount;
+ for (int c = offset; c < n; c++)
+ {
+ ITree child = GetChild(c);
+ child.ChildIndex = c;
+ child.Parent = this;
+ BaseTree baseTree = child as BaseTree;
+ if (baseTree != null)
+ baseTree.FreshenParentAndChildIndexesDeeply();
+ }
+ }
+
public virtual void SanityCheckParentAndChildIndexes()
{
SanityCheckParentAndChildIndexes( null, -1 );
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 )
diff --git a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/IPositionTrackingStream.cs b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/IPositionTrackingStream.cs
new file mode 100644
index 0000000..8bc8945
--- /dev/null
+++ b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/IPositionTrackingStream.cs
@@ -0,0 +1,59 @@
+/*
+ [The "BSD license"]
+ Copyright (c) 2012 Terence Parr
+ Copyright (c) 2012 Sam Harwell
+ 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
+{
+ /**
+ *
+ * @author Sam Harwell
+ */
+ public interface IPositionTrackingStream
+ {
+ /**
+ * Returns an element containing concrete information about the current
+ * position in the stream.
+ *
+ * @param allowApproximateLocation if {@code false}, this method returns
+ * {@code null} if an element containing exact information about the current
+ * position is not available
+ */
+ object GetKnownPositionElement(bool allowApproximateLocation);
+
+ /**
+ * Determines if the specified {@code element} contains concrete position
+ * information.
+ *
+ * @param element the element to check
+ * @return {@code true} if {@code element} contains concrete position
+ * information, otherwise {@code false}
+ */
+ bool HasPositionInformation(object element);
+
+ }
+}
diff --git a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/ITreeNodeStream.cs b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/ITreeNodeStream.cs
index b133f39..8f3f30a 100644
--- a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/ITreeNodeStream.cs
+++ b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/ITreeNodeStream.cs
@@ -47,18 +47,18 @@ namespace Antlr.Runtime.Tree
}
/** <summary>
- * Get tree node at current input pointer + i ahead where i=1 is next node.
- * i&lt;0 indicates nodes in the past. So LT(-1) is previous node, but
- * implementations are not required to provide results for k &lt; -1.
- * LT(0) is undefined. For i&gt;=n, return null.
- * Return null for LT(0) and any index that results in an absolute address
- * that is negative.
+ * Get tree node at current input pointer + {@code k} ahead where
+ * {@code k==1} is next node. {@code k<0} indicates nodes in the past. So
+ * {@code LT(-1)} is previous node, but implementations are not required to
+ * provide results for {@code k < -1}. {@code LT(0)} is undefined. For
+ * {@code k<=n}, return {@code null}. Return {@code null} for {@code LT(0)}
+ * and any index that results in an absolute address that is negative.
* </summary>
*
* <remarks>
- * This is analogus to the LT() method of the TokenStream, but this
- * returns a tree node instead of a token. Makes code gen identical
- * for both parser and tree grammars. :)
+ * This is analogous to {@link TokenStream#LT}, but this returns a tree node
+ * instead of a {@link Token}. Makes code generation identical for both
+ * parser and tree grammars.
* </remarks>
*/
object LT( int k );
@@ -74,10 +74,11 @@ namespace Antlr.Runtime.Tree
}
/** <summary>
- * If the tree associated with this stream was created from a TokenStream,
- * you can specify it here. Used to do rule $text attribute in tree
- * parser. Optional unless you use tree parser rule text attribute
- * or output=template and rewrite=true options.
+ * If the tree associated with this stream was created from a
+ * {@link TokenStream}, you can specify it here. Used to do rule
+ * {@code $text} attribute in tree parser. Optional unless you use tree
+ * parser rule {@code $text} attribute or {@code output=template} and
+ * {@code rewrite=true} options.
* </summary>
*/
ITokenStream TokenStream
@@ -96,11 +97,11 @@ namespace Antlr.Runtime.Tree
}
/** <summary>
- * As we flatten the tree, we use UP, DOWN nodes to represent
- * the tree structure. When debugging we need unique nodes
- * so we have to instantiate new ones. When doing normal tree
- * parsing, it's slow and a waste of memory to create unique
- * navigation nodes. Default should be false;
+ * As we flatten the tree, we use {@link Token#UP}, {@link Token#DOWN} nodes
+ * to represent the tree structure. When debugging we need unique nodes so
+ * we have to instantiate new ones. When doing normal tree parsing, it's
+ * slow and a waste of memory to create unique navigation nodes. Default
+ * should be {@code false}.
* </summary>
*/
bool UniqueNavigationNodes
@@ -110,11 +111,11 @@ namespace Antlr.Runtime.Tree
}
/** <summary>
- * Return the text of all nodes from start to stop, inclusive.
- * If the stream does not buffer all the nodes then it can still
- * walk recursively from start until stop. You can always return
- * null or "" too, but users should not access $ruleLabel.text in
- * an action of course in that case.
+ * Return the text of all nodes from {@code start} to {@code stop},
+ * inclusive. If the stream does not buffer all the nodes then it can still
+ * walk recursively from start until stop. You can always return
+ * {@code null} or {@code ""} too, but users should not access
+ * {@code $ruleLabel.text} in an action of course in that case.
* </summary>
*/
string ToString( object start, object stop );
@@ -123,17 +124,18 @@ namespace Antlr.Runtime.Tree
#region REWRITING TREES (used by tree parser)
/** <summary>
- * Replace from start to stop child index of parent with t, which might
- * be a list. Number of children may be different
- * after this call. The stream is notified because it is walking the
- * tree and might need to know you are monkeying with the underlying
- * tree. Also, it might be able to modify the node stream to avoid
- * restreaming for future phases.
+ * Replace children of {@code parent} from index {@code startChildIndex} to
+ * {@code stopChildIndex} with {@code t}, which might be a list. Number of
+ * children may be different after this call. The stream is notified because
+ * it is walking the tree and might need to know you are monkeying with the
+ * underlying tree. Also, it might be able to modify the node stream to
+ * avoid restreaming for future phases.
* </summary>
*
* <remarks>
- * If parent is null, don't do anything; must be at root of overall tree.
- * Can't replace whatever points to the parent externally. Do nothing.
+ * If {@code parent} is {@code null}, don't do anything; must be at root of
+ * overall tree. Can't replace whatever points to the parent externally. Do
+ * nothing.
* </remarks>
*/
void ReplaceChildren( object parent, int startChildIndex, int stopChildIndex, object t );
diff --git a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/RewriteRuleElementStream.cs b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/RewriteRuleElementStream.cs
index 8e3d5b0..cb76ace 100644
--- a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/RewriteRuleElementStream.cs
+++ b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/RewriteRuleElementStream.cs
@@ -71,10 +71,7 @@ namespace Antlr.Runtime.Tree
/** <summary>Once a node / subtree has been used in a stream, it must be dup'd
* from then on. Streams are reset after subrules so that the streams
* can be reused in future subrules. So, reset must set a dirty bit.
- * If dirty, then next() always returns a dup.
- *
- * I wanted to use "naughty bit" here, but couldn't think of a way
- * to use "naughty".
+ * If dirty, then next() always returns a dup.</summary>
*/
protected bool dirty = false;
diff --git a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeFilter.cs b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeFilter.cs
index ef7b412..ba44e2d 100644
--- a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeFilter.cs
+++ b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeFilter.cs
@@ -58,8 +58,8 @@ namespace Antlr.Runtime.Tree
try
{
// share TreeParser object but not parsing-related state
- state = new RecognizerSharedState();
- input = new CommonTreeNodeStream( originalAdaptor, t );
+ SetState(new RecognizerSharedState());
+ SetTreeNodeStream(new CommonTreeNodeStream(originalAdaptor, t));
( (CommonTreeNodeStream)input ).TokenStream = originalTokenStream;
BacktrackingLevel = 1;
whichRule();
diff --git a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeParser.cs b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeParser.cs
index 927ee23..f5a1508 100644
--- a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeParser.cs
+++ b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeParser.cs
@@ -58,13 +58,13 @@ namespace Antlr.Runtime.Tree
public TreeParser( ITreeNodeStream input )
: base() // highlight that we go to super to set state object
{
- SetTreeNodeStream( input );
+ this.input = input;
}
public TreeParser( ITreeNodeStream input, RecognizerSharedState state )
: base( state ) // share the state object with another parser
{
- SetTreeNodeStream( input );
+ this.input = input;
}
public override void Reset()
diff --git a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeRewriter.cs b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeRewriter.cs
index b610c2c..16a38a2 100644
--- a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeRewriter.cs
+++ b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeRewriter.cs
@@ -67,8 +67,8 @@ namespace Antlr.Runtime.Tree
try
{
// share TreeParser object but not parsing-related state
- state = new RecognizerSharedState();
- input = new CommonTreeNodeStream( originalAdaptor, t );
+ SetState(new RecognizerSharedState());
+ SetTreeNodeStream(new CommonTreeNodeStream(originalAdaptor, t));
( (CommonTreeNodeStream)input ).TokenStream = originalTokenStream;
BacktrackingLevel = 1;
IAstRuleReturnScope r = whichRule();
@@ -119,12 +119,12 @@ namespace Antlr.Runtime.Tree
// methods the downup strategy uses to do the up and down rules.
// to override, just define tree grammar rule topdown and turn on
// filter=true.
- public virtual IAstRuleReturnScope Topdown()
+ protected virtual IAstRuleReturnScope Topdown()
{
return null;
}
- public virtual IAstRuleReturnScope Bottomup()
+ protected virtual IAstRuleReturnScope Bottomup()
{
return null;
}