1	package antlr;
2	
3	import antlr.collections.AST;
4	/**
5	 */
6	public class ASTIterator {
7		protected AST cursor = null;
8		protected AST original = null;
9	
10	
11		public ASTIterator(AST t) {
12			original = cursor = t;
13		}
14	/** Is 'sub' a subtree of 't' beginning at the root? */
15	public boolean isSubtree(AST t, AST sub) {
16		AST sibling;
17	
18		// the empty tree is always a subset of any tree.
19		if ( sub==null ) {
20			return true;
21		}
22		
23		// if the tree is empty, return true if the subtree template is too. 	
24		if ( t==null ) {
25			if ( sub!=null ) return false;
26			return true;
27		}	
28	
29		// Otherwise, start walking sibling lists.  First mismatch, return false.
30		for (sibling=t;
31			  sibling!=null&&sub!=null;
32			  sibling=sibling.getNextSibling(), sub=sub.getNextSibling())
33		{
34			// as a quick optimization, check roots first.
35			if ( sibling.getType() != sub.getType() ) return false;
36			// if roots match, do full match test on children.
37			if ( sibling.getFirstChild()!=null ) {
38				if ( !isSubtree(sibling.getFirstChild(), sub.getFirstChild()) ) return false;
39			}	
40		}
41		return true;
42	}
43		/** Find the next subtree with structure and token types equal to
44		 * those of 'template'.
45		 */
46		public AST next(AST template) {
47			AST t = null;
48			AST sibling = null;
49			
50			if ( cursor==null ) {	// do nothing if no tree to work on
51				return null;
52			}
53			
54			// Start walking sibling list looking for subtree matches.
55			for ( ; cursor!=null; cursor=cursor.getNextSibling())
56			{
57				// as a quick optimization, check roots first.
58				if ( cursor.getType() == template.getType() ) {
59					// if roots match, do full match test on children.
60					if ( cursor.getFirstChild()!=null ) {
61						if ( isSubtree(cursor.getFirstChild(), template.getFirstChild()) ) {
62							return cursor;
63						}	
64					}
65				}	
66			}
67			return t;	
68		}
69	}
70