-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patheval.py
More file actions
120 lines (74 loc) · 2.33 KB
/
eval.py
File metadata and controls
120 lines (74 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
'''
A simple interpreter for addition and subtraction
Inspired by tutorial from Ruslan Spivak
Author: GotoCode
'''
# input string --> lexer --> token stream
# token stream --> parser --> *recognition*
# *after recognition* --> interpreter --> value
### Token types ###
INTEGER = 'INTEGER'
EOF = 'EOF'
PLUS = 'PLUS'
MINUS = 'MINUS'
### Token - {type:t, value:v} ###
def make_token(type, value):
return {'type' : type,
'value': value}
### LEXER CODE ###
def skip_whitespace(text, pos):
while pos < len(text) and text[pos].isspace():
pos += 1
return pos
def make_integer(text, pos):
result = ''
while pos < len(text) and text[pos].isdigit():
result += text[pos]
pos += 1
return (pos, result)
def make_lexer(text):
pos = 0
# return appropriate token based on current_char
while pos < len(text):
curr_char = text[pos]
if curr_char.isspace():
pos = skip_whitespace(text, pos)
elif curr_char.isdigit():
(pos, int_string) = make_integer(text, pos)
yield make_token(INTEGER, int(int_string))
elif curr_char == '-':
pos += 1
yield make_token(MINUS, '-')
elif curr_char == '+':
pos += 1
yield make_token(PLUS, '+')
else:
raise Exception('Unrecognized char at index: %d' % pos)
# once out of bounds, any further calls yield EOF token
while True:
yield make_token(EOF, None)
### PARSER / INTERPRETER CODE ###
def eval(text):
lexer = make_lexer(text)
curr_token = lexer.next()
if curr_token['type'] != INTEGER:
raise Exception('Syntax Error')
result = curr_token['value']
curr_token = lexer.next()
while curr_token['type'] != EOF:
if curr_token['type'] == PLUS:
result += lexer.next()['value']
else:
result -= lexer.next()['value']
curr_token = lexer.next()
return result
def main():
#try:
while True:
input_str = raw_input('calc> ')
result = eval(input_str)
print result
#except:
# print 'Goodbye!\n'
if __name__ == '__main__':
main()