1

这只是一个例子

YACC 语法:

abc:ABC STRING NEWLINE

end:END

.

.

.lex 文件:

int lineno=1;

.

.

string [a-zA-Z]+

%%

ABC   {return ABC;}

END   {return END;}

[\n]  {lineno++;return NEWLINE;}

{string} {return STRING;}

%%

如果输入文件是,则每次出现 NEWLINE lineno 时都会增加:

ABC xyz

END

yacc 解析成功

如果输入文件是:

ABC 123

END

它显示第 1 行:语法错误

正如预期的那样

但如果输入文件是:

ABC

END

然后它显示line2 :syntax error

但是错误出现在第 1 行而不是第 2 行。

怎么做才能显示正确的行号?

4

2 回答 2

3

因为解析器直到从词法分析器接收到令牌才发现错误NEWLINE,到那时你已经增加了行号。

这实际上不是一个罕见的问题,在错误的行上显示错误。一个很好的例子是您忘记;在 C 源文件中的语句末尾添加分号 ( )。错误很可能在下一行。

编辑: Yacc 中的错误恢复处理。

Yacc 有一个特殊的终端符号error,可用于错误恢复。在您的情况下,它可以这样使用:

abc:ABC STRING NEWLINE
   |error NEWLINE
   ;

error您可以在和符号之间添加一段代码来打印错误消息,但它可能无论如何都不起作用,因为解析器在看到该符号NEWLINE之前并不知道有错误。NEWLINE

于 2012-10-31T07:16:54.113 回答
0

你可以保守地用你的语法错误信息来表达,比如“行号 %d 附近的语法错误”。

于 2012-10-31T12:53:56.090 回答