aboutsummaryrefslogtreecommitdiff
path: root/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeWizard.cs
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeWizard.cs')
-rw-r--r--runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeWizard.cs736
1 files changed, 0 insertions, 736 deletions
diff --git a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeWizard.cs b/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeWizard.cs
deleted file mode 100644
index 98c759b..0000000
--- a/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/TreeWizard.cs
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- * [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.
- */
-
-// TODO: build indexes for wizard
-//#define BUILD_INDEXES
-
-namespace Antlr.Runtime.Tree
-{
- using System.Collections.Generic;
-
- using IList = System.Collections.IList;
-#if BUILD_INDEXES
- using IDictionary = System.Collections.IDictionary;
-#endif
-
- /** <summary>
- * Build and navigate trees with this object. Must know about the names
- * of tokens so you have to pass in a map or array of token names (from which
- * this class can build the map). I.e., Token DECL means nothing unless the
- * class can translate it to a token type.
- * </summary>
- *
- * <remarks>
- * In order to create nodes and navigate, this class needs a TreeAdaptor.
- *
- * This class can build a token type -> node index for repeated use or for
- * iterating over the various nodes with a particular type.
- *
- * This class works in conjunction with the TreeAdaptor rather than moving
- * all this functionality into the adaptor. An adaptor helps build and
- * navigate trees using methods. This class helps you do it with string
- * patterns like "(A B C)". You can create a tree from that pattern or
- * match subtrees against it.
- * </remarks>
- */
- public class TreeWizard
- {
- protected ITreeAdaptor adaptor;
- protected IDictionary<string, int> tokenNameToTypeMap;
-
- public interface IContextVisitor
- {
- // TODO: should this be called visit or something else?
- void Visit( object t, object parent, int childIndex, IDictionary<string, object> labels );
- }
-
- public abstract class Visitor : IContextVisitor
- {
- public virtual void Visit( object t, object parent, int childIndex, IDictionary<string, object> labels )
- {
- Visit( t );
- }
- public abstract void Visit( object t );
- }
-
- class ActionVisitor : Visitor
- {
- System.Action<object> _action;
-
- public ActionVisitor( System.Action<object> action )
- {
- _action = action;
- }
-
- public override void Visit( object t )
- {
- _action( t );
- }
- }
-
- /** <summary>
- * When using %label:TOKENNAME in a tree for parse(), we must
- * track the label.
- * </summary>
- */
- public class TreePattern : CommonTree
- {
- public string label;
- public bool hasTextArg;
- public TreePattern( IToken payload ) :
- base( payload )
- {
- }
- public override string ToString()
- {
- if ( label != null )
- {
- return "%" + label + ":"; //+ base.ToString();
- }
- else
- {
- return base.ToString();
- }
- }
- }
-
- public class WildcardTreePattern : TreePattern
- {
- public WildcardTreePattern( IToken payload ) :
- base( payload )
- {
- }
- }
-
- /** <summary>This adaptor creates TreePattern objects for use during scan()</summary> */
- public class TreePatternTreeAdaptor : CommonTreeAdaptor
- {
- public override object Create( IToken payload )
- {
- return new TreePattern( payload );
- }
- }
-
-#if BUILD_INDEXES
- // TODO: build indexes for the wizard
-
- /** <summary>
- * During fillBuffer(), we can make a reverse index from a set
- * of token types of interest to the list of indexes into the
- * node stream. This lets us convert a node pointer to a
- * stream index semi-efficiently for a list of interesting
- * nodes such as function definition nodes (you'll want to seek
- * to their bodies for an interpreter). Also useful for doing
- * dynamic searches; i.e., go find me all PLUS nodes.
- * </summary>
- */
- protected IDictionary<int, IList<int>> tokenTypeToStreamIndexesMap;
-
- /** <summary>
- * If tokenTypesToReverseIndex set to INDEX_ALL then indexing
- * occurs for all token types.
- * </summary>
- */
- public static readonly HashSet<int> INDEX_ALL = new HashSet<int>();
-
- /** <summary>
- * A set of token types user would like to index for faster lookup.
- * If this is INDEX_ALL, then all token types are tracked. If null,
- * then none are indexed.
- * </summary>
- */
- protected HashSet<int> tokenTypesToReverseIndex = null;
-#endif
-
- public TreeWizard( ITreeAdaptor adaptor )
- {
- this.adaptor = adaptor;
- }
-
- public TreeWizard( ITreeAdaptor adaptor, IDictionary<string, int> tokenNameToTypeMap )
- {
- this.adaptor = adaptor;
- this.tokenNameToTypeMap = tokenNameToTypeMap;
- }
-
- public TreeWizard( ITreeAdaptor adaptor, string[] tokenNames )
- {
- this.adaptor = adaptor;
- this.tokenNameToTypeMap = ComputeTokenTypes( tokenNames );
- }
-
- public TreeWizard( string[] tokenNames )
- : this( new CommonTreeAdaptor(), tokenNames )
- {
- }
-
- /** <summary>
- * Compute a Map&lt;String, Integer&gt; that is an inverted index of
- * tokenNames (which maps int token types to names).
- * </summary>
- */
- public virtual IDictionary<string, int> ComputeTokenTypes( string[] tokenNames )
- {
- IDictionary<string, int> m = new Dictionary<string, int>();
- if ( tokenNames == null )
- {
- return m;
- }
- for ( int ttype = TokenTypes.Min; ttype < tokenNames.Length; ttype++ )
- {
- string name = tokenNames[ttype];
- m[name] = ttype;
- }
- return m;
- }
-
- /** <summary>Using the map of token names to token types, return the type.</summary> */
- public virtual int GetTokenType( string tokenName )
- {
- if ( tokenNameToTypeMap == null )
- {
- return TokenTypes.Invalid;
- }
-
- int value;
- if ( tokenNameToTypeMap.TryGetValue( tokenName, out value ) )
- return value;
-
- return TokenTypes.Invalid;
- }
-
- /** <summary>
- * Walk the entire tree and make a node name to nodes mapping.
- * For now, use recursion but later nonrecursive version may be
- * more efficient. Returns Map&lt;Integer, List&gt; where the List is
- * of your AST node type. The Integer is the token type of the node.
- * </summary>
- *
- * <remarks>
- * TODO: save this index so that find and visit are faster
- * </remarks>
- */
- public IDictionary<int, IList> Index( object t )
- {
- IDictionary<int, IList> m = new Dictionary<int, IList>();
- IndexCore( t, m );
- return m;
- }
-
- /** <summary>Do the work for index</summary> */
- protected virtual void IndexCore( object t, IDictionary<int, IList> m )
- {
- if ( t == null )
- {
- return;
- }
- int ttype = adaptor.GetType( t );
- IList elements;
- if ( !m.TryGetValue( ttype, out elements ) || elements == null )
- {
- elements = new List<object>();
- m[ttype] = elements;
- }
- elements.Add( t );
- int n = adaptor.GetChildCount( t );
- for ( int i = 0; i < n; i++ )
- {
- object child = adaptor.GetChild( t, i );
- IndexCore( child, m );
- }
- }
-
- class FindTreeWizardVisitor : TreeWizard.Visitor
- {
- IList _nodes;
- public FindTreeWizardVisitor( IList nodes )
- {
- _nodes = nodes;
- }
- public override void Visit( object t )
- {
- _nodes.Add( t );
- }
- }
- class FindTreeWizardContextVisitor : TreeWizard.IContextVisitor
- {
- TreeWizard _outer;
- TreePattern _tpattern;
- IList _subtrees;
- public FindTreeWizardContextVisitor( TreeWizard outer, TreePattern tpattern, IList subtrees )
- {
- _outer = outer;
- _tpattern = tpattern;
- _subtrees = subtrees;
- }
-
- public void Visit( object t, object parent, int childIndex, IDictionary<string, object> labels )
- {
- if ( _outer.ParseCore( t, _tpattern, null ) )
- {
- _subtrees.Add( t );
- }
- }
- }
-
- /** <summary>Return a List of tree nodes with token type ttype</summary> */
- public virtual IList Find( object t, int ttype )
- {
- IList nodes = new List<object>();
- Visit( t, ttype, new FindTreeWizardVisitor( nodes ) );
- return nodes;
- }
-
- /** <summary>Return a List of subtrees matching pattern.</summary> */
- public virtual IList Find( object t, string pattern )
- {
- IList subtrees = new List<object>();
- // Create a TreePattern from the pattern
- TreePatternLexer tokenizer = new TreePatternLexer( pattern );
- TreePatternParser parser =
- new TreePatternParser( tokenizer, this, new TreePatternTreeAdaptor() );
- TreePattern tpattern = (TreePattern)parser.Pattern();
- // don't allow invalid patterns
- if ( tpattern == null ||
- tpattern.IsNil ||
- tpattern.GetType() == typeof( WildcardTreePattern ) )
- {
- return null;
- }
- int rootTokenType = tpattern.Type;
- Visit( t, rootTokenType, new FindTreeWizardContextVisitor( this, tpattern, subtrees ) );
- return subtrees;
- }
-
- public virtual object FindFirst( object t, int ttype )
- {
- return null;
- }
-
- public virtual object FindFirst( object t, string pattern )
- {
- return null;
- }
-
- /** <summary>
- * Visit every ttype node in t, invoking the visitor. This is a quicker
- * version of the general visit(t, pattern) method. The labels arg
- * of the visitor action method is never set (it's null) since using
- * a token type rather than a pattern doesn't let us set a label.
- * </summary>
- */
- public void Visit( object t, int ttype, IContextVisitor visitor )
- {
- VisitCore( t, null, 0, ttype, visitor );
- }
-
- public void Visit( object t, int ttype, System.Action<object> action )
- {
- Visit( t, ttype, new ActionVisitor( action ) );
- }
-
- /** <summary>Do the recursive work for visit</summary> */
- protected virtual void VisitCore( object t, object parent, int childIndex, int ttype, IContextVisitor visitor )
- {
- if ( t == null )
- {
- return;
- }
- if ( adaptor.GetType( t ) == ttype )
- {
- visitor.Visit( t, parent, childIndex, null );
- }
- int n = adaptor.GetChildCount( t );
- for ( int i = 0; i < n; i++ )
- {
- object child = adaptor.GetChild( t, i );
- VisitCore( child, t, i, ttype, visitor );
- }
- }
-
- class VisitTreeWizardContextVisitor : TreeWizard.IContextVisitor
- {
- TreeWizard _outer;
- IContextVisitor _visitor;
- IDictionary<string, object> _labels;
- TreePattern _tpattern;
-
- public VisitTreeWizardContextVisitor( TreeWizard outer, IContextVisitor visitor, IDictionary<string, object> labels, TreePattern tpattern )
- {
- _outer = outer;
- _visitor = visitor;
- _labels = labels;
- _tpattern = tpattern;
- }
-
- public void Visit( object t, object parent, int childIndex, IDictionary<string, object> unusedlabels )
- {
- // the unusedlabels arg is null as visit on token type doesn't set.
- _labels.Clear();
- if ( _outer.ParseCore( t, _tpattern, _labels ) )
- {
- _visitor.Visit( t, parent, childIndex, _labels );
- }
- }
- }
-
- /** <summary>
- * For all subtrees that match the pattern, execute the visit action.
- * The implementation uses the root node of the pattern in combination
- * with visit(t, ttype, visitor) so nil-rooted patterns are not allowed.
- * Patterns with wildcard roots are also not allowed.
- * </summary>
- */
- public void Visit( object t, string pattern, IContextVisitor visitor )
- {
- // Create a TreePattern from the pattern
- TreePatternLexer tokenizer = new TreePatternLexer( pattern );
- TreePatternParser parser =
- new TreePatternParser( tokenizer, this, new TreePatternTreeAdaptor() );
- TreePattern tpattern = (TreePattern)parser.Pattern();
- // don't allow invalid patterns
- if ( tpattern == null ||
- tpattern.IsNil ||
- tpattern.GetType() == typeof( WildcardTreePattern ) )
- {
- return;
- }
- IDictionary<string, object> labels = new Dictionary<string, object>(); // reused for each _parse
- int rootTokenType = tpattern.Type;
- Visit( t, rootTokenType, new VisitTreeWizardContextVisitor( this, visitor, labels, tpattern ) );
- }
-
- /** <summary>
- * Given a pattern like (ASSIGN %lhs:ID %rhs:.) with optional labels
- * on the various nodes and '.' (dot) as the node/subtree wildcard,
- * return true if the pattern matches and fill the labels Map with
- * the labels pointing at the appropriate nodes. Return false if
- * the pattern is malformed or the tree does not match.
- * </summary>
- *
- * <remarks>
- * If a node specifies a text arg in pattern, then that must match
- * for that node in t.
- *
- * TODO: what's a better way to indicate bad pattern? Exceptions are a hassle
- * </remarks>
- */
- public bool Parse( object t, string pattern, IDictionary<string, object> labels )
- {
- TreePatternLexer tokenizer = new TreePatternLexer( pattern );
- TreePatternParser parser =
- new TreePatternParser( tokenizer, this, new TreePatternTreeAdaptor() );
- TreePattern tpattern = (TreePattern)parser.Pattern();
- /*
- System.out.println("t="+((Tree)t).toStringTree());
- System.out.println("scant="+tpattern.toStringTree());
- */
- bool matched = ParseCore( t, tpattern, labels );
- return matched;
- }
-
- public bool Parse( object t, string pattern )
- {
- return Parse( t, pattern, null );
- }
-
- /** <summary>
- * Do the work for parse. Check to see if the t2 pattern fits the
- * structure and token types in t1. Check text if the pattern has
- * text arguments on nodes. Fill labels map with pointers to nodes
- * in tree matched against nodes in pattern with labels.
- * </summary>
- */
- protected virtual bool ParseCore( object t1, TreePattern tpattern, IDictionary<string, object> labels )
- {
- // make sure both are non-null
- if ( t1 == null || tpattern == null )
- {
- return false;
- }
- // check roots (wildcard matches anything)
- if ( tpattern.GetType() != typeof( WildcardTreePattern ) )
- {
- if ( adaptor.GetType( t1 ) != tpattern.Type )
- {
- return false;
- }
- // if pattern has text, check node text
- if ( tpattern.hasTextArg && !adaptor.GetText( t1 ).Equals( tpattern.Text ) )
- {
- return false;
- }
- }
- if ( tpattern.label != null && labels != null )
- {
- // map label in pattern to node in t1
- labels[tpattern.label] = t1;
- }
- // check children
- int n1 = adaptor.GetChildCount( t1 );
- int n2 = tpattern.ChildCount;
- if ( n1 != n2 )
- {
- return false;
- }
- for ( int i = 0; i < n1; i++ )
- {
- object child1 = adaptor.GetChild( t1, i );
- TreePattern child2 = (TreePattern)tpattern.GetChild( i );
- if ( !ParseCore( child1, child2, labels ) )
- {
- return false;
- }
- }
- return true;
- }
-
- /** <summary>
- * Create a tree or node from the indicated tree pattern that closely
- * follows ANTLR tree grammar tree element syntax:
- *
- * (root child1 ... child2).
- * </summary>
- *
- * <remarks>
- * You can also just pass in a node: ID
- *
- * Any node can have a text argument: ID[foo]
- * (notice there are no quotes around foo--it's clear it's a string).
- *
- * nil is a special name meaning "give me a nil node". Useful for
- * making lists: (nil A B C) is a list of A B C.
- * </remarks>
- */
- public virtual object Create( string pattern )
- {
- TreePatternLexer tokenizer = new TreePatternLexer( pattern );
- TreePatternParser parser = new TreePatternParser( tokenizer, this, adaptor );
- object t = parser.Pattern();
- return t;
- }
-
- /** <summary>
- * Compare t1 and t2; return true if token types/text, structure match exactly.
- * The trees are examined in their entirety so that (A B) does not match
- * (A B C) nor (A (B C)).
- * </summary>
- *
- * <remarks>
- * TODO: allow them to pass in a comparator
- * TODO: have a version that is nonstatic so it can use instance adaptor
- *
- * I cannot rely on the tree node's equals() implementation as I make
- * no constraints at all on the node types nor interface etc...
- * </remarks>
- */
- public static bool Equals( object t1, object t2, ITreeAdaptor adaptor )
- {
- return EqualsCore( t1, t2, adaptor );
- }
-
- /** <summary>
- * Compare type, structure, and text of two trees, assuming adaptor in
- * this instance of a TreeWizard.
- * </summary>
- */
- public new bool Equals( object t1, object t2 )
- {
- return EqualsCore( t1, t2, adaptor );
- }
-
- protected static bool EqualsCore( object t1, object t2, ITreeAdaptor adaptor )
- {
- // make sure both are non-null
- if ( t1 == null || t2 == null )
- {
- return false;
- }
- // check roots
- if ( adaptor.GetType( t1 ) != adaptor.GetType( t2 ) )
- {
- return false;
- }
- if ( !adaptor.GetText( t1 ).Equals( adaptor.GetText( t2 ) ) )
- {
- return false;
- }
- // check children
- int n1 = adaptor.GetChildCount( t1 );
- int n2 = adaptor.GetChildCount( t2 );
- if ( n1 != n2 )
- {
- return false;
- }
- for ( int i = 0; i < n1; i++ )
- {
- object child1 = adaptor.GetChild( t1, i );
- object child2 = adaptor.GetChild( t2, i );
- if ( !EqualsCore( child1, child2, adaptor ) )
- {
- return false;
- }
- }
- return true;
- }
-
-#if BUILD_INDEXES
- // TODO: next stuff taken from CommonTreeNodeStream
-
- /** <summary>
- * Given a node, add this to the reverse index tokenTypeToStreamIndexesMap.
- * You can override this method to alter how indexing occurs. The
- * default is to create a
- *
- * Map&lt;Integer token type,ArrayList&lt;Integer stream index&gt;&gt;
- * </summary>
- *
- * <remarks>
- * This data structure allows you to find all nodes with type INT in order.
- *
- * If you really need to find a node of type, say, FUNC quickly then perhaps
- *
- * Map&lt;Integertoken type,Map&lt;Object tree node,Integer stream index&gt;&gt;
- *
- * would be better for you. The interior maps map a tree node to
- * the index so you don't have to search linearly for a specific node.
- *
- * If you change this method, you will likely need to change
- * getNodeIndex(), which extracts information.
- * </remarks>
- */
- protected void fillReverseIndex( object node, int streamIndex )
- {
- //System.out.println("revIndex "+node+"@"+streamIndex);
- if ( tokenTypesToReverseIndex == null )
- {
- return; // no indexing if this is empty (nothing of interest)
- }
- if ( tokenTypeToStreamIndexesMap == null )
- {
- tokenTypeToStreamIndexesMap = new Dictionary<int, IList<int>>(); // first indexing op
- }
- int tokenType = adaptor.getType( node );
- if ( !( tokenTypesToReverseIndex == INDEX_ALL ||
- tokenTypesToReverseIndex.Contains( tokenType ) ) )
- {
- return; // tokenType not of interest
- }
- IList<int> indexes;
-
- if ( !tokenTypeToStreamIndexesMap.TryGetValue( tokenType, out indexes ) || indexes == null )
- {
- indexes = new List<int>(); // no list yet for this token type
- indexes.Add( streamIndex ); // not there yet, add
- tokenTypeToStreamIndexesMap[tokenType] = indexes;
- }
- else
- {
- if ( !indexes.Contains( streamIndex ) )
- {
- indexes.Add( streamIndex ); // not there yet, add
- }
- }
- }
-
- /** <summary>
- * Track the indicated token type in the reverse index. Call this
- * repeatedly for each type or use variant with Set argument to
- * set all at once.
- * </summary>
- *
- * <param name="tokenType" />
- */
- public void reverseIndex( int tokenType )
- {
- if ( tokenTypesToReverseIndex == null )
- {
- tokenTypesToReverseIndex = new HashSet<int>();
- }
- else if ( tokenTypesToReverseIndex == INDEX_ALL )
- {
- return;
- }
- tokenTypesToReverseIndex.add( tokenType );
- }
-
- /** <summary>
- * Track the indicated token types in the reverse index. Set
- * to INDEX_ALL to track all token types.
- * </summary>
- */
- public void reverseIndex( HashSet<int> tokenTypes )
- {
- tokenTypesToReverseIndex = tokenTypes;
- }
-
- /** <summary>
- * Given a node pointer, return its index into the node stream.
- * This is not its Token stream index. If there is no reverse map
- * from node to stream index or the map does not contain entries
- * for node's token type, a linear search of entire stream is used.
- * </summary>
- *
- * <remarks>
- * Return -1 if exact node pointer not in stream.
- * </remarks>
- */
- public int getNodeIndex( object node )
- {
- //System.out.println("get "+node);
- if ( tokenTypeToStreamIndexesMap == null )
- {
- return getNodeIndexLinearly( node );
- }
- int tokenType = adaptor.getType( node );
- IList<int> indexes;
- if ( !tokenTypeToStreamIndexesMap.TryGetValue( tokenType, out indexes ) || indexes == null )
- {
- //System.out.println("found linearly; stream index = "+getNodeIndexLinearly(node));
- return getNodeIndexLinearly( node );
- }
- for ( int i = 0; i < indexes.size(); i++ )
- {
- int streamIndex = indexes[i];
- object n = get( streamIndex );
- if ( n == node )
- {
- //System.out.println("found in index; stream index = "+streamIndexI);
- return streamIndex; // found it!
- }
- }
- return -1;
- }
-#endif
-
- }
-}