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

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

BYACCJ: How do I include line number in my error message?

问题

这是我的当前错误处理函数:

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

这是我在BYACC/J的主页上找到的默认错误函数。我找不到任何添加行号的方法。我的问题类似于这个问题。但是那个问题的解决方案在这里不起作用。

对于我的词法分析器,我正在使用一个JFlex文件。

英文:

This is my current error handling function:

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

This is the default error function I found on the BYACC/J homepage. I can't find any way to add the line number. My question is similar to this question. But the solution to it doesn't work here.

For my lexer I am using a JFlex file.

答案1

得分: 1

这与你链接的问题中提出的 bison/flex 解决方案并没有太大的区别。至少,原理是相同的。只是细节上有所不同。

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

因此,我们必须查阅 JFlex 的文档,以找出如何使其跟踪行号,然后在选项和声明部分找到以下内容:

  • %line

    打开行计数。整型成员变量 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 时,解析器已经请求了向前看的标记,该标记可能在错误的下一行,甚至与错误之间相隔数行注释。 (当错误是缺少语句终止符时,这个问题经常会出现。)但这是一个很好的开始。

英文:

It's not that different from the bison/flex solution proposed in the question you link. At least, the principle is the same. Only the details differ.

The key fact is that it is the scanner, not the parser, which needs to count lines, because it is the scanner which converts the input text into tokens. The parser knows nothing about the original text; it just receives a sequence of nicely-processed tokens.

So we have to scour the documentation for JFlex to figure out how to get it to track line numbers, and then we find the following in the section on options and declarations:

> * %line
>
> Turns line counting on. The int member variable yyline contains the number of lines (starting with 0) from the beginning of input to the beginning of the current token.

The JFlex manual doesn't mention that yyline is a private member variable, so in order to get at it from the parser you need to add something like the following to your JFlex file:

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

}

You can then add a call to GetLine in the error function:

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

That will sometimes produce confusing error messages, because by the time yyerror is called, the parser has already requested the lookahead token, which may be on the line following the error or even separated from the error by several lines of comments. (This problem often shows up when the error is a missing statement terminator.) But it's a good start.

huangapple
  • 本文由 发表于 2020年4月10日 02:21:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/61127717.html
匿名

发表评论

匿名网友

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

确定