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