[英]How can I create an abstract syntax tree considering '|'? (Ply / Yacc)
考慮以下語法:
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 這樣的函數分開,但在這種情況下,我將消除運算符優先級。 文檔不是很有幫助,因為我是初學者,無法解決這個問題。 我在這個主題上找到的最好的材料是 this ,但它沒有考慮運算符優先級的復雜性。
編輯:我無法訪問 p 2或 p[3],因為我得到了一個 IndexError(它只匹配術語)。 在我鏈接的 PDF 中,他們明確地將運算符放在元組中,例如: ('+', p 1 , p 2 ),因此,考慮到優先級證明了我的問題(我無法將函數、表達式分開是表達式,應該有一種方法來考慮管道並訪問任何運算符)。
據我所知,在p[0] = ("expr", p[1], p[2])
, p[1]
將是左手表達式, p[2]
將是運算符,並且p[3]
(您沒有使用)將是右手術語。
只需使用p[2]
來確定運算符,添加p[3]
,因為您將需要它,並且您應該很高興。
此外,您必須驗證p
有多少項,因為如果最后一條規則是| term"""
| term"""
匹配, p
將只有兩個項目而不是四個。
看一下GardenSnake 示例中的一個片段:
def p_comparison(p):
"""comparison : comparison PLUS comparison
| comparison MINUS comparison
| comparison MULT comparison
| comparison DIV comparison
| comparison LT comparison
| comparison EQ comparison
| comparison GT comparison
| PLUS comparison
| MINUS comparison
| power"""
if len(p) == 4:
p[0] = binary_ops[p[2]]((p[1], p[3]))
elif len(p) == 3:
p[0] = unary_ops[p[1]](p[2])
else:
p[0] = p[1]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.