在 Lex 中处理无效标记

Handling invalid tokens in Lex

当使用 Lex 扫描无效的标记或字符时,是否应该返回一个特殊的错误代码,或者我应该只使用 EXIT_FAILURE 调用退出函数?

通常,您不应尝试在词法扫描器中检测错误。简单地依赖回退规则要简单得多

.     return *yytext;

来处理 single-character 运算符标记和错误。 Bison/yacc 会将任何未知的标记类型视为错误,这将允许 error-handling 集中在解析器组件中。

有时无法避免注意到错误。例如,在像 C 这样的语言中,其字符串文字不能跨越多个源代码行,如果要尝试错误恢复,则词法扫描器必须检测到未闭合的引号。 (如果您不打算尝试错误恢复,您也可以让回退规则将不匹配的引号作为单个 '"' 标记处理,如上所述,但是如果您打算尝试错误恢复,那会更好继续下一行而不是下一个字符。)

在这种情况下,仍然可以使用一些其他未使用的单字符标记。或者您可以在 bison/flex 文件中定义一个特殊的 bad-token 标记,这将具有几乎完全相同的效果。

["]([^\n\]|\(.|\n))*["]    { return STRING; }
["]([^\n\]|\(.|\n))*       { return '"'; }

["]([^\n\]|\(.|\n))*["]    { return STRING; }
["]([^\n\]|\(.|\n))*       { return BAD_STRING; }

即使您不打算尝试错误恢复(目前),词法分析器也不应自行调用 exit。这将阻止解析器产生错误消息或返回错误代码。像任何库函数一样,即使是解析器也不应该调用 exit;只有客户端代码可以做出该决定。