-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.py
More file actions
159 lines (126 loc) · 3.5 KB
/
parser.py
File metadata and controls
159 lines (126 loc) · 3.5 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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import ply.yacc as yacc
import testcases
from lexer import tokens
from representation import *
def p_program(p):
"program : statements"
p[0] = Program(p[1])
def p_statements(p):
"statements : statements statement"
p[1].append(p[2])
p[0] = p[1]
def p_statements_empty(p):
"statements :"
p[0] = []
def p_statement(p):
"""statement : while_stmt
| define_stmt
| assign_stmt
| expression SEMICOLON
| return_stmt
| if_stmt
"""
p[0] = p[1]
def p_define(p):
"define_stmt : VAR ID OP_EQUAL expression SEMICOLON"
p[0] = DefineStmt(p[2], p[4])
def p_assign(p):
"assign_stmt : ID OP_EQUAL expression SEMICOLON"
p[0] = AssignStmt(p[1], p[3])
def p_while(p):
"while_stmt : WHILE LPAREN expression RPAREN compound_statements"
p[0] = WhileStmt(p[3], p[5])
def p_return_none(p):
"return_stmt : RETURN SEMICOLON"
p[0] = ReturnStmt()
def p_return(p):
"return_stmt : RETURN expression SEMICOLON"
p[0] = ReturnStmt(p[2])
def p_if(p):
"if_stmt : IF LPAREN expression RPAREN compound_statements else_clause"
p[0] = IfStmt(p[3], p[5], p[6])
def p_else_empty(p):
"else_clause :"
p[0] = None
def p_else(p):
"else_clause : ELSE compound_statements"
p[0] = p[2]
def p_compound_statements(p):
"compound_statements : LBRACKET statements RBRACKET"
p[0] = p[2]
def p_expression_bin_op(p):
"""expression : expression OP_PLUS expression
| expression OP_MINUS expression
| expression OP_TIMES expression
| expression OP_DIVIDE expression
| expression OP_GT expression
| expression OP_GTEQ expression
| expression OP_LT expression
| expression OP_LTEQ expression
| expression OP_EQ expression
"""
p[0] = BinaryOp(p[2], p[1], p[3])
def p_expression_id(p):
"expression : ID"
p[0] = Identifier(p[1])
def p_term_factor(p):
"expression : NUMBER"
p[0] = Number(p[1])
def p_expression_expr(p):
"expression : LPAREN expression RPAREN"
p[0] = p[2]
def p_expression_func_call(p):
"""expression : function_call
| function_decl
"""
p[0] = p[1]
def p_func_call(p):
"function_call : expression LPAREN arguments RPAREN"
p[0] = FunctionCall(p[1], p[3])
def p_arguments_empty(p):
"arguments :"
p[0] = []
def p_arguments(p):
"arguments : argument arguments_rest"
p[0] = [p[1]] + p[2]
def p_arguments_rest(p):
"arguments_rest : COMMA argument arguments_rest"
p[0] = [p[2]] + p[3]
def p_arguments_rest_empty(p):
"arguments_rest :"
p[0] = []
def p_argument(p):
"argument : expression"
p[0] = p[1]
def p_func_decl(p):
"function_decl : FUNCTION LPAREN parameters RPAREN compound_statements"
p[0] = FunctionDecl(p[3], p[5])
def p_parameters(p):
"parameters : parameter parameters_rest"
p[0] = [p[1]] + p[2]
def p_parameters_rest(p):
"parameters_rest : COMMA parameter parameters_rest"
p[0] = [p[2]] + p[3]
def p_parameters_rest_empty(p):
"parameters_rest :"
p[0] = []
def p_parameter(p):
"parameter : ID"
p[0] = p[1]
precedence = (
('nonassoc', 'OP_GT', 'OP_GTEQ', 'OP_LT', 'OP_LTEQ', 'OP_EQ'),
('left', 'OP_PLUS', 'OP_MINUS'),
('left', 'OP_TIMES', 'OP_DIVIDE'),
('right', 'LPAREN') # to make function call possess higher precedence
)
def p_error(p):
print "Syntax error with", p
# Build the parser
parser = yacc.yacc()
# while True:
# try:
# s = raw_input('calc > ')
# except EOFError:
# break
# if not s:
# continue