Yacc - '错误'意思?

时间:2017-03-26 12:17:15

标签: bison

令牌'错误&#39 ;?的含义是什么?如何在没有的情况下检测错误;

2 个答案:

答案 0 :(得分:2)

error伪终端匹配后,野牛解析器继续以正常方式解析,除了它丢弃了无法处理的令牌"。

如果遇到紧跟error令牌的令牌,它可以移动该令牌,这意味着它将停止丢弃令牌。

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

这里,"处理"被解释有点松散,因为减少动作实际上不接受先行标记。尽管如此,减少错误产生就足够了。

在这种情况下,必须注意调用yyerrok。如果使用yyerrok取消错误处理并且前瞻标记无法移位,则错误处理程序将重新进入,并且可能会陷入无限循环。

例如,

commands: %empty | commands command

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

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

第三次制作处理丢失的分号。在这里,我们无法调用yyerrok,因为前瞻令牌可能是非法令牌,例如。如果我们要调用yyerrok,错误状态将被清除,错误处理将立即重新进入与前瞻令牌相同的感叹号,从而导致无限循环。但 如果没有yyerrok,解析器仍处于错误处理模式,并且将丢弃违规令牌。

注意:上述内容旨在帮助回答error生成的效果,error令牌之后没有任何内容的问题。它无意回答任何未被提出的问题,例如"我如何做 X ?" (对于 X 的各种值)。提供的示例有点人为。原文使用换行符作为表达式终止符,并且没有必要包含第二个错误处理生成,因为除了EOF之外它实际上是不可能省略终止换行符。

答案 1 :(得分:1)

一个常见的混淆源 - error令牌用于错误恢复,而不是错误检测。语法错误由解析器自动检测和报告。您可以使用YYERROR宏来检测操作中的其他错误并告诉Bison。

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