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에서 찾은 최고의 소재이지만, 연산자 우선 순위의 복잡성은 고려하지 않았습니다.
편집 : IndexError (용어 만 일치)를 얻었으므로 p 2 또는 p [3]에 액세스 할 수 없습니다. 필자가 링크 한 PDF에서 이들은 ('+', p 1, p 2)와 같이 연산자를 명시 적으로 튜플에 넣었으므로 우선 순위를 고려하여 내 문제를 수정했습니다 (함수를 구분할 수는 없지만 표현식 식을 고려하면 파이프를 고려하고 모든 연산자에 액세스 할 수있는 방법이 있어야합니다.
에서 조각을 살펴보십시오. 우선 순위에는 아무런 문제가 없습니다. 당신은 우선 순위를 사용하지 않습니다. 문법은 모호하지 않으며 연산자 우선 순위는 문법에 내재되어 있습니다. 두 개의 서로 다른 액션 함수 사이에 비 터미널을 나누어도 문법이 변경되지 않고 더 간단한 액션이 만들어집니다. – rici