在 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
;只有客户端代码可以做出该决定。
当使用 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
;只有客户端代码可以做出该决定。