comparison python/c3/parser.py @ 296:9417caea2eb3

Directorized some backend files
author Windel Bouwman
date Sun, 01 Dec 2013 13:36:58 +0100
parents 6aa721e7b10b
children
comparison
equal deleted inserted replaced
295:917eab04b8b7 296:9417caea2eb3
1 import logging 1 import logging
2 from .lexer import Lexer 2 from .lexer import Lexer
3 from . import astnodes 3 from .astnodes import FieldRef, Literal, TypeCast, Unop, Binop
4 from .astnodes import Assignment, ExpressionStatement, CompoundStatement
5 from .astnodes import ReturnStatement, WhileStatement, IfStatement
6 from .astnodes import FunctionType, Function, FormalParameter
7 from .astnodes import StructureType, DefinedType, PointerType
8 from .astnodes import Constant, Variable
9 from .astnodes import StructField, Deref
10 from .astnodes import Package, ImportDesignator
11 from .astnodes import Designator, VariableUse, FunctionCall
4 from ppci import CompilerError 12 from ppci import CompilerError
5 13
6 14
7 class Parser: 15 class Parser:
8 """ Parses sourcecode into an abstract syntax tree (AST) """ 16 """ Parses sourcecode into an abstract syntax tree (AST) """
65 73
66 def parsePackage(self): 74 def parsePackage(self):
67 self.Consume('module') 75 self.Consume('module')
68 name = self.Consume('ID') 76 name = self.Consume('ID')
69 self.Consume(';') 77 self.Consume(';')
70 self.mod = astnodes.Package(name.val, name.loc) 78 self.mod = Package(name.val, name.loc)
71 self.currentPart = self.mod 79 self.currentPart = self.mod
72 while self.Peak != 'END': 80 while self.Peak != 'END':
73 self.parseTopLevel() 81 self.parseTopLevel()
74 self.Consume('END') 82 self.Consume('END')
75 83
90 def parseDesignator(self): 98 def parseDesignator(self):
91 """ A designator designates an object """ 99 """ A designator designates an object """
92 name = self.Consume('ID') 100 name = self.Consume('ID')
93 if self.hasConsumed(':'): 101 if self.hasConsumed(':'):
94 name2 = self.Consume('ID') 102 name2 = self.Consume('ID')
95 return astnodes.ImportDesignator(name.val, name2.val, name.loc) 103 return ImportDesignator(name.val, name2.val, name.loc)
96 else: 104 else:
97 return astnodes.Designator(name.val, name.loc) 105 return Designator(name.val, name.loc)
98 106
99 # Type system 107 # Type system
100 def parseTypeSpec(self): 108 def parseTypeSpec(self):
101 # For now, do simple type spec, just parse an ID: 109 # For now, do simple type spec, just parse an ID:
102 #return self.parseDesignator() 110 #return self.parseDesignator()
105 self.Consume('{') 113 self.Consume('{')
106 mems = [] 114 mems = []
107 while self.Peak != '}': 115 while self.Peak != '}':
108 mem_t = self.parseTypeSpec() 116 mem_t = self.parseTypeSpec()
109 mem_n = self.Consume('ID').val 117 mem_n = self.Consume('ID').val
110 mems.append(astnodes.StructField(mem_n, mem_t)) 118 mems.append(StructField(mem_n, mem_t))
111 while self.hasConsumed(','): 119 while self.hasConsumed(','):
112 mem_n = self.Consume('ID').val 120 mem_n = self.Consume('ID').val
113 mems.append(astnodes.StructField(mem_n, mem_t)) 121 mems.append(StructField(mem_n, mem_t))
114 self.Consume(';') 122 self.Consume(';')
115 self.Consume('}') 123 self.Consume('}')
116 theT = astnodes.StructureType(mems) 124 theT = StructureType(mems)
117 else: 125 else:
118 theT = self.parseDesignator() 126 theT = self.parseDesignator()
119 # Check for pointer suffix: 127 # Check for pointer suffix:
120 while self.hasConsumed('*'): 128 while self.hasConsumed('*'):
121 theT = astnodes.PointerType(theT) 129 theT = PointerType(theT)
122 return theT 130 return theT
123 131
124 def parseTypeDef(self): 132 def parseTypeDef(self):
125 self.Consume('type') 133 self.Consume('type')
126 newtype = self.parseTypeSpec() 134 newtype = self.parseTypeSpec()
127 typename = self.Consume('ID') 135 typename = self.Consume('ID')
128 self.Consume(';') 136 self.Consume(';')
129 df = astnodes.DefinedType(typename.val, newtype, typename.loc) 137 df = DefinedType(typename.val, newtype, typename.loc)
130 self.addDeclaration(df) 138 self.addDeclaration(df)
131 139
132 # Variable declarations: 140 # Variable declarations:
133 def parseVarDef(self): 141 def parseVarDef(self):
134 self.Consume('var') 142 self.Consume('var')
135 t = self.parseTypeSpec() 143 t = self.parseTypeSpec()
136 def parseVar(): 144 def parseVar():
137 name = self.Consume('ID') 145 name = self.Consume('ID')
138 v = astnodes.Variable(name.val, t) 146 v = Variable(name.val, t)
139 v.loc = name.loc 147 v.loc = name.loc
140 if self.hasConsumed('='): 148 if self.hasConsumed('='):
141 v.ival = self.Expression() 149 v.ival = self.Expression()
142 self.addDeclaration(v) 150 self.addDeclaration(v)
143 parseVar() 151 parseVar()
150 t = self.parseTypeSpec() 158 t = self.parseTypeSpec()
151 def parseConst(): 159 def parseConst():
152 name = self.Consume('ID') 160 name = self.Consume('ID')
153 self.Consume('=') 161 self.Consume('=')
154 val = self.Expression() 162 val = self.Expression()
155 c = astnodes.Constant(name.val, t, val) 163 c = Constant(name.val, t, val)
156 c.loc = name.loc 164 c.loc = name.loc
157 parseConst() 165 parseConst()
158 while self.hasConsumed(','): 166 while self.hasConsumed(','):
159 parseConst() 167 parseConst()
160 self.Consume(';') 168 self.Consume(';')
162 # Procedures 170 # Procedures
163 def parseFunctionDef(self): 171 def parseFunctionDef(self):
164 loc = self.Consume('function').loc 172 loc = self.Consume('function').loc
165 returntype = self.parseTypeSpec() 173 returntype = self.parseTypeSpec()
166 fname = self.Consume('ID').val 174 fname = self.Consume('ID').val
167 f = astnodes.Function(fname, loc) 175 f = Function(fname, loc)
168 self.addDeclaration(f) 176 self.addDeclaration(f)
169 savePart = self.currentPart 177 savePart = self.currentPart
170 self.currentPart = f 178 self.currentPart = f
171 self.Consume('(') 179 self.Consume('(')
172 parameters = [] 180 parameters = []
173 if not self.hasConsumed(')'): 181 if not self.hasConsumed(')'):
174 def parseParameter(): 182 def parseParameter():
175 typ = self.parseTypeSpec() 183 typ = self.parseTypeSpec()
176 name = self.Consume('ID') 184 name = self.Consume('ID')
177 param = astnodes.FormalParameter(name.val, typ) 185 param = FormalParameter(name.val, typ)
178 param.loc = name.loc 186 param.loc = name.loc
179 self.addDeclaration(param) 187 self.addDeclaration(param)
180 parameters.append(param) 188 parameters.append(param)
181 parseParameter() 189 parseParameter()
182 while self.hasConsumed(','): 190 while self.hasConsumed(','):
183 parseParameter() 191 parseParameter()
184 self.Consume(')') 192 self.Consume(')')
185 paramtypes = [p.typ for p in parameters] 193 paramtypes = [p.typ for p in parameters]
186 f.typ = astnodes.FunctionType(paramtypes, returntype) 194 f.typ = FunctionType(paramtypes, returntype)
187 f.body = self.parseCompoundStatement() 195 f.body = self.parseCompoundStatement()
188 self.currentPart = savePart 196 self.currentPart = savePart
189 197
190 # Statements: 198 # Statements:
191 199
197 yes = self.parseCompoundStatement() 205 yes = self.parseCompoundStatement()
198 if self.hasConsumed('else'): 206 if self.hasConsumed('else'):
199 no = self.parseCompoundStatement() 207 no = self.parseCompoundStatement()
200 else: 208 else:
201 no = None 209 no = None
202 return astnodes.IfStatement(condition, yes, no, loc) 210 return IfStatement(condition, yes, no, loc)
203 211
204 def parseWhileStatement(self): 212 def parseWhileStatement(self):
205 loc = self.Consume('while').loc 213 loc = self.Consume('while').loc
206 self.Consume('(') 214 self.Consume('(')
207 condition = self.Expression() 215 condition = self.Expression()
208 self.Consume(')') 216 self.Consume(')')
209 statements = self.parseCompoundStatement() 217 statements = self.parseCompoundStatement()
210 return astnodes.WhileStatement(condition, statements, loc) 218 return WhileStatement(condition, statements, loc)
211 219
212 def parseReturnStatement(self): 220 def parseReturnStatement(self):
213 loc = self.Consume('return').loc 221 loc = self.Consume('return').loc
214 if self.Peak == ';': 222 if self.Peak == ';':
215 expr = astnodes.Literal(0, loc) 223 expr = Literal(0, loc)
216 else: 224 else:
217 expr = self.Expression() 225 expr = self.Expression()
218 self.Consume(';') 226 self.Consume(';')
219 return astnodes.ReturnStatement(expr, loc) 227 return ReturnStatement(expr, loc)
220 228
221 def parseCompoundStatement(self): 229 def parseCompoundStatement(self):
222 self.Consume('{') 230 self.Consume('{')
223 statements = [] 231 statements = []
224 while not self.hasConsumed('}'): 232 while not self.hasConsumed('}'):
225 s = self.Statement() 233 s = self.Statement()
226 if s is None: 234 if s is None:
227 continue 235 continue
228 statements.append(s) 236 statements.append(s)
229 return astnodes.CompoundStatement(statements) 237 return CompoundStatement(statements)
230 238
231 def Statement(self): 239 def Statement(self):
232 # Determine statement type based on the pending token: 240 # Determine statement type based on the pending token:
233 if self.Peak == 'if': 241 if self.Peak == 'if':
234 return self.parseIfStatement() 242 return self.parseIfStatement()
249 x = self.UnaryExpression() 257 x = self.UnaryExpression()
250 if self.Peak == '=': 258 if self.Peak == '=':
251 # We enter assignment mode here. 259 # We enter assignment mode here.
252 loc = self.Consume('=').loc 260 loc = self.Consume('=').loc
253 rhs = self.Expression() 261 rhs = self.Expression()
254 return astnodes.Assignment(x, rhs, loc) 262 return Assignment(x, rhs, loc)
255 else: 263 else:
256 return astnodes.ExpressionStatement(x, x.loc) 264 return ExpressionStatement(x, x.loc)
257 265
258 # Expression section: 266 # Expression section:
259 # We not implement these C constructs: 267 # We not implement these C constructs:
260 # a(2), f = 2 268 # a(2), f = 2
261 # and this: 269 # and this:
264 def Expression(self): 272 def Expression(self):
265 exp = self.LogicalAndExpression() 273 exp = self.LogicalAndExpression()
266 while self.Peak == 'or': 274 while self.Peak == 'or':
267 loc = self.Consume('or').loc 275 loc = self.Consume('or').loc
268 e2 = self.LogicalAndExpression() 276 e2 = self.LogicalAndExpression()
269 exp = astnodes.Binop(exp, 'or', e2, loc) 277 exp = Binop(exp, 'or', e2, loc)
270 return exp 278 return exp
271 279
272 def LogicalAndExpression(self): 280 def LogicalAndExpression(self):
273 o = self.EqualityExpression() 281 o = self.EqualityExpression()
274 while self.Peak == 'and': 282 while self.Peak == 'and':
275 loc = self.Consume('and').loc 283 loc = self.Consume('and').loc
276 o2 = self.EqualityExpression() 284 o2 = self.EqualityExpression()
277 o = astnodes.Binop(o, 'and', o2, loc) 285 o = Binop(o, 'and', o2, loc)
278 return o 286 return o
279 287
280 def EqualityExpression(self): 288 def EqualityExpression(self):
281 ee = self.SimpleExpression() 289 ee = self.SimpleExpression()
282 while self.Peak in ['<', '==', '>']: 290 while self.Peak in ['<', '==', '>']:
283 op = self.Consume(self.Peak) 291 op = self.Consume(self.Peak)
284 ee2 = self.SimpleExpression() 292 ee2 = self.SimpleExpression()
285 ee = astnodes.Binop(ee, op.typ, ee2, op.loc) 293 ee = Binop(ee, op.typ, ee2, op.loc)
286 return ee 294 return ee
287 295
288 def SimpleExpression(self): 296 def SimpleExpression(self):
289 """ Shift operations before + and - ? """ 297 """ Shift operations before + and - ? """
290 e = self.AddExpression() 298 e = self.AddExpression()
291 while self.Peak in ['>>', '<<']: 299 while self.Peak in ['>>', '<<']:
292 op = self.Consume(self.Peak) 300 op = self.Consume(self.Peak)
293 e2 = self.AddExpression() 301 e2 = self.AddExpression()
294 e = astnodes.Binop(e, op.typ, e2, op.loc) 302 e = Binop(e, op.typ, e2, op.loc)
295 return e 303 return e
296 304
297 def AddExpression(self): 305 def AddExpression(self):
298 e = self.Term() 306 e = self.Term()
299 while self.Peak in ['+', '-']: 307 while self.Peak in ['+', '-']:
300 op = self.Consume(self.Peak) 308 op = self.Consume(self.Peak)
301 e2 = self.Term() 309 e2 = self.Term()
302 e = astnodes.Binop(e, op.typ, e2, op.loc) 310 e = Binop(e, op.typ, e2, op.loc)
303 return e 311 return e
304 312
305 def Term(self): 313 def Term(self):
306 t = self.BitwiseOr() 314 t = self.BitwiseOr()
307 while self.Peak in ['*', '/']: 315 while self.Peak in ['*', '/']:
308 op = self.Consume(self.Peak) 316 op = self.Consume(self.Peak)
309 t2 = self.BitwiseOr() 317 t2 = self.BitwiseOr()
310 t = astnodes.Binop(t, op.typ, t2, op.loc) 318 t = Binop(t, op.typ, t2, op.loc)
311 return t 319 return t
312 320
313 def BitwiseOr(self): 321 def BitwiseOr(self):
314 a = self.BitwiseAnd() 322 a = self.BitwiseAnd()
315 while self.Peak in ['|']: 323 while self.Peak in ['|']:
316 op = self.Consume(self.Peak) 324 op = self.Consume(self.Peak)
317 b = self.BitwiseAnd() 325 b = self.BitwiseAnd()
318 a = astnodes.Binop(a, op.typ, b, op.loc) 326 a = Binop(a, op.typ, b, op.loc)
319 return a 327 return a
320 328
321 def BitwiseAnd(self): 329 def BitwiseAnd(self):
322 a = self.CastExpression() 330 a = self.CastExpression()
323 while self.Peak in ['&']: 331 while self.Peak in ['&']:
324 op = self.Consume(self.Peak) 332 op = self.Consume(self.Peak)
325 b = self.CastExpression() 333 b = self.CastExpression()
326 a = astnodes.Binop(a, op.typ, b, op.loc) 334 a = Binop(a, op.typ, b, op.loc)
327 return a 335 return a
328 336
329 # Domain of unary expressions: 337 # Domain of unary expressions:
330 338
331 def CastExpression(self): 339 def CastExpression(self):
339 t = self.parseTypeSpec() 347 t = self.parseTypeSpec()
340 self.Consume('>') 348 self.Consume('>')
341 self.Consume('(') 349 self.Consume('(')
342 ce = self.Expression() 350 ce = self.Expression()
343 self.Consume(')') 351 self.Consume(')')
344 return astnodes.TypeCast(t, ce, loc) 352 return TypeCast(t, ce, loc)
345 else: 353 else:
346 return self.UnaryExpression() 354 return self.UnaryExpression()
347 355
348 def UnaryExpression(self): 356 def UnaryExpression(self):
349 if self.Peak in ['&', '*']: 357 if self.Peak in ['&', '*']:
350 op = self.Consume(self.Peak) 358 op = self.Consume(self.Peak)
351 ce = self.CastExpression() 359 ce = self.CastExpression()
352 if op.val == '*': 360 if op.val == '*':
353 return astnodes.Deref(ce, op.loc) 361 return Deref(ce, op.loc)
354 else: 362 else:
355 return astnodes.Unop(op.typ, ce, op.loc) 363 return Unop(op.typ, ce, op.loc)
356 else: 364 else:
357 return self.PostFixExpression() 365 return self.PostFixExpression()
358 366
359 def PostFixExpression(self): 367 def PostFixExpression(self):
360 pfe = self.PrimaryExpression() 368 pfe = self.PrimaryExpression()
367 if not self.hasConsumed(')'): 375 if not self.hasConsumed(')'):
368 args.append(self.Expression()) 376 args.append(self.Expression())
369 while self.hasConsumed(','): 377 while self.hasConsumed(','):
370 args.append(self.Expression()) 378 args.append(self.Expression())
371 self.Consume(')') 379 self.Consume(')')
372 pfe = astnodes.FunctionCall(pfe, args, pfe.loc) 380 pfe = FunctionCall(pfe, args, pfe.loc)
373 elif self.hasConsumed('->'): 381 elif self.hasConsumed('->'):
374 field = self.Consume('ID') 382 field = self.Consume('ID')
375 pfe = astnodes.Deref(pfe, pfe.loc) 383 pfe = Deref(pfe, pfe.loc)
376 pfe = astnodes.FieldRef(pfe, field.val, field.loc) 384 pfe = FieldRef(pfe, field.val, field.loc)
377 elif self.hasConsumed('.'): 385 elif self.hasConsumed('.'):
378 field = self.Consume('ID') 386 field = self.Consume('ID')
379 pfe = astnodes.FieldRef(pfe, field.val, field.loc) 387 pfe = FieldRef(pfe, field.val, field.loc)
380 else: 388 else:
381 raise Exception() 389 raise Exception()
382 return pfe 390 return pfe
383 391
384 def PrimaryExpression(self): 392 def PrimaryExpression(self):
386 e = self.Expression() 394 e = self.Expression()
387 self.Consume(')') 395 self.Consume(')')
388 return e 396 return e
389 elif self.Peak == 'NUMBER': 397 elif self.Peak == 'NUMBER':
390 val = self.Consume('NUMBER') 398 val = self.Consume('NUMBER')
391 return astnodes.Literal(val.val, val.loc) 399 return Literal(val.val, val.loc)
392 elif self.Peak == 'REAL': 400 elif self.Peak == 'REAL':
393 val = self.Consume('REAL') 401 val = self.Consume('REAL')
394 return astnodes.Literal(val.val, val.loc) 402 return Literal(val.val, val.loc)
395 elif self.Peak == 'true': 403 elif self.Peak == 'true':
396 val = self.Consume('true') 404 val = self.Consume('true')
397 return astnodes.Literal(True, val.loc) 405 return Literal(True, val.loc)
398 elif self.Peak == 'false': 406 elif self.Peak == 'false':
399 val = self.Consume('false') 407 val = self.Consume('false')
400 return astnodes.Literal(False, val.loc) 408 return Literal(False, val.loc)
401 elif self.Peak == 'ID': 409 elif self.Peak == 'ID':
402 d = self.parseDesignator() 410 d = self.parseDesignator()
403 return astnodes.VariableUse(d, d.loc) 411 return VariableUse(d, d.loc)
404 self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak)) 412 self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak))