当前位置: 首页 > 知识库问答 >
问题:

如何报告antlr4中的语法歧义

令狐烨烨
2023-03-14

根据antlr4书(第159页),并使用语法Ambig. g4,语法歧义可以通过以下方式报告:

grun Ambig stat -diagnostics

或等效代码形式:

parser.removeErrorListeners();
parser.addErrorListener(new DiagnosticErrorListener());
parser.getInterpreter().setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);

grun命令使用antlr-4.5.3为我正确报告歧义。但是当我使用代码表单时,我没有收到歧义报告。这是命令跟踪:

$ antlr4 Ambig.g4   # see the book's page.159 for the grammar
$ javac Ambig*.java
$ grun Ambig stat -diagnostics < in1.txt # in1.txt is as shown on page.159
    line 1:3 reportAttemptingFullContext d=0 (stat), input='f();'
    line 1:3 reportAmbiguity d=0 (stat): ambigAlts={1, 2}, input='f();'
$ javac TestA_Listener.java
$ java TestA_Listener < in1.txt   # exits silently

TestA_Listener.java代码如下:

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*; // for PredictionMode
import java.util.*;
public class TestA_Listener {
    public static void main(String[] args) throws Exception {
        ANTLRInputStream input = new ANTLRInputStream(System.in);
        AmbigLexer lexer = new AmbigLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        AmbigParser parser = new AmbigParser(tokens);
        parser.removeErrorListeners(); // remove ConsoleErrorListener
        parser.addErrorListener(new DiagnosticErrorListener());
        parser.getInterpreter().setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);
        parser.stat();
    }
}

有人能指出应该如何修改上述java代码以打印歧义报告吗?

为了完整起见,下面是代码 Ambig.g4 :

语法阿姆比格;

stat: expr ';'        // expression statement
    | ID '(' ')' ';'  // function call statement
    ;

expr: ID '(' ')'
    | INT
    ;

INT :   [0-9]+ ;
ID  :   [a-zA-Z]+ ;
WS  :   [ \t\r\n]+ -> skip ;

以下是1.txt中的输入文件:

f();

共有3个答案

傅乐湛
2023-03-14

以下代码将起作用

public static void main(String[] args) throws IOException {
    CharStream input = CharStreams.fromStream(System.in);
    AmbigLexer lexer = new AmbigLexer(input);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    AmbigParser parser = new AmbigParser(tokens);
    //parser.removeErrorListeners(); // remove ConsoleErrorListener
    parser.addErrorListener(new org.antlr.v4.runtime.DiagnosticErrorListener());  // add ours
    parser.getInterpreter().setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);
    parser.stat(); // parse as usual
}
鞠乐
2023-03-14

我等了好几天,让其他人发布他们的答案。终于经过几轮实验,我找到了答案:

应从上述代码中删除以下行。然后,我们得到与 grun 给出的相同的模糊性报告。

parser.removeErrorListeners(); // remove ConsoleErrorListener
颜举
2023-03-14

Antlr4是一个自上而下的解析器,因此对于给定的输入,解析匹配是明确的:

stat-

第二个统计alt是多余的,从未达到过,而不是模棱两可的。

为了解决明显的冗余,可以使用一个谓词:

stat: e=expr {isValidExpr($e)}? ';'   #exprStmt
    | ID '(' ')' ';'                  #funcStmt
    ;

isValidexpr为false时,将评估函数语句替代方案。

 类似资料:
  • 这个问题是一个类似问题的后续问题与java代码 - 如何报告语法歧义在antlr4。我正在尝试将该代码移植到c,但是我在使用antlr模板时遇到了一些编译错误。 c中的主程序如下: 我在上面运行了以下命令: 在调用getInterpreter时,我得到了以下编译错误: 你能告诉我如何修复上面的代码吗?我用的是antlr-4.6

  • 使用上面的测试数据运行ANTLR4测试平台,输出为 我可以看到第一个标记是ID的<4>,值为'rrv0' 我已经尝试重新安排lexer项目顺序。我还尝试通过在语法规则中显式匹配来使用隐式lexer项(而不是通过显式lexer项)。我也试着做火柴。那些对我来说并不成功。

  • 但我看不出这两个规则中有任何空字符串的可能性。还是我错了?这个代码有什么问题?

  • 在ANTLR4中,我有一个lexer规则,说我可以使用任何字符得到任何单词,但空格和换行符除外。其定义如下: 我还有一个lexer规则(定义在than WORD之前),用于进入EVAL模式: 我考虑的另一个选择是将“word”定义为${and}包围的文本以外的任何东西。但我不知道如何创建这样的lexer规则。 我该怎么解决?要区分评价和词?

  • 亲爱的Antlr4社区, 解析似乎很顺利: 但是,我得到以下错误消息: 错误是: [1]交换量子精确和正态分布的定义。但是交换在第一个输入中引入了一个错误: 因为在这种情况下,'6'只被视为一个正态分布,而不是一个全精确值。 [2]尝试为Quanteact(数量的花括号)创建一个上下文,这样lexer只在这个有限的上下文中提供Quanteact符号。但是我没有为此找到ANTLR4原语。 所以似乎什