Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/third_party/ply/example/unicalc/calc.py
7087 views
1
# -----------------------------------------------------------------------------
2
# calc.py
3
#
4
# A simple calculator with variables. This is from O'Reilly's
5
# "Lex and Yacc", p. 63.
6
#
7
# This example uses unicode strings for tokens, docstrings, and input.
8
# -----------------------------------------------------------------------------
9
10
import sys
11
sys.path.insert(0,"../..")
12
13
tokens = (
14
'NAME','NUMBER',
15
'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
16
'LPAREN','RPAREN',
17
)
18
19
# Tokens
20
21
t_PLUS = ur'\+'
22
t_MINUS = ur'-'
23
t_TIMES = ur'\*'
24
t_DIVIDE = ur'/'
25
t_EQUALS = ur'='
26
t_LPAREN = ur'\('
27
t_RPAREN = ur'\)'
28
t_NAME = ur'[a-zA-Z_][a-zA-Z0-9_]*'
29
30
def t_NUMBER(t):
31
ur'\d+'
32
try:
33
t.value = int(t.value)
34
except ValueError:
35
print "Integer value too large", t.value
36
t.value = 0
37
return t
38
39
t_ignore = u" \t"
40
41
def t_newline(t):
42
ur'\n+'
43
t.lexer.lineno += t.value.count("\n")
44
45
def t_error(t):
46
print "Illegal character '%s'" % t.value[0]
47
t.lexer.skip(1)
48
49
# Build the lexer
50
import ply.lex as lex
51
lex.lex()
52
53
# Parsing rules
54
55
precedence = (
56
('left','PLUS','MINUS'),
57
('left','TIMES','DIVIDE'),
58
('right','UMINUS'),
59
)
60
61
# dictionary of names
62
names = { }
63
64
def p_statement_assign(p):
65
'statement : NAME EQUALS expression'
66
names[p[1]] = p[3]
67
68
def p_statement_expr(p):
69
'statement : expression'
70
print p[1]
71
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]
81
82
def p_expression_uminus(p):
83
'expression : MINUS expression %prec UMINUS'
84
p[0] = -p[2]
85
86
def p_expression_group(p):
87
'expression : LPAREN expression RPAREN'
88
p[0] = p[2]
89
90
def p_expression_number(p):
91
'expression : NUMBER'
92
p[0] = p[1]
93
94
def p_expression_name(p):
95
'expression : NAME'
96
try:
97
p[0] = names[p[1]]
98
except LookupError:
99
print "Undefined name '%s'" % p[1]
100
p[0] = 0
101
102
def p_error(p):
103
if p:
104
print "Syntax error at '%s'" % p.value
105
else:
106
print "Syntax error at EOF"
107
108
import ply.yacc as yacc
109
yacc.yacc()
110
111
while 1:
112
try:
113
s = raw_input('calc > ')
114
except EOFError:
115
break
116
if not s: continue
117
yacc.parse(unicode(s))
118
119