Search code examples
antlrantlr4parse-tree

how to modify ANTLR4 ParseTree?


I want to modify Java SytaxTree in a way of prefixing variables with some prefix (using ANTLR4)

Example myVar++ -> prefix.myVar++

expression
 |-- expression
 |    |-- primary
 |         |-- myVar
 |-- ++

// ->

expression
 |-- expression
 |     |-- expression
 |          |-- primary
 |               |-- prefix
 |     |-- .
 |     |-- myVar
 |-- ++

Assuming my function gets SyntaxTree and returns modified SyntaxTree, I can't use simple TokenStreamRewriter as it produces only String, doesn't it? Also Java8 grammar is given and may not be modified.

I need to modify the tree itself (if it is even possible).

My Skeleton is like: (in Scala but it is almost same as Java)

class MyVisitor extends Java8BaseVisitor[Unit] {
    // ...
    override def visitPrimary(ctx: Java8Parser.PrimaryContext) = {
        if (isVariable(ctx)) {    // this condition works
            // TODO
        }
    }
}

I struggle with implementation of // TODO. I tried using addChild and getParent but with no success and throwing Nullpointers.

I guess I don't understand construction/modification of ParseTree at all as I found no suitable source.

Could you give me a hint or some sources?

According to github issue and similar question it appears to be unsupported - what other solutions would you recommend? I think about TokenStreamRewriter and getText and then parsing again (into new ParseTree) but this could be very ineffective (I am about to prefix more than once).


Solution

  • If you want to just alter the text of the variable, I'd do this:

    There is

    1. the CommonToken class that implements IWritableToken class

    2. or you create your own writable Token class

    cast the IToken interface to this class and set the token text (e.g. prepend the prefix).

    This modifies the parse tree in place.

    If you want to add a different token in front of the variable, this doesn't work.