Mercurial > lcfOS
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)) |