代码之家  ›  专栏  ›  技术社区  ›  Hari

BYACCJ:如何在错误消息中包含行号?

  •  0
  • Hari  · 技术社区  · 4 年前

    这是我当前的错误处理功能:

    public void yyerror(String error) {
        System.err.println("Error: "+ error);
    }
    

    这是我在BYACC/J上发现的默认错误函数 homepage 。我找不到任何方法来添加行号。我的问题与此类似 question 。但解决这个问题的办法在这里行不通。

    对于我的lexer,我使用的是JFlex文件。

    0 回复  |  直到 4 年前
        1
  •  1
  •   rici    4 年前

    这与您链接的问题中提出的bison/flex解决方案没有太大不同。至少,原则是一样的。只是细节不同。

    关键的事实是,需要计数行的是扫描仪,而不是解析器,因为扫描仪将输入文本转换为标记。解析器对原始文本一无所知;它只接收一系列处理良好的令牌。

    因此,我们必须在文档中搜索JFlex,找出如何让它跟踪行号,然后在选项和声明部分找到以下内容:

    • %line

      启用行计数。int成员变量 yyline 包含从输入开始到当前标记开始的行数(从0开始)。

    JFlex手册没有提到这一点 yyline 是一个私有成员变量,因此为了从解析器中获取它,您需要在JFlex文件中添加以下内容:

    %line
    {
        public int GetLine() { return yyline + 1; }
        // ...
    
    }
    

    然后,您可以向添加呼叫 GetLine 在错误函数中:

    public void yyerror (String error) {
      System.err.println ("Error at line " + lexer.GetLine() + ": " + error);
    }
    

    这有时会产生令人困惑的错误消息,因为到那时 yyerror 当调用时,解析器已经请求了先行标记,该标记可能位于错误后面的行上,甚至与错误用几行注释隔开。(当错误是缺少语句终止符时,这个问题经常出现。)但这是一个良好的开端。