我继承了一个 ANTLR 语法,现在用 Python Lex Yacc 实现它而无需任何更改。我的问题是,ANTLR 通常使用非常高级的 EBNF 来定义语法,而 Yacc 使用简单的上下文无关语法。
我对二进制表达式的 AST 定义感到困惑。从 ANTLR 给出,它们看起来像
disjunction
: conjunction ('||' conjunction)*
这个定义的存在是出于优先考虑,不要怀疑名称。
在我的 CFG 中,它看起来像
def p_sum(self, p):
""" sum : product product_list """
???
def p_product_list(self, p):
""" product_list : PLUS product product_list
| MINUS product product_list
| epsilon
"""
???
其他一些表达式看起来像
def p_disjunction_1(self, p):
""" disjunction : conjunction """
p[0] = p[1]
def p_disjunction_2(self, p):
""" disjunction : conjunction OR disjunction """
p[0] = BinaryOp(p[2], p[1], p[3], p[1].coord)
我想要的是我的 AST 仅包含 BinaryExpression 节点,如第二个示例中所示:
BinaryExpression('+', lhs, rhs)
但是这个语法给了我一个因素列表。有什么办法可以用我的方式写吗?这 ???是我需要的地方,但需要一个表达式来构建我的 AST,但我想不出一个好的方法来做到这一点。我看到的是用一元表达式列表定义一个节点,但这对我来说很难看。还是有另一种写语法的方法?我不敢碰它,因为我担心我会改变它以解析不同的东西。