我如何指示解析器不要继续处理未终止的注释?
How can I instruct the parser not to continue processing unterminated comments?
我正在努力改进编译器分配的错误报告。我正在使用以下代码在 Flex 中处理未终止的注释:
<INITIAL>"/*" {BEGIN(COMMENT);}
<COMMENT>"*/" {BEGIN(INITIAL);}
<COMMENT>([^*]|\n)+ {}
<COMMENT><<EOF>> {yyerror("UNTERMINATED COMMENT"); BEGIN(INITIAL);}
问题在于解析器也在打印其错误消息:
$ ./comp tests/comments.cf
ERROR: UNTERMINATED COMMENT: 27
ERROR: syntax error: 27
如何让解析器停止工作?在 BEGIN(INITIAL)
后加一个 exit
给了我想要的,但它似乎不是处理它的方法。
你当然应该 return 0(或其他)来自 <<EOF>>
动作,因为如果你不这样做,词法分析器将尝试继续扫描(这是未定义的行为;扫描器应该在发出 EOF 信号后不要继续读取输入,除非它已经安排了一个新的输入缓冲区。)
很可能未终止的注释会导致语法错误,因为程序的结尾很可能已被吞没在注释中。如果你不想报告这个错误,那么你可以简单地设置一个标志,yyerror
在打印错误消息之前检查它。在这种简单的情况下,不需要重置该标志,因为未终止的注释错误只能发生在输入结束时,并且此时不可能进行错误恢复。
Bison 本身有一种机制,通过在报告语法错误后抑制 "syntax error" 对三个标记的 yyerror
调用来减少虚假错误报告。从解析器操作中只能有限地访问此功能,但不能从解析器外部访问,因此无法从扫描器操作中启用它。
如果您想要一个在扫描器和解析器之间具有更清晰接口的解决方案,您可以考虑以下可能性:
在您的词法分析器中,当检测到未终止的注释时,return 一个未使用的标记,比如 UNTERMINATED_COMMENT。
当解析器接收到 UNTERMINATED_COMMENT 标记时,它将立即发出语法错误信号(或几乎立即发出信号。在某些情况下,它甚至可能在检查前瞻性内容之前执行一些归约token 是。)当调用 yyerror
时,yychar
全局变量的值将是先行标记,因此它将是 UNTERMINATED_COMMENT
; yyerror
可以使用此事实生成更精确的错误消息,而不是通用的 "syntax error".
此时立即终止解析很重要,因为再次调用扫描器将是未定义的行为。这可以通过在 yyerror
函数中将 yychar
设置为 YYEOF
来完成。 (另一种方法是在 rhs 中包含带有 UNTERMINATED_COMMENT
的错误产生式,其操作为 YYABORT。)
我正在努力改进编译器分配的错误报告。我正在使用以下代码在 Flex 中处理未终止的注释:
<INITIAL>"/*" {BEGIN(COMMENT);}
<COMMENT>"*/" {BEGIN(INITIAL);}
<COMMENT>([^*]|\n)+ {}
<COMMENT><<EOF>> {yyerror("UNTERMINATED COMMENT"); BEGIN(INITIAL);}
问题在于解析器也在打印其错误消息:
$ ./comp tests/comments.cf
ERROR: UNTERMINATED COMMENT: 27
ERROR: syntax error: 27
如何让解析器停止工作?在 BEGIN(INITIAL)
后加一个 exit
给了我想要的,但它似乎不是处理它的方法。
你当然应该 return 0(或其他)来自 <<EOF>>
动作,因为如果你不这样做,词法分析器将尝试继续扫描(这是未定义的行为;扫描器应该在发出 EOF 信号后不要继续读取输入,除非它已经安排了一个新的输入缓冲区。)
很可能未终止的注释会导致语法错误,因为程序的结尾很可能已被吞没在注释中。如果你不想报告这个错误,那么你可以简单地设置一个标志,yyerror
在打印错误消息之前检查它。在这种简单的情况下,不需要重置该标志,因为未终止的注释错误只能发生在输入结束时,并且此时不可能进行错误恢复。
Bison 本身有一种机制,通过在报告语法错误后抑制 "syntax error" 对三个标记的 yyerror
调用来减少虚假错误报告。从解析器操作中只能有限地访问此功能,但不能从解析器外部访问,因此无法从扫描器操作中启用它。
如果您想要一个在扫描器和解析器之间具有更清晰接口的解决方案,您可以考虑以下可能性:
在您的词法分析器中,当检测到未终止的注释时,return 一个未使用的标记,比如 UNTERMINATED_COMMENT。
当解析器接收到 UNTERMINATED_COMMENT 标记时,它将立即发出语法错误信号(或几乎立即发出信号。在某些情况下,它甚至可能在检查前瞻性内容之前执行一些归约token 是。)当调用
yyerror
时,yychar
全局变量的值将是先行标记,因此它将是UNTERMINATED_COMMENT
;yyerror
可以使用此事实生成更精确的错误消息,而不是通用的 "syntax error".此时立即终止解析很重要,因为再次调用扫描器将是未定义的行为。这可以通过在
yyerror
函数中将yychar
设置为YYEOF
来完成。 (另一种方法是在 rhs 中包含带有UNTERMINATED_COMMENT
的错误产生式,其操作为 YYABORT。)