ANTLR 4解析问题:可用于TestRig,但不能在Java中使用

问题描述

我正在使用ANTLR 4.8用Java编写lambda演算解释器。使用TestRun工具时,解析可以按预期进行。但是,在我的Java代码中,每当我使用其中的abstractionExpr规则解析lambda表达式时,最终都会得到空的解析列表。我不明白TestRun和我的Java代码间的差异。

以下是使用TestRun的示例:

$ grun LambdaExpr lexpr -tree
^x.y
(lexpr ^ x . (lexpr y))

这是我的Java程序在解析相同表达式时的输出

$ java LambdaCalculusInterpreter
Parse tree output: []

下面是我的语法:

grammar LambdaExpr;

Var         : [a-z]+ ;

WS          : [ \t\r\n]+ -> skip ;


lexpr       : Var                   # varExpr
            | '^' Var '.' lexpr     # abstractionExpr
            | '(' lexpr lexpr ')'   # applicationExpr
            ;

下面是我的Java代码

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;

public class LambdaCalculusInterpreter {
    public static void main(String[] args) {
    CharStream inputStream = CharStreams.fromString("^x.y");
    LambdaExprLexer lexer = new LambdaExprLexer(inputStream);
    CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);
    LambdaExprParser parser = new LambdaExprParser(commonTokenStream);

    ParseTree tree = parser.lexpr();
    System.out.println("Parse tree output: " + tree.toString());
}

解决方法

toString继承自org.antlr.v4.runtime.RuleContext,其实现与您期望的实现不同。您将要致电toStringTree(...)

ParseTree tree = parser.lexpr();
System.out.println("Parse tree output: " + tree.toStringTree(parser));

打印:

Parse tree output: (lexpr ^ x . (lexpr y))

还要确保您使用的是org.antlr.v4.runtime.tree.ParseTree,而不是您的类路径中恰巧存在的其他一些ParseTree类(可能并非如此)。