yacc在错误的位置显示语法错误

时间:2012-10-31 06:00:33

标签: yacc lex

这只是一个例子

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

它显示了line1:语法错误

这是预期的

但如果输入文件是:

ABC

END

然后显示 line2 :语法错误

然而错误在第1行而非第2行。

可以做什么以便显示正确的行号?

2 个答案:

答案 0 :(得分:3)

因为解析器在从词法分析器收到NEWLINE令牌之前找不到错误,所以此时你已经增加了行号。

这实际上不是一个不常见的问题,在错误的行上显示错误。一个很好的例子,如果你忘了在C源文件的语句末尾加一个分号(;)。错误很可能出现在下一行。

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

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

abc:ABC STRING NEWLINE
   |error NEWLINE
   ;

您可以在errorNEWLINE符号之间添加一段代码来打印错误消息,但它可能无法正常工作,因为解析器不知道有错误,直到它有无论如何都看到了NEWLINE符号。

答案 1 :(得分:0)

您可以保守地说出语法错误消息,例如“行号%d附近的语法错误”。