[antlr-interest] Using own ASTLabelType and quantification

John B. Brodie jbb at acm.org
Tue Jan 12 10:09:41 PST 2010


On Tue, 2010-01-12 at 17:06 +0100, Olaf Keijsers wrote:
> Greetings,
> I am trying to make a treewalker for my grammar in order to check if it 
> contains nondeterminism. I would like to be able to set some properties for 
> every node I encounter, so I figured it would be a good idea to use my own 
> ASTLabelType.
> I have set "ASTLabelType=GrooveTree" in my options, and my grammar uses this 
> labeltype now, but I get the following exception when trying to use the 
> checker:
> java.lang.ClassCastException: org.antlr.runtime.tree.CommonTree cannot be 
> cast to groove.control.parse.GrooveTree
>  at 
> groove.control.parse.GCLDeterminismChecker.program(GCLDeterminismChecker.java:139)
> This line contains:
> root_0 = (GrooveTree)adaptor.nil();
> and is part of the program() method. Somehow I think this is a beginner's 
> error, but I cannot find the solution. I have tried to work around it by 
> using the default ASTLabelType and keeping a Map<CommonTree,Boolean> to keep 
> track of the property I would like, but this seems cumbersome. Could anyone 
> point me in a good direction?

You need to setup a tree adaptor so that the runtime knows how to
construct your nodes.

These are the things I had to do in order to get my own ASTLabelType,
note that my AST is called ExprAST -- so replace all occurrances of that
string below with yours. also note that I did this over a year ago using
an earlier version of ANTLR v3, so altho this still works, just re-ran
my tests, today's version of ANTLR may make some of my steps simpler
and/or entirely un-necessary... YMMV

1) in the grammar add the ASTLabelType= option (as you have already

2) create your new tree node class, ensuring that it extends CommonTree.
Here is my ExprAST (note that Type is also one of my classes):

//----begin ExprAST here....
import org.antlr.runtime.Token;
import org.antlr.runtime.tree.*;

public class ExprAST extends CommonTree {

   public Type type;

   public ExprAST() {
      type = null;

   public ExprAST(Token tok) {
      type = null;

   public ExprAST(ExprAST tree) {
      this.type = tree.type;

   public ExprAST(Token tok, Type type) {
      this.type = type;

   @Override public Tree dupNode() {
      return new ExprAST(this);

   @Override public String toString() {
      final String result;
      if (type==null) {
         result = super.toString();
      } else {
         result = String.format("%s[%s]",
      return result;
//----end ExprAST

3) copy org.antlr.runtime.tree.CommonErrorNode from the ANTLR run-time
sources. I called mine ExprASTErrorNode. Edit your copy so that is
extends your new tree node class rather than CommonTree.

4) create an instance of the adaptor class, i do this in my main:

//---begin adaptor code here...
   // Custom adaptor to create ExprAST node type
   private static final TreeAdaptor adaptor = new CommonTreeAdaptor() {
         @Override public Object create(Token payload) {
            return new ExprAST(payload);
         @Override public Object dupNode(Object old) {
            return (old==null)? null : ((ExprAST)old).dupNode();
         @Override public Object errorNode(TokenStream input,
                                           Token start, Token stop,
                                           RecognitionException e) {
            return new ExprASTErrorNode(input, start, stop, e);
//----end adaptor code.

5) call the parser's setAdaptor method with the above adaptor. I invoke
my parser with something similar to this:

//----begin parser invocation code here...
   ExprLexer lexer = new ExprLexer(...whatever....);
   CommonTokenStream tokens = new CommonTokenStream(lexer);
   ExprParser parser = new ExprParser(tokens);
   ExprParser.program_return p_result = parser.program();

   ast = p_result.tree;
//----end parser invocation code.

> Thanks!

Hope this helps...

More information about the antlr-interest mailing list