我有以下规则:
functionInv
: NAME paramInvList #functionInvStmt
;
paramInvList
: BRO BRC
| BRO expression (',' expression )* BRC
;
和相应的 Ast 类:
public class FunctionInvocationExpr implements Ast {
private final String target;
private final List<Ast> arguments;
public FunctionInvocationExpr(String target, List<Ast> arguments) {
this.target = target;
this.arguments = arguments;
}
@Override
public <T> T accept(AstVisitor<T> visitor) {
return visitor.visitFunctionInvocationExpr(this);
}
}
问题是,我如何从一个到另一个。谷歌搜索根本没有帮助。有人可以指出我正确的方向吗? 我使用访客代码生成。
生成词法分析和解析器类时,需要添加参数-visitor
,以便 ANTLR 为您生成一些默认访问者:
java -jar antlr-4.8-complete.jar -visitor Test.g4
这将为您创建一个TestBaseVisitor<T>
类:
public class TestBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements TestVisitor<T> {
@Override
public T visitFunctionInvStmt(TestParser.FunctionInvStmtContext ctx) { return visitChildren(ctx); }
@Override
public T visitParamInvList(TestParser.ParamInvListContext ctx) { return visitChildren(ctx); }
@Override
public T visitExpression(TestParser.ExpressionContext ctx) { return visitChildren(ctx); }
// ...
}
您可以扩展并使其返回您自己的Ast
节点:
class AstVisitorBuilder extends TestBaseVisitor<Ast> {
@Override
public Ast visitFunctionInvStmt(TestParser.FunctionInvStmtContext ctx) {
final String functionName = ctx.NAME().getText();
final List<Ast> arguments = new ArrayList<>();
if (ctx.paramInvList().expression() != null) {
for (TestParser.ExpressionContext expression : ctx.paramInvList().expression()) {
arguments.add(this.visitExpression(expression));
}
}
return new FunctionInvocationExpr(functionName, arguments);
}
@Override
public Ast visitExpression(TestParser.ExpressionContext ctx) {
return null; // TODO return your expression AST node here
}
// ...
}
调用此操作可以按如下方式完成:
TestLexer lexer = new TestLexer(new ANTLRInputStream("your source code"));
TestParser parser = new TestParser(new CommonTokenStream(lexer));
Ast ast = new AstVisitorBuilder().visit(parser.functionInv());
// ...