令牌'错误&#39 ;?的含义是什么?如何在没有的情况下检测错误;
答案 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
伪令牌可以移位的点。然后它会移动错误令牌并尝试从那里继续。