Reputation: 23247
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
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