我正致力于改进编译器分配的错误报告。我使用以下代码在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
如何指示解析器不要继续工作?在exit
之后添加BEGIN(INITIAL)
可以提供我想要的内容,但似乎不是解决问题的方法。
答案 0 :(得分:1)
你当然应该从<<EOF>>
动作返回0(或其他东西),因为如果你不这样做,词法分析器会尝试继续扫描(这是未定义的行为;扫描仪不应该继续阅读在发出EOF信号后输入,除非它已安排有新的输入缓冲区。)
未终止的评论肯定会导致语法错误,因为程序的结尾很可能已被评论中吞没。如果您不希望报告此错误,则可以在打印错误消息之前设置yyerror
检查的标志。在这种简单的情况下,不需要重置该标志,因为未终止的注释错误只能在输入结束时发生,并且此时不能进行错误恢复。
Bison本身有一种通过抑制&#34;语法错误来减少虚假错误报告的机制。报告语法错误后,调用yyerror
三个令牌。解析器操作中对此功能的访问权限有限,但无法从解析器外部访问,因此无法通过扫描程序操作启用此功能。
如果您想要在扫描仪和解析器之间使用更清晰的接口的解决方案,您可能会考虑以下可能性:
在词法分析器中,当检测到未终止的注释时,返回一个未使用的令牌,例如UNTERMINATED_COMMENT。
当解析器收到UNTERMINATED_COMMENT标记时,它会立即发出语法错误信号(或几乎立即发出信号。在某些情况下,它甚至可以在检查前瞻标记之前执行一些减少。)当{{1调用yyerror
全局的值将是先行标记,因此它将是yychar
; UNTERMINATED_COMMENT
可以使用此事实来生成更准确的错误消息,而不是通用的#34;语法错误&#34;。
此时立即终止解析非常重要,因为再次调用扫描程序将是未定义的行为。这可以通过在yyerror
函数中将yychar
设置为YYEOF
来完成。 (另一种方法是在rhs中包含yyerror
的错误生成,其行为为YYABORT。)