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で見つけた最高の素材ですが、演算子の優先順位の複雑さは考慮されていません。
EDIT:IndexErrorを取得しているため、2またはp [3]にアクセスできません(これは用語にのみ一致します)。私がリンクしたPDFでは、( '+'、p 1、p 2)のように明示的に演算子をタプルの中に入れて、優先順位を考慮して問題を明らかにしています(関数を分離できません。表現は、パイプを考慮して任意の演算子にアクセスする方法があるはずです)。
からスニペットを見てみましょう。優先順位に問題はありません。あなたは本当に優先順位を使用しません。文法は曖昧でなく、演算子の優先順位は文法に固有のものです。 2つの異なるアクション関数の間で非終端記号を分割しても、文法は変更されず、より単純なアクションが生成されます。 – rici