-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinterpreter.py
More file actions
103 lines (80 loc) · 1.88 KB
/
interpreter.py
File metadata and controls
103 lines (80 loc) · 1.88 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
import sys
sys.path.insert(0,"../..") # Add path to ply-2.8/
f=open(sys.argv[1],'r')
reserved = {
'print' : 'PRINT',
}
tokens = [
'NAME','NUMBER',
] + list(reserved.values())
# Each literal must be a single character
literals = ['=','+','-','*','/']
# Tokens defns
def t_NAME(t):
r'[a-zA-Z_][a-zA-Z_0-9]*'
t.type = reserved.get(t.value,'NAME') # Check for reserved words
return t
def t_NUMBER(t):
r'\d+'
t.value = int(t.value)
return t
t_ignore = " \t"
def t_newline(t):
r'\n+'
t.lexer.lineno += t.value.count("\n")
def t_error(t):
print("Illegal character '%s'" % t.value[0])
t.lexer.skip(1)
# Build the lexer, and enable debugging
import ply.lex as lex
lex.lex(debug=1)
# Parsing rules
precedence = (
('left','+','-'),('left','+','-')
)
# dictionary of names
names = { }
def p_statement_assign(p):
'statement : NAME "=" expression'
names[p[1]] = p[3]
def p_statement_expr(p):
'statement : PRINT expression'
print(p[2])
def p_expression_term(p):
'expression : term'
p[0]=p[1]
def p_expression_binop(p):
'expression : expression "+" term'
p[0] = p[1] + p[3]
def p_expression_binop2(p):
'expression : expression "-" term'
p[0] = p[1] - p[3]
def p_term_factor(p):
'term : factor'
p[0]=p[1]
def p_term_binop(p):
'term : term "*" factor'
p[0] = p[1] * p[3]
def p_term_binop2(p):
'term : term "/" factor'
p[0] = p[1] / p[3]
def p_factor_number(p):
"factor : NUMBER"
p[0] = p[1]
def p_factor_name(p):
"factor : NAME"
try:
p[0] = names[p[1]]
except LookupError:
print("Undefined name '%s'" % p[1])
p[0] = 0
def p_error(p):
if p:
print("Syntax error at '%s'" % p.value)
else:
print("Syntax error at EOF")
import ply.yacc as yacc
yacc.yacc()
inp=f.readlines()
for s in inp:
yacc.parse(s)