Better JJTree Visitors

26 Oct 2007

JavaCC comes with a built in tree builder, JJTree. One of the nice bits about JJTree is that it will generate a visitor implementation so you can easily traverse the abstract syntax tree. However, the interface that JJTree generates looks like this:

public interface FooVisitor {
  public Object visit(SimpleNode node, Object data);
  public Object visit(ASTBar node, Object data);
}

Since that second parameter is an Object, you're always downcasting if you want to use it. For example, if you're passing around a Map, you'll need to do something like this in your visitor:

public class MyVisitor extends MyVisitorAdapter {
  public Object visit(ASTBar node, Object data) {
    Map myMap = (Map)data;
    // do stuff with the Map
  }
}

But thanks to Paul Cager, JJTree has a new VISITOR_DATA_TYPE option. Just set it like this:

options {
  VISITOR=true;
  MULTI=true;
  VISITOR_DATA_TYPE="java.util.Map";
}

With this option in place, the generated visitor interface looks like this:

public interface FooVisitor {
  public Object visit(SimpleNode node, java.util.Map data);
  public Object visit(ASTBar node, java.util.Map data);
}

And now your visitor implementation can look like this - no cast necessary!

public class MyVisitor extends MyVisitorAdapter {
  public Object visit(ASTBar node, java.util.Map data) {
    // do stuff with the Map
  }
}

Note that you'll want to declare a fully-qualified type, otherwise you'll need to go back and fill in the import statements. So it's more readable, more type-safe, and it probably yields a small runtime performance improvement due to the eliminated cast. You can grab a javacc.jar built from CVS here if you want to give it a whirl. Props to Paul for this and his other recent bug fixes!

Using JavaCC or JJTree? Get the JavaCC book!