1# ----------------------------------------------------------------------------- 2# yacc_sr.py 3# 4# A grammar with shift-reduce conflicts 5# ----------------------------------------------------------------------------- 6import sys 7 8if ".." not in sys.path: sys.path.insert(0,"..") 9import ply.yacc as yacc 10 11from calclex import tokens 12 13# Parsing rules 14 15# dictionary of names 16names = { } 17 18def p_statement_assign(t): 19 'statement : NAME EQUALS expression' 20 names[t[1]] = t[3] 21 22def p_statement_expr(t): 23 'statement : expression' 24 print(t[1]) 25 26def p_expression_binop(t): 27 '''expression : expression PLUS expression 28 | expression MINUS expression 29 | expression TIMES expression 30 | expression DIVIDE expression''' 31 if t[2] == '+' : t[0] = t[1] + t[3] 32 elif t[2] == '-': t[0] = t[1] - t[3] 33 elif t[2] == '*': t[0] = t[1] * t[3] 34 elif t[2] == '/': t[0] = t[1] / t[3] 35 36def p_expression_uminus(t): 37 'expression : MINUS expression' 38 t[0] = -t[2] 39 40def p_expression_group(t): 41 'expression : LPAREN expression RPAREN' 42 t[0] = t[2] 43 44def p_expression_number(t): 45 'expression : NUMBER' 46 t[0] = t[1] 47 48def p_expression_name(t): 49 'expression : NAME' 50 try: 51 t[0] = names[t[1]] 52 except LookupError: 53 print("Undefined name '%s'" % t[1]) 54 t[0] = 0 55 56def p_error(t): 57 print("Syntax error at '%s'" % t.value) 58 59yacc.yacc() 60 61 62 63 64