如何正确实现ANTLR4访问者

时间:2016-12-13 21:43:31

标签: java antlr antlr4

我正在尝试为玩具语言实现解析器。

我已经编写了语法,但是当我尝试从CST创建AST时遇到了问题。

我定义了一个继承自MyParserVisitor<ASTNode>的类,其中ASTNode是一个虚拟类,我的类estructure中的每个类都从该类继承。

现在,我的语法的两条规则如下:

program:
    funcDecl* expr
;
expr:
    constant                                     # constExpr
|   identifier                                   # idExpr
;

其中funcDeclconstantidentifier是终端规则。

当我尝试为program实现访问者时,每当我调用函数visit时,我都必须将结果转换为正确的类型。例如:

@Override
public Program visitProgram(fopplParser.ProgramContext ctx){
    // Rule: funcDecl* expr
    List<FuncDecl> funcs = new LinkedList<FuncDecl>();
    for(fopplParser.FuncDeclContext f : ctx.funcDecl())
        funcs.add((FuncDecl) visit(f));

    Expr expr = (Expr)visit(ctx.expr());
    return new Program(funcs, expr);
}

是否有可能以某种方式省略所有这些铸件?我觉得我在这里做错了。

对于FuncDecl,我可以将该行更改为     funcs.add(visitFuncDecl(f)); 并使用以下签名实现visitFuncDecl     pubic FuncDecl visitFuncDecl(fopplParser.FuncDeclContext ctx); 但我不能用表达式做到这一点,因为没有visitExpr函数,而是两个函数,即visitConstExprvisitIdExpr

此外,如果我有这样的规则     idList: identifier* 在这种情况下,我无法返回List<Identifier>。我应该创建一个只是List<Identifier>的包装器的类,还是应该直接使我的Visitor类继承自MyParserVisitor<Object>

1 个答案:

答案 0 :(得分:1)

我认为你混淆了ANTLR访客类的含义和你走解析树的意图。 ANTLR访客类用于评估。它可以参数化以返回给定的类作为访问节点的结果(例如,当您计算表达式时的数学值)。对于步行,解析树使用解析树监听器。然后,您可以覆盖enterXXX和exitXXX函数,并构建符号表或任何您喜欢的符号表。