6.2 将语法规则合并

最后更新于:2022-04-01 01:10:20

如果语法规则类似的话,可以合并到一个方法中。例如,考虑前面例子中的两个规则: ~~~ def p_expression_plus(p): 'expression : expression PLUS term' p[0] = p[1] + p[3] def p_expression_minus(t): 'expression : expression MINUS term' p[0] = p[1] - p[3] ~~~ 比起写两个方法,你可以像下面这样写在一个方法里面: ~~~ def p_expression(p): '''expression : expression PLUS term | expression MINUS term''' if p[2] == '+': p[0] = p[1] + p[3] elif p[2] == '-': p[0] = p[1] - p[3] ~~~ 总之,方法的文档字符串可以包含多个语法规则。所以,像这样写也是合法的(尽管可能会引起困惑): ~~~ def p_binary_operators(p): '''expression : expression PLUS term | expression MINUS term term : term TIMES factor | term DIVIDE factor''' if p[2] == '+': p[0] = p[1] + p[3] elif p[2] == '-': p[0] = p[1] - p[3] elif p[2] == '*': p[0] = p[1] * p[3] elif p[2] == '/': p[0] = p[1] / p[3] ~~~ 如果所有的规则都有相似的结构,那么将语法规则合并才是个不错的注意(比如,产生式的项数相同)。不然,语义动作可能会变得复杂。不过,简单情况下,可以使用`len()`方法区分,比如: ~~~ def p_expressions(p): '''expression : expression MINUS expression | MINUS expression''' if (len(p) == 4): p[0] = p[1] - p[3] elif (len(p) == 3): p[0] = -p[2] ~~~ 如果考虑解析的性能,你应该避免像这些例子一样在一个语法规则里面用很多条件来处理。因为,每次检查当前究竟匹配的是哪个语法规则的时候,实际上重复做了分析器已经做过的事(分析器已经准确的知道哪个规则被匹配了)。为每个规则定义单独的方法,可以消除这点开销。
';