1 # -----------------------------------------------------------------------------
4 # A simple calculator with variables. This is from O'Reilly's
5 # "Lex and Yacc", p. 63.
6 # -----------------------------------------------------------------------------
9 sys.path.insert(0,"../..")
11 if sys.version_info[0] >= 3:
16 'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
29 t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
34 t.value = int(t.value)
36 print("Integer value too large %s" % t.value)
44 t.lexer.lineno += t.value.count("\n")
47 print("Illegal character '%s'" % t.value[0])
57 ('left','PLUS','MINUS'),
58 ('left','TIMES','DIVIDE'),
65 def p_statement_assign(t):
66 'statement : NAME EQUALS expression'
69 def p_statement_expr(t):
70 'statement : expression'
73 def p_expression_binop(t):
74 '''expression : expression PLUS expression
75 | expression MINUS expression
76 | expression TIMES expression
77 | expression DIVIDE expression'''
78 if t[2] == '+' : t[0] = t[1] + t[3]
79 elif t[2] == '-': t[0] = t[1] - t[3]
80 elif t[2] == '*': t[0] = t[1] * t[3]
81 elif t[2] == '/': t[0] = t[1] / t[3]
82 elif t[2] == '<': t[0] = t[1] < t[3]
84 def p_expression_uminus(t):
85 'expression : MINUS expression %prec UMINUS'
88 def p_expression_group(t):
89 'expression : LPAREN expression RPAREN'
92 def p_expression_number(t):
96 def p_expression_name(t):
101 print("Undefined name '%s'" % t[1])
106 print("Syntax error at '%s'" % t.value)
108 print("Syntax error at EOF")
110 import ply.yacc as yacc
111 yacc.yacc(optimize=1)
115 s = raw_input('calc > ')