ANTLR4:getFirstChildWithType与ParseTree

ANTLR4:getFirstChildWithType与ParseTree,antlr4,Antlr4,我一直在玩ANTLR4,试图转换一个ANTLR3项目 我已经从来自官方存储库的ANLTR4语法生成了一个lexer、一个解析器和一个visitor类。在visitor中,我使用visitor提供的ctx调用我的一个类: myFunction(ctx.getChild(0)) 然后,在myFunction中,我想检索具有特定类型的第一个子项,因此我尝试执行以下操作: final ParseTree classNameElement = (ParseTree) ((Gram

我一直在玩ANTLR4,试图转换一个ANTLR3项目

我已经从来自官方存储库的ANLTR4语法生成了一个lexer、一个解析器和一个visitor类。在visitor中,我使用visitor提供的ctx调用我的一个类:

myFunction(ctx.getChild(0))
然后,在myFunction中,我想检索具有特定类型的第一个子项,因此我尝试执行以下操作:

final ParseTree classNameElement =
            (ParseTree) ((GrammarAST) node).getFirstChildWithType(MyParser.IDENTIFIER);
其中node是myFunction的参数,因此是ParseTree。getFirstChildWithType似乎仅在GrammarAST中可用,因此强制转换

我收到错误:无法转换为org.antlr.v4.tool.ast.GrammarAST

所以这可能是不可能的,我肯定错过了一些东西,但我想从ParseTree中找到第一个具有特定类型的子级

谢谢大家!

请注意,GrammarAST位于ANTLR工具层次结构中。对于生成的解析树,您应该专门处理运行时

要在解析树节点中搜索给定类型的子节点,请执行以下操作:

public ParseTree getFirstChildOfType(ParseTree node, int tokentype) {
    for (int idx = 0; idx < node.getChildCount(); idx++) {
        ParseTree child = node.getChild(idx);
        if (child instanceof TerminalNode) {
            Token token = (Token) child.getPayload();
            if (token.getType() == tokentype) {
                return child;
            }
        }
    }
    return null;
}
这将获得给定类型的第一个直接终端,即子终端。如果需要类型的绝对第一个,则需要递归到非终结节点


如果后者实际上是所需的函数,那么可以更好/更直接地使用parse tree walker来实现所需的总体目标。

谢谢。我不知道工具层次结构和使用生成的解析树之间的区别。顺便说一句,我注意到您使用getPayload来获取令牌,我试图使用以下难看的代码来获取它:int-typeChild=ParserRuleContext-child.getStart.getType;您认为它可以工作吗?TerminalNode只能包含一个令牌,因此getStart、getStop和getPayload是等效的,最后一个令牌的意图更加明确。