1 # -----------------------------------------------------------------------------
4 # A simple calculator with variables. This is from O'Reilly's
5 # "Lex and Yacc", p. 63.
7 # This example uses unicode strings for tokens, docstrings, and input.
8 # -----------------------------------------------------------------------------
11 sys.path.insert(0,"../..")
15 'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
28 t_NAME = ur'[a-zA-Z_][a-zA-Z0-9_]*'
33 t.value = int(t.value)
35 print "Integer value too large", t.value
43 t.lexer.lineno += t.value.count("\n")
46 print "Illegal character '%s'" % t.value[0]
56 ('left','PLUS','MINUS'),
57 ('left','TIMES','DIVIDE'),
64 def p_statement_assign(p):
65 'statement : NAME EQUALS expression'
68 def p_statement_expr(p):
69 'statement : expression'
72 def p_expression_binop(p):
73 '''expression : expression PLUS expression
74 | expression MINUS expression
75 | expression TIMES expression
76 | expression DIVIDE expression'''
77 if p[2] == u'+' : p[0] = p[1] + p[3]
78 elif p[2] == u'-': p[0] = p[1] - p[3]
79 elif p[2] == u'*': p[0] = p[1] * p[3]
80 elif p[2] == u'/': p[0] = p[1] / p[3]
82 def p_expression_uminus(p):
83 'expression : MINUS expression %prec UMINUS'
86 def p_expression_group(p):
87 'expression : LPAREN expression RPAREN'
90 def p_expression_number(p):
94 def p_expression_name(p):
99 print "Undefined name '%s'" % p[1]
104 print "Syntax error at '%s'" % p.value
106 print "Syntax error at EOF"
108 import ply.yacc as yacc
113 s = raw_input('calc > ')
117 yacc.parse(unicode(s))