ANTLR 4 解析问题:在 TestRig 中有效,但在 Java 中无效

huangapple go评论72阅读模式
英文:

ANTLR 4 Parsing Problems: Works with TestRig But Not in 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());
    }
}
英文:

I'm writing a lambda calculus interpreter in Java using ANTLR 4.8. Parsing works as expected when using the TestRun tool. However, inside my Java code, I end up with empty parsing lists whenever I parse lambda expressions with the abstractionExpr rule in them. I don't understand the discrepancy between TestRun and my Java code.

Here is an example using TestRun:

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

And here is the output of my Java program when parsing the same expression:

$ java LambdaCalculusInterpreter
Parse tree output: []

Below is my grammar:

grammar LambdaExpr;

Var         : [a-z]+ ;

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


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

Below is my Java code:

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());
}

答案1

得分: 1

toString是从org.antlr.v4.runtime.RuleContext继承而来的,其实现与您的期望不同。您将需要调用toStringTree(...)

ParseTree tree = parser.lexpr();
System.out.println("解析树输出:" + tree.toStringTree(parser));

这将输出:

解析树输出:(lexpr ^ x . (lexpr y))

还请确保您使用的是org.antlr.v4.runtime.tree.ParseTree,而不是在您的类路径中可能存在的其他ParseTree类(这可能不是情况)。

英文:

The toString is inherited from org.antlr.v4.runtime.RuleContext, which has a different implementation than you expect. You'll want to call toStringTree(...):

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

which prints:

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

Also make sure you're using org.antlr.v4.runtime.tree.ParseTree, not some other ParseTree class that happens to be present in your classpath (which might not be the case).

huangapple
  • 本文由 发表于 2020年9月1日 05:56:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/63678691.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定