/** <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>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; }
/** <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; }
/** <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; }