Java ANTLR4 AST创建-如何创建AstVistor

Java ANTLR4 AST创建-如何创建AstVistor,java,antlr4,abstract-syntax-tree,Java,Antlr4,Abstract Syntax Tree,在这个SO问题的帮助下,我能够创建AST节点,但我仍在编写BuildAstVisitor,如公认答案的示例所示 我的语法是这样开始的: mini: (constDecl | varDef | funcDecl | funcDef)* ; 我既不能给块分配标签,也不能给不是集合的块分配标签,我不知道如何访问下一个节点 public Expr visitMini(MiniCppParser.MiniContext ctx) { return visitConstDecl(ctx.const

在这个SO问题的帮助下,我能够创建AST节点,但我仍在编写BuildAstVisitor,如公认答案的示例所示

我的语法是这样开始的:

mini: (constDecl | varDef | funcDecl | funcDef)* ;
我既不能给块分配标签,也不能给不是集合的块分配标签,我不知道如何访问下一个节点

public Expr visitMini(MiniCppParser.MiniContext ctx) {
    return visitConstDecl(ctx.constDecl());
}
上面的代码有以下问题:我不知道如何确定它是constDecl、varDef还是任何其他选项,ctx.constDecl返回一个列表,而visitConstDecl函数只需要一个元素

编辑:

更多语法规则:

mini: (constDecl | varDef | funcDecl | funcDef)* ;

//--------------------------------------------------

constDecl:   'const' type ident=ID init ';' ;
init:        '=' ( value=BOOLEAN | sign=('+' | '-')? value=NUMBER ) ;
// ...

//--------------------------------------------------

OP_ADD: '+';
OP_SUB: '-';
OP_MUL: '*';
OP_DIV: '/';
OP_MOD: '%';

BOOLEAN        : 'true' | 'false' ;
NUMBER         : '-'? INT ;
fragment INT   : '0' | [1-9] [0-9]* ;
ID             : [a-zA-Z]+ ;
// ...
我仍然不能完全确定如何实现BuildAstVisitor。我现在有了一些大致如下的东西,但在我看来肯定不对

@Override
public Expr visitMini(MiniCppParser.MiniContext ctx) {
  for (MiniCppParser.ConstDeclContext constDeclCtx : ctx.constDecl()) {
    visit(constDeclCtx);
  }
  return null;
}

@Override
public Expr visitConstDecl(MiniCppParser.ConstDeclContext ctx) {
  visit(ctx.type());
  return visit(ctx.init());
}

如果要获取单个子规则,请为它们实现visitXXX函数visitconstecl、visitVarDef等,而不是visitMini函数。只有在输入中确实存在匹配项时才会调用它们。因此,您无需对发生情况进行任何检查。

您在表达式周围放置了一个Kleene星号*,这意味着每个项目可以发生任意次数,或者根本不发生。这就是为什么ctx.constDecl返回一个列表,其中包含所有constDecl子节点。只能将标签指定给顶级可选元素,即规则:foo labelA | bar labelB;,这就是ANTLR拒绝的原因。我真的不知道这里的解决方案是什么,因为我不知道您到底想做什么,但是您要么删除该星形以获得恰好一个要匹配的分支,要么访问每个子节点而不仅仅是第一个。如果我要访问每个子节点,那么visitMini函数会返回什么?在您的示例中,您不必访问节点列表。如果我实现了访问者,我不必亲自访问节点吗?我认为这样做的原因是我可以自己遍历CST,从中构建AST。因此,我确实需要实现visitMini函数,因为这将是输入的第一条规则。对不起,如果我弄错了!我发现了我的错误:我是在实现访问者,而不是扩展XBaseVisitor。