Antlr4,如何报告特定的语法错误

Posted

技术标签:

【中文标题】Antlr4,如何报告特定的语法错误【英文标题】:Antlr4, How to report specific syntax error 【发布时间】:2013-09-27 06:54:09 【问题描述】:

我正在尝试使用 antlr4 为我的简单语法编写一些错误检查。

语法本身是由函数构造的。

FUNCTION hello (n)
    ......

FUNCTION main (n) 
    ......

我不确定它应该如何捕获特定错误,例如缺少函数名称缺少主函数

这是我的 ErrorListener 的样子

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

public class SimpleErrorListener extends BaseErrorListener 
    @Override
    public void syntaxError(Recognizer<?, ?> recognizer,
            Object offendingSymbol,
            int line,
            int charPositionInLine,
            String msg,
            RecognitionException e) 
        List<String> stack = ((Parser) recognizer.getRuleInvocationStack();
        Collections.reverse(stack);
        System.err.println("rule stack: " + stack);
        System.err.println("line" + line + ":" + 
            charPositionInLine + "at" + offendingSymbol + ": " + msg);
    

我还删除了控制台错误侦听器并添加了这个,但我不知道如何处理这些特定错误。 任何建议表示赞赏。非常感谢。

【问题讨论】:

【参考方案1】:

报告语义错误通常比报告语法错误容易得多。如果您想要自定义报告语法错误,则需要更改语法,使这些语法错误成为语义错误。例如,如果您当前像这样解析您的函数:

function : FUNCTION ID '(' ...

然后您可以使用以下规则之一将“缺少函数名称”变成语法错误:

function : FUNCTION ID? '(' ...

// alternate
function : FUNCTION (ID | /*missing function name; reported in listener*/) '(' ...

请注意,随着您添加越来越多的特殊情况,您的语法将很快变得难以管理。

【讨论】:

嗨,@280Z28,非常感谢!我尝试编辑为 ID?在我的语法中,但它没有报告。功能:“功能”ID?参数变量块; 然后我也试着看看它生成了什么msg到ErrorListener,我添加了if (msg.contains("expecting ID")) System.out.println("Error: function name undefined") ; --> 它确实报告了,虽然我不确定这是否是正确的方法:) 对于缺少主函数&重复函数名错误,我在语法中添加了一些谓词,例如将所有函数名添加到本地HashSet中,如果有重复则报错。但是,使用谓词可能会导致多条错误消息:如果我有 10 个函数并且它们都不是 main 函数,那么通过使用这种方法,它会打印 10 条错误消息,所以我认为这种方法不正确。 :( 再次感谢@280Z28 的提示,我想我已经通过在语法中使用谓词来实现它。我构造了一个函数 id 的 HashMap 并计算 id 的数量。在程序结束时,我将检查数字以及 HashMap 是否包含键“main”。 :)

以上是关于Antlr4,如何报告特定的语法错误的主要内容,如果未能解决你的问题,请参考以下文章

ANTLR4 词法分析器规则在 perl 语法上产生错误或冲突

ANTLR4 如何编写语法文件之语法结构

ANTLR4 如何编写语法文件之语法结构

ANTLR4 如何编写语法文件之语法词汇

ANTLR4 如何编写语法文件之语法词汇

ANTLR4 如何编写语法文件之语法解析器规则