Jordi
Jordi

Reputation: 23247

there's no way to visit a GrammarRootAST

I've been trying for ages to create a visitor that implements GrammarASTVisitor.

I'm loading the grammar rules on a Grammar object:

final Grammar g = Grammar.load("....dslGrammar.g4");

After that, I'm trying to visit the grammar's AST using my implementation of GrammarASTVisitor interface:

public class DSLGrammarVisitor implements GrammarASTVisitor {

    @Override
    public Object visit(GrammarAST node)
    {   

    }

    @Override
    public Object visit(GrammarRootAST node)
    {
        return null;
    }

    @Override
    public Object visit(RuleAST node)
    {
        return null;
    }

    @Override
    public Object visit(BlockAST node)
    {
        return null;
    }

    @Override
    public Object visit(OptionalBlockAST node)
    {
        return null;
    }

    @Override
    public Object visit(PlusBlockAST node)
    {
        return null;
    }

    @Override
    public Object visit(StarBlockAST node)
    {   
        return null;
    }

    @Override
    public Object visit(AltAST node)
    {
        return null;
    }

    @Override
    public Object visit(NotAST node)
    {
        return null;
    }

    @Override
    public Object visit(PredAST node)
    {
        return null;
    }

    @Override
    public Object visit(RangeAST node)
    {
        return null;
    }

    @Override
    public Object visit(SetAST node)
    {
        return null;
    }

    @Override
    public Object visit(RuleRefAST node)
    {
        return null;
    }

    @Override
    public Object visit(TerminalAST node)
    {
        return null;
    }
}

So, after the grammar is loaded from the file, I do:

GrammarASTVisitor v = new GrammarASTVisitorImpl();
g.ast.visit(v)

After that, visit(grammarRootAST) method is performed. However, I've just realized I'm not quite been able to figure out how on earth visit the children. I'm not quite figure out how to get the children AST nodes keeping its type.

I've tried with node.getChildren(), however it returns a List<? extends Object>, so there is no visit(Object) method on GrammarASTVisitor implementing a visit(Object).

I've tried with node.getChildrenAsArray() also, however, every item is a GrammarAST node instead of a RuleAST, SetAST, TerminalAST and so on...

Any ideas?

Upvotes: 0

Views: 90

Answers (1)

Aykut Kllic
Aykut Kllic

Reputation: 927

Unfortunately Java does not support double dispatching. You have to manually override the visit(GrammarAST node) which switches by the class of the node and dispatches to the appropriate method. Actually they should given some abstract class which does this but it does not exist.

So basically something like the code below (written in xtend but you can convert it to java) should do the trick:

GrammarASTVisitor() {
override visit(GrammarAST node) {
    node.children?.forEach[
        switch(it) {
            case RuleAST: visit(it as RuleAST)
            case BlockAST: visit(it as BlockAST)
            case OptionalBlockAST: visit(it as OptionalBlockAST)
            case PlusBlockAST: visit(it as PlusBlockAST)
            case StarBlockAST: visit(it as StarBlockAST)
            case AltAST: visit(it as AltAST)
            case NotAST: visit(it as NotAST)
            case PredAST: visit(it as PredAST)
            case RangeAST: visit(it as RangeAST)
            case SetAST: visit(it as SetAST)
            case RuleRefAST: visit(it as RuleRefAST)
            case TerminalAST: visit(it as TerminalAST)
            default: visit(it as GrammarAST)
        }
    ]
    node
}

override visit(GrammarRootAST node) {
    node.children?.forEach[this.visit(it as GrammarAST)]
    node
}

...

Upvotes: 1

Related Questions