Yacc--'error' 是什么意思?

Yacc--What does 'error' mean?

令牌'error'是什么意思?如何在没有 ;

的情况下检测错误

匹配到error伪终端后,bison解析器继续正常解析,只是丢弃了"cannot be handled".

的token

如果遇到紧跟在 error 标记之后的标记,它可以移动该标记,这意味着它将停止丢弃标记。

但是,这不是解析器处理令牌的唯一方式。它也可以通过减少来处理它。

这里,单词 "handled" 的解释有点松散,因为缩减操作实际上并不接受先行标记。尽管如此,减少错误的产生已经足够了。

在这种情况下,必须注意不要调用yyerrok。如果用yyerrok取消了错误处理,无法移动lookahead token,那么错误处理程序会重新进入,有可能陷入死循环。

例如,

commands: %empty | commands command

command : exp ';'   { printf("Value is %d\n", ); }
        | error ';' { printf("Bad expression\n"); yyerrok; }
        | error     { printf("Missing semicolon\n"); }

第一个 command 产生式导致打印出正确表达式的结果。第二个产生式处理仍然有分号的语法错误。它可以取消错误处理,因为 ; 已经被移动,所以可以重新启动错误处理。

第三个产品处理缺少的分号。在这里,我们不能调用yyerrok,因为lookahead token 有可能是非法的token,比如!。如果我们调用 yyerrok,错误状态将被清除,错误处理将立即重新进入,并带有与先行标记相同的感叹号,从而导致无限循环。但 没有 yyerrok,解析器仍处于错误处理模式,违规标记将被丢弃。

注意:以上内容旨在帮助回答以下问题:error 产生式在 error 标记后没有任何内容会产生什么影响。它无意回答任何未被问到的问题,例如 "How do I do X ?"(对于 X 的各种值)。提供的示例有点人为。原始使用换行符作为表达式终止符,并且没有必要包括第二个错误处理产生式,因为除了 EOF 之外,实际上不可能省略终止换行符。

一个常见的混淆来源 -- error 标记用于错误 恢复 ,而不是错误 检测 。解析器会自动检测并报告语法错误。您可以检测操作中的其他错误,并使用 YYERROR 宏将其告知 bison。

从概念上讲,error 令牌替换了一系列零个或多个输入令牌,以尝试将无效输入流转换为有效输入流。当错误发生时,bison 生成的解析器进入错误恢复模式,丢弃令牌和状态,直到它到达可以移动 error 伪令牌的点。然后它会转移错误标记并尝试从那里继续。