2015-05-09 36 views
0

我正在改进我的编译器分配的错误报告。我使用下面的代码处理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给了我想要的东西,但似乎并没有办法处理它。

+1

顺便说一句,你的''规则是不正确的;没有规则与注释中的“*”匹配,因此会落入默认规则。如果你的默认规则是'。 {return yytext [0];这会造成特别的灾难性后果。如果默认规则是弹性生成的默认值('ECHO'),它将会很奇怪。另外,字符集'[^ *]'包含'\ n',所以'| \ n'是多余的。 – rici

回答

1

你当然应该从<<EOF>>操作中返回0(或者其他),因为如果你不这样做,词法分析器会尝试继续扫描(这是未定义的行为;扫描器在EOF之后不应该继续读取输入除非它安排了新的输入缓冲区)

由于程序结束很可能已经被注入评论中,所以未终止的注释很可能会导致语法错误。如果您不想要报告此错误,那么您可以简单地设置一个标记,在打印错误消息之前,该标记将被yyerror检查。在这种简单的情况下,不需要重置该标志,因为未终止的注释错误只能在输入结束时发生,并且在该点不可能进行错误恢复。

野牛本身有一个机制,通过在报告语法错误后,通过抑制针对yyerror的三个标记的“语法错误”调用来减少虚假错误报告。在解析器操作中对此功能的访问权限有限,但不能从解析器外部访问,因此无法通过扫描器操作启用。

如果你想与扫描仪和分析器之间的清洁界面的解决方案,你可以考虑以下可能性:

  1. 在你的词法分析器,当检测到未终止的注释时,返回其他未使用的令牌,说UNTERMINATED_COMMENT。

  2. 当解析器接收UNTERMINATED_COMMENT令牌,它将立即发信号通知语法错误(或几乎立即。在某些情况下,它可以执行一些减少之前就检查超前记号是什么)。当yyerror被调用时, yychar global的值将是lookahead token,所以它会是UNTERMINATED_COMMENT; yyerror可以使用这个事实来产生更精确的错误消息,而不是通用的“语法错误”。

  3. 在这一点上立即终止解析很重要,因为再次调用扫描器将是未定义的行为。这可以通过yyerror函数中的yychar设置为YYEOF来完成。 (另一种方法是,包括错误与生产在UNTERMINATED_COMMENT的RHS,其作用是YYABORT。)