-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathHW2_parser.py
102 lines (90 loc) · 2.19 KB
/
HW2_parser.py
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
# Lexer
tokens = ['ASSIGN','LEFTPARAN','RIGHTPARAN','INT','NAME','PLUS', 'UNARYSUB']
reserved = {'print' : 'PRINT',
'input' : 'INPUT'}
tokens += reserved.values()
t_ASSIGN = r'='
t_PLUS = r'\+'
t_UNARYSUB = r'\-'
t_LEFTPARAN = r'\('
t_RIGHTPARAN = r'\)'
t_ignore = ' \t\r'
t_ignore_COMMENT = r'(\#[^\n]*)'
def t_INT(t):
r'\d+'
try:
t.value = int(t.value)
except ValueError:
print "integer value too large", t.value
t.value = 0
return t
def t_NAME(t):
r'[_a-zA-Z]\w*'
if t.value in reserved:
t.type = reserved[ t.value ]
return t
def t_newline(t):
r'\n+'
t.lexer.lineno += t.value.count("\n")
def t_comment(t):
r'\#[^\n]*'
def t_error(t):
print "Illegal character '%s'" % t.value[0]
t.lexer.skip(1)
import ply_3_4.lex as lex
lexer = lex.lex()
# Parser
from compiler.ast import Module, Stmt, Printnl, Add, Const, Name, Discard, CallFunc, UnarySub, AssName, Assign
precedence = (
('nonassoc','PRINT'),
('nonassoc','INPUT'),
('left','PLUS'),
('nonassoc','UNARYSUB'),
('nonassoc','LEFTPARAN','RIGHTPARAN'),
('nonassoc','INT','NAME'),
)
start = 'program'
def p_program(t):
'program : module'
t[0] = Module(None, t[1])
def p_module(t):
'module : statement'
#print t[0], t[1]
t[0] = Stmt(t[1])
def p_empty(t):
'module :'
t[0] = Stmt([])
def p_mult_statement(t):
'statement : statement statement'
t[0] = t[1]+t[2]
def p_print_statement(t):
'statement : PRINT expression'
t[0] = [Printnl([t[2]], None)]
def p_assign_statement(t):
'statement : NAME ASSIGN expression'
t[0] = [Assign([AssName(t[1], 'OP_ASSIGN')],t[3])]
def p_expression_statement(t):
'statement : expression'
t[0] = [Discard(t[1])]
def p_name_expression(t):
'expression : NAME'
t[0] = Name(t[1])
def p_int_expression(t):
'expression : INT'
t[0] = Const(t[1])
def p_plus_expression(t):
'expression : expression PLUS expression'
t[0] = Add((t[1], t[3]))
def p_neg_expression(t):
'expression : UNARYSUB expression'
t[0] = UnarySub(t[2])
def p_paren_expression(t):
'expression : LEFTPARAN expression RIGHTPARAN'
t[0] = t[2]
def p_input_expression(t):
'expression : INPUT LEFTPARAN RIGHTPARAN'
t[0] = CallFunc(Name('input'),[])
def p_error(t):
print "Syntax error at '%s'" % t.value
import ply_3_4.yacc as yacc
yacc.yacc()