这只是一个例子
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行。
可以做什么以便显示正确的行号?
答案 0 :(得分:3)
因为解析器在从词法分析器收到NEWLINE
令牌之前找不到错误,所以此时你已经增加了行号。
这实际上不是一个不常见的问题,在错误的行上显示错误。一个很好的例子,如果你忘了在C源文件的语句末尾加一个分号(;
)。错误很可能出现在下一行。
编辑:Yacc中的错误恢复处理。
Yacc有一个特殊的终端符号error
,可用于错误恢复。在您的情况下,它可以像这样使用:
abc:ABC STRING NEWLINE
|error NEWLINE
;
您可以在error
和NEWLINE
符号之间添加一段代码来打印错误消息,但它可能无法正常工作,因为解析器不知道有错误,直到它有无论如何都看到了NEWLINE
符号。
答案 1 :(得分:0)
您可以保守地说出语法错误消息,例如“行号%d附近的语法错误”。