考慮以下語法:如何創建考慮'|'的抽象語法樹? (簾布層/ 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