Mercurial > lcfOS
comparison python/ppci/c3/parser.py @ 354:5477e499b039
Added some sort of string functionality
author | Windel Bouwman |
---|---|
date | Thu, 13 Mar 2014 18:59:06 +0100 |
parents | d1ecc493384e |
children | c05ab629976a |
comparison
equal
deleted
inserted
replaced
353:b8ad45b3a573 | 354:5477e499b039 |
---|---|
1 import logging | 1 import logging |
2 from ppci import CompilerError | 2 from .. import CompilerError |
3 from .astnodes import Member, Literal, TypeCast, Unop, Binop | 3 from .astnodes import Member, Literal, TypeCast, Unop, Binop |
4 from .astnodes import Assignment, ExpressionStatement, Compound | 4 from .astnodes import Assignment, ExpressionStatement, Compound |
5 from .astnodes import Return, While, If, Empty, For | 5 from .astnodes import Return, While, If, Empty, For |
6 from .astnodes import FunctionType, Function, FormalParameter | 6 from .astnodes import FunctionType, Function, FormalParameter |
7 from .astnodes import StructureType, DefinedType, PointerType | 7 from .astnodes import StructureType, DefinedType, PointerType, ArrayType |
8 from .astnodes import Constant, Variable | 8 from .astnodes import Constant, Variable |
9 from .astnodes import StructField, Deref | 9 from .astnodes import StructField, Deref, Index |
10 from .astnodes import Package | 10 from .astnodes import Package |
11 from .astnodes import Identifier | 11 from .astnodes import Identifier |
12 from .astnodes import FunctionCall | 12 from .astnodes import FunctionCall |
13 | 13 |
14 | 14 |
103 while self.hasConsumed(','): | 103 while self.hasConsumed(','): |
104 ids.append(self.Consume('ID')) | 104 ids.append(self.Consume('ID')) |
105 return ids | 105 return ids |
106 | 106 |
107 # Type system | 107 # Type system |
108 def parseTypeSpec(self): | 108 def PostFixId(self): |
109 # For now, do simple type spec, just parse an ID: | 109 pfe = self.PrimaryExpression_Id() |
110 while self.Peak in ['.']: | |
111 if self.hasConsumed('.'): | |
112 field = self.Consume('ID') | |
113 pfe = Member(pfe, field.val, field.loc) | |
114 else: | |
115 raise Exception() | |
116 return pfe | |
117 | |
118 def PrimaryExpression_Id(self): | |
119 if self.Peak == 'ID': | |
120 return self.parseDesignator() | |
121 self.Error('Expected ID, got {0}'.format(self.Peak)) | |
122 | |
123 def parse_type_spec(self): | |
124 """ Parse type specification """ | |
110 if self.Peak == 'struct': | 125 if self.Peak == 'struct': |
111 self.Consume('struct') | 126 self.Consume('struct') |
112 self.Consume('{') | 127 self.Consume('{') |
113 mems = [] | 128 mems = [] |
114 while self.Peak != '}': | 129 while self.Peak != '}': |
115 mem_t = self.parseTypeSpec() | 130 mem_t = self.parse_type_spec() |
116 for i in self.parseIdSequence(): | 131 for i in self.parseIdSequence(): |
117 mems.append(StructField(i.val, mem_t)) | 132 mems.append(StructField(i.val, mem_t)) |
118 self.Consume(';') | 133 self.Consume(';') |
119 self.Consume('}') | 134 self.Consume('}') |
120 theT = StructureType(mems) | 135 theT = StructureType(mems) |
121 elif self.Peak == 'enum': | 136 elif self.Peak == 'enum': |
122 # TODO) | 137 # TODO) |
123 raise NotImplementedError() | 138 raise NotImplementedError() |
124 else: | 139 else: |
125 theT = self.PostFixExpression() | 140 theT = self.PostFixId() |
126 # Check for pointer suffix: | 141 |
127 while self.hasConsumed('*'): | 142 # Check for pointer or array suffix: |
128 theT = PointerType(theT) | 143 while self.Peak in ['*', '[']: |
144 if self.hasConsumed('*'): | |
145 theT = PointerType(theT) | |
146 elif self.hasConsumed('['): | |
147 if self.Peak == ']': | |
148 size = 0 | |
149 self.Consume(']') | |
150 else: | |
151 size = self.Expression() | |
152 self.Consume(']') | |
153 theT = ArrayType(theT, size) | |
154 else: | |
155 raise Exception() | |
129 return theT | 156 return theT |
130 | 157 |
131 def parseTypeDef(self): | 158 def parseTypeDef(self): |
132 self.Consume('type') | 159 self.Consume('type') |
133 newtype = self.parseTypeSpec() | 160 newtype = self.parse_type_spec() |
134 typename = self.Consume('ID') | 161 typename = self.Consume('ID') |
135 self.Consume(';') | 162 self.Consume(';') |
136 df = DefinedType(typename.val, newtype, typename.loc) | 163 df = DefinedType(typename.val, newtype, typename.loc) |
137 self.addDeclaration(df) | 164 self.addDeclaration(df) |
138 | 165 |
139 # Variable declarations: | 166 # Variable declarations: |
140 def parseVarDef(self): | 167 def parseVarDef(self): |
141 self.Consume('var') | 168 self.Consume('var') |
142 t = self.parseTypeSpec() | 169 t = self.parse_type_spec() |
143 for name in self.parseIdSequence(): | 170 for name in self.parseIdSequence(): |
144 v = Variable(name.val, t) | 171 v = Variable(name.val, t) |
145 v.loc = name.loc | 172 v.loc = name.loc |
146 self.addDeclaration(v) | 173 self.addDeclaration(v) |
147 self.Consume(';') | 174 self.Consume(';') |
148 return Empty() | 175 return Empty() |
149 | 176 |
150 def parseConstDef(self): | 177 def parseConstDef(self): |
151 self.Consume('const') | 178 self.Consume('const') |
152 t = self.parseTypeSpec() | 179 t = self.parse_type_spec() |
153 while True: | 180 while True: |
154 name = self.Consume('ID') | 181 name = self.Consume('ID') |
155 self.Consume('=') | 182 self.Consume('=') |
156 val = self.Expression() | 183 val = self.Expression() |
157 c = Constant(name.val, t, val) | 184 c = Constant(name.val, t, val) |
161 break | 188 break |
162 self.Consume(';') | 189 self.Consume(';') |
163 | 190 |
164 def parseFunctionDef(self): | 191 def parseFunctionDef(self): |
165 loc = self.Consume('function').loc | 192 loc = self.Consume('function').loc |
166 returntype = self.parseTypeSpec() | 193 returntype = self.parse_type_spec() |
167 fname = self.Consume('ID').val | 194 fname = self.Consume('ID').val |
168 f = Function(fname, loc) | 195 f = Function(fname, loc) |
169 self.addDeclaration(f) | 196 self.addDeclaration(f) |
170 savePart = self.currentPart | 197 savePart = self.currentPart |
171 self.currentPart = f | 198 self.currentPart = f |
172 self.Consume('(') | 199 self.Consume('(') |
173 parameters = [] | 200 parameters = [] |
174 if not self.hasConsumed(')'): | 201 if not self.hasConsumed(')'): |
175 while True: | 202 while True: |
176 typ = self.parseTypeSpec() | 203 typ = self.parse_type_spec() |
177 name = self.Consume('ID') | 204 name = self.Consume('ID') |
178 param = FormalParameter(name.val, typ) | 205 param = FormalParameter(name.val, typ) |
179 param.loc = name.loc | 206 param.loc = name.loc |
180 self.addDeclaration(param) | 207 self.addDeclaration(param) |
181 parameters.append(param) | 208 parameters.append(param) |
185 paramtypes = [p.typ for p in parameters] | 212 paramtypes = [p.typ for p in parameters] |
186 f.typ = FunctionType(paramtypes, returntype) | 213 f.typ = FunctionType(paramtypes, returntype) |
187 f.body = self.parseCompound() | 214 f.body = self.parseCompound() |
188 self.currentPart = savePart | 215 self.currentPart = savePart |
189 | 216 |
190 def parseIf(self): | 217 def parse_if(self): |
191 loc = self.Consume('if').loc | 218 loc = self.Consume('if').loc |
192 self.Consume('(') | 219 self.Consume('(') |
193 condition = self.Expression() | 220 condition = self.Expression() |
194 self.Consume(')') | 221 self.Consume(')') |
195 yes = self.Statement() | 222 yes = self.Statement() |
202 condition = self.Expression() | 229 condition = self.Expression() |
203 self.Consume(')') | 230 self.Consume(')') |
204 statements = self.Statement() | 231 statements = self.Statement() |
205 return While(condition, statements, loc) | 232 return While(condition, statements, loc) |
206 | 233 |
207 def parseFor(self): | 234 def parse_for(self): |
208 loc = self.Consume('for').loc | 235 loc = self.Consume('for').loc |
209 self.Consume('(') | 236 self.Consume('(') |
210 init = self.Statement() | 237 init = self.Statement() |
211 self.Consume(';') | 238 self.Consume(';') |
212 condition = self.Expression() | 239 condition = self.Expression() |
233 return Compound(statements) | 260 return Compound(statements) |
234 | 261 |
235 def Statement(self): | 262 def Statement(self): |
236 # Determine statement type based on the pending token: | 263 # Determine statement type based on the pending token: |
237 if self.Peak == 'if': | 264 if self.Peak == 'if': |
238 return self.parseIf() | 265 return self.parse_if() |
239 elif self.Peak == 'while': | 266 elif self.Peak == 'while': |
240 return self.parseWhile() | 267 return self.parseWhile() |
241 elif self.Peak == 'for': | 268 elif self.Peak == 'for': |
242 return self.parseFor() | 269 return self.parse_for() |
243 elif self.Peak == '{': | 270 elif self.Peak == '{': |
244 return self.parseCompound() | 271 return self.parseCompound() |
245 elif self.hasConsumed(';'): | 272 elif self.hasConsumed(';'): |
246 return Empty() | 273 return Empty() |
247 elif self.Peak == 'var': | 274 elif self.Peak == 'var': |
337 so introduce extra keyword 'cast' | 364 so introduce extra keyword 'cast' |
338 """ | 365 """ |
339 if self.Peak == 'cast': | 366 if self.Peak == 'cast': |
340 loc = self.Consume('cast').loc | 367 loc = self.Consume('cast').loc |
341 self.Consume('<') | 368 self.Consume('<') |
342 t = self.parseTypeSpec() | 369 t = self.parse_type_spec() |
343 self.Consume('>') | 370 self.Consume('>') |
344 self.Consume('(') | 371 self.Consume('(') |
345 ce = self.Expression() | 372 ce = self.Expression() |
346 self.Consume(')') | 373 self.Consume(')') |
347 return TypeCast(t, ce, loc) | 374 return TypeCast(t, ce, loc) |
361 | 388 |
362 def PostFixExpression(self): | 389 def PostFixExpression(self): |
363 pfe = self.PrimaryExpression() | 390 pfe = self.PrimaryExpression() |
364 while self.Peak in ['[', '.', '->', '(', '++']: | 391 while self.Peak in ['[', '.', '->', '(', '++']: |
365 if self.hasConsumed('['): | 392 if self.hasConsumed('['): |
366 raise NotImplementedError('Array not yet implemented') | 393 i = self.Expression() |
394 self.Consume(']') | |
395 pfe = Index(pfe, i, i.loc) | |
367 elif self.hasConsumed('->'): | 396 elif self.hasConsumed('->'): |
368 field = self.Consume('ID') | 397 field = self.Consume('ID') |
369 pfe = Deref(pfe, pfe.loc) | 398 pfe = Deref(pfe, pfe.loc) |
370 pfe = Member(pfe, field.val, field.loc) | 399 pfe = Member(pfe, field.val, field.loc) |
371 elif self.hasConsumed('.'): | 400 elif self.hasConsumed('.'): |
408 val = self.Consume('STRING') | 437 val = self.Consume('STRING') |
409 return Literal(val.val, val.loc) | 438 return Literal(val.val, val.loc) |
410 elif self.Peak == 'ID': | 439 elif self.Peak == 'ID': |
411 return self.parseDesignator() | 440 return self.parseDesignator() |
412 self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak)) | 441 self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak)) |
442 |