0
votes

I have developed small ANTLR grammar. which contains three files.

  • GLexer.g : lexer
  • GParser.g : parser of tpye AST
  • GWalker.g : tree parser

Also I have custom tree node GTree (extends CommonTree) and tree adopterGAdaptor ( extends CommonTreeAdaptor ). See sample code below.

lexer : GLexer.g

lexer grammar GLexer;
..
some lexer rule
..

**Parser GParser.g **

parser grammar GParser;
options {
    output          = AST;
    tokenVocab      = GLexer;
}
statement 
  : 
     rule* 
       -> ^(STATEMENTS rules* )
  ;

Tree Grammar : GWalker.g

tree grammar GWalker;
options {
  tokenVocab      = GParser;
  ASTLabelType    = GTree;
}
statement returns [String node]
  : 
     ^(STATEMENTS rules* )
  ;

Tree node

public class GTree extends CommonTree {
    public String text;
    public HashMap<String, Object> params = new HashMap<String, Object>();
    public GTree(Token t) {
        super(t);
        text = (t != null ? t.getText() : "[]");
    }
}

Tree Adopter

public class GTreeAdaptor extends CommonTreeAdaptor {
    public GTree create(Token payload) {
        GTree c = new GTree(payload);
        return c;
    }
}

ANTLR handler

try {
    //lexer splits input into tokens
    ANTLRStringStream input = new ANTLRStringStream("input String");
    TokenStream tokens = new CommonTokenStream( new GLexer( input ) );

    //parser generates abstract syntax tree
    GParser parser = new GParser(tokens);
    // Initiate Custom Adopter and set in parser
    TreeAdaptor adaptor = new GTreeAdaptor();
    parser.setTreeAdaptor(adaptor);
    GParser.statement_return st = parser.statement();

    CommonTreeNodeStream gTreeNodeStream = new CommonTreeNodeStream(
            st.getTree());

    GWalker gwalker = new GWalker(gTreeNodeStream);
    String returnValue = gwalker.statement();
    // print returnValue
} catch (RecognitionException e) {
    throw new IllegalStateException("Recognition exception is never thrown, only declared.");
}

When I run handle code above , it is giving casting exception. I know why this casting exception when all nodes in generated AST should be of type GTree as my custom tree adopter GTreeAdaptor will create only tree node of type GTree.

Help me understandinmg this and getting it resoved.

Casting exception

java.lang.ClassCastException: org.antlr.runtime.tree.CommonTree cannot be cast to driver.antlr.model.GTree       
at driver.antlr.lexerparser.GWalker.statement(GWalker.java:119)   
1

1 Answers

0
votes

I am able to resolved by adding method dupNode() in class GTreeAdaptor

Link : https://theantlrguy.atlassian.net/wiki/pages/viewpage.action?pageId=2687038

Changed Adopter Definition :

public class GTreeAdaptor extends CommonTreeAdaptor {
   public GTree create(Token payload) {
       GTree c = new GTree(payload);
       return c;
   }
   public Object dupNode(Object t) {
       if ( t==null ) return null;
       return create(((GTree )t).token);
   }
}