考虑以下语法:如何创建考虑'|'的抽象语法树? (帘布层/ Yacc的)
expr : expr '+' term | expr '-' term | term
term : term '*' factor | term '/' factor | factor
factor : '(' expr ')' | identifier | number
这是我的代码使用厚度:
from ply import lex, yacc
tokens = [
"identifier",
"number",
"plus",
"minus",
"mult",
"div"
]
t_ignore = r" \t"
t_identifier = r"^[a-zA-Z]+$"
t_number = r"[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?"
t_plus = r"\+"
t_minus = r"-"
t_mult = r"\*"
t_div = r"/"
def p_stmt(p):
"""stmt : expr"""
p[0] = ("stmt", p[1])
def p_expr(p):
"""expr : expr plus term
| expr minus term
| term"""
p[0] = ("expr", p[1], p[2]) # Problem here <<<
def p_term(p):
"""term : term mult factor
| term div factor
| factor"""
def p_factor(p):
"""factor : '(' expr ')'
| identifier
| number"""
if __name__ == "__main__":
lex.lex()
yacc.yacc()
data = "32 + 10"
result = yacc.parse(data)
print(result)
我怎么建立一个AST与表达,如果我不能访问运营商?我可以分开像p_expr_plus这样的函数,但是在这种情况下,我会消除运算符优先级。 docs不是很有帮助,因为我是初学者,不能解决这个问题。我在is this这个主题上找到了最好的素材,但它没有考虑运算符优先级的复杂性。
编辑:我不能访问p 2或p [3],因为我得到一个IndexError(它只与术语匹配)。在我已经链接的PDF中,他们明确地将操作符放在元组中,如:('+',p 1,p 2),因此,考虑到优先级,显示我的问题(我不能分开函数,表达式是表达式,应该有一种方法来考虑管道和访问任何运营商)。
我不明白为什么你觉得你“不能分开的功能”,因为优先。优先顺序没有问题。你真的不使用优先权;语法是明确的,操作符优先级是语法中固有的。在两个不同的动作函数之间划分非终结符不会改变语法,并产生更简单的动作。 – rici