上述计算器例子的文法中存在左递归,为什么 bison 可以处理?
时间: 2024-09-19 09:13:39 浏览: 284
在上述的计算器文法示例中,虽然存在左递归,Bison(BLANKENSHIP'S YACC NOTATION,也称为YYC,一种解析器生成器)能够处理这种情况,主要是因为Bison允许使用终结符( terminals,如数字、操作符)作为非终结符的右部,这被称为"终结符优先"(terminal-driven)。即便有左递归,Bison仍然可以构造解析树并执行语法分析。实际上,Bison会自动转换为不包含左递归的形式,这个过程称为"归约"(reduction),从而消除对无尽循环的担忧。
yylval是一个预定义的变量,它在词法分析阶段用于存储每个输入符号的实际值。在解析过程中,yylval并不直接参与表达式的计算,而是作为一个临时存储空间,用来传递从输入流中读取的值给动作(action)部分。当遇到非终结符的解析时,yylval会被赋予适当的值(通常是通过$1、$2等元素传递过来的结果),这样就实现了不同部分的协同工作。
关于除数为0的情况,1.3样例代码并未处理这种错误情况。在语法层面,除以零通常被视为违反数学基本规则,但在实际应用中,比如编程环境,可能会通过异常处理来标识这种非法行为。然而,在纯语法解析阶段,如果设计的目标只是合法的算术表达式,那么除以零应视为错误而不是合法语句,因此测试案例中把它当作合法的可能是因为其关注点在于语法解析,而非全面的语义分析。
要使计算器文法支持除数0规避,可以在语法中添加条件判断或错误处理规则,比如:
```bnf
expr: expr '*' factor { $$ = $1 * $3; }
| expr '/' factor { if ($3 != 0) { $$ = $1 / $3; } else { error("Division by zero"); } }
...
factor: INTEGER { $$ = $1; }
```
这里添加了一个if语句检查除数是否为0,如果是,则触发错误处理。但请注意,这仅限于语法层面,对于完整的程序,还需要实现错误处理逻辑。
阅读全文