[antlr-interest] Re: matching an AST segment with Java 5 (fixed)

John Green greenj at ix.netcom.com
Wed Jul 26 10:25:44 PDT 2006


OK, now it actually matches the node types, rather than just the tree shape. Sigh.

Here's a quick test mTest(), which calls a sample usage m(), which calls match().


private static final int PLUS = 20;
private static final int NUMBER = 30;
void mTest() {
	AST p1 = new CommonAST(); p1.setType(PLUS);
	AST p2 = new CommonAST(); p2.setType(PLUS);
	AST n1 = new CommonAST(); n1.setType(NUMBER); n1.setText("1");
	AST n2 = new CommonAST(); n2.setType(NUMBER); n2.setText("2");
	AST n3 = new CommonAST(); n3.setType(NUMBER); n3.setText("3");
	p1.setFirstChild(p2);
	p2.setFirstChild(n1);
	n1.setNextSibling(n2);
	p2.setNextSibling(n3);
	m(p1);
}

void m(AST currentNode) {
	// Looking for: #(PLUS #(PLUS NUMBER NUMBER) NUMBER)
	// and if found, print the text of the first NUMBER node.
	Object [] match = match(
			currentNode
			, new Object[]{PLUS, new Object[]{PLUS, NUMBER, NUMBER}, NUMBER}
			);
	if (match!=null) {
		System.out.println(((AST)((Object[])match[1])[1]).getText());
	} else {
		System.out.println("No match");
	}
}

/** Match an AST to a (possibly nested) array of integer node types.
 * <p>
 * Matches AST node types to the integer values in the input Object[].
 * The first integer value in the Object[] is expected to match the
 * head node of an AST branch. Multiple Object[] may be nested, to
 * describe the shape of the AST to be matched.
 * <p>
 * The input Object[] may describe just the beginning portion of the
 * AST. The Object[] is not expected to describe the entire AST in
 * order to match.
 * @author John Green (www.joanju.com)
 * @param ast Parent node of the AST branch to match.
 * @param objarray Possibly nested Object[] of integer node types.
 * @return An Object[] matching the shape of the input Object[], but
 * with AST node references rather than integer node types. Null if
 * the AST does not match the input Object[].
 */
public static Object[] match(AST ast, Object[] objarray) {
	if	(	ast==null
		||	ast.getType() != (Integer)objarray[0]	
		) return null;
	Object[] ret = new Object[objarray.length];
	ret[0] = ast;
	AST currAST = ast.getFirstChild();
	for (int count = 1; count < objarray.length; count++) {
		if (currAST==null) return null;
		if (objarray[count] instanceof Object[]) {
			Object[] nonterminal = match(currAST, (Object[])objarray[count]);
			if (nonterminal==null) return null;
			ret[count] = nonterminal;
		} else {
			if (currAST.getType() != (Integer)objarray[count]) return null;
			ret[count] = currAST;
		}
		currAST = currAST.getNextSibling();
	}
	return ret;
}


John Green wrote:
> With Java 5 and autoboxing, I could use nested Object arrays as a quick 
> and dirty description for a segment of an AST. Has anybody done this 
> sort of thing before? Specifically, I wonder if match(AST, Object[]) as 
> per my "usage example" below has been written and exists in any of the 
> Antlr or other libraries.
> 
> It'll be easy to write, I'd just rather use existing libraries.  :)
> 
> Cheers,
> John
> www.joanju.com
> 


More information about the antlr-interest mailing list