【发布时间】:2016-08-04 13:22:50
【问题描述】:
考虑以下语法:
expr : expr '+' term | expr '-' term | term
term : term '*' factor | term '/' factor | factor
factor : '(' expr ')' | identifier | number
这是我使用 ply 的代码:
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这个主题上找到的最好的材料,但它没有考虑运算符优先级的复杂性。
编辑:我无法访问 p2 或 p[3],因为我得到一个 IndexError(它仅与术语匹配)。在我链接的 PDF 中,他们明确地将运算符放在元组中,例如:('+', p1, p2),因此,考虑到优先级证明了我的问题(我无法将函数,表达式就是表达式,应该有办法考虑管道和访问任何运算符)。
【问题讨论】:
-
我不明白为什么你会因为优先级而感到“无法分离功能”。优先级没有问题。你不使用优先级,真的;语法是明确的,运算符优先级是语法中固有的。在两个不同的动作函数之间划分一个非终结符不会改变语法,并且会产生更简单的动作。
标签: python abstract-syntax-tree yacc ply