Mercurial > lcfOS
annotate python/ppci/c3/parser.py @ 300:158068af716c
yafm
author | Windel Bouwman |
---|---|
date | Tue, 03 Dec 2013 18:00:22 +0100 |
parents | python/c3/parser.py@9417caea2eb3 |
children | 6753763d3bec |
rev | line source |
---|---|
254 | 1 import logging |
293 | 2 from .lexer import Lexer |
296 | 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 | |
152 | 12 from ppci import CompilerError |
148 | 13 |
288 | 14 |
148 | 15 class Parser: |
213 | 16 """ Parses sourcecode into an abstract syntax tree (AST) """ |
17 def __init__(self, diag): | |
254 | 18 self.logger = logging.getLogger('c3') |
213 | 19 self.diag = diag |
293 | 20 self.lexer = Lexer(diag) |
213 | 21 |
22 def parseSource(self, source): | |
254 | 23 self.logger.info('Parsing source') |
24 self.initLex(source) | |
25 try: | |
26 self.parsePackage() | |
27 return self.mod | |
28 except CompilerError as e: | |
29 self.diag.addDiag(e) | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
30 |
213 | 31 def Error(self, msg): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
32 raise CompilerError(msg, self.token.loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
33 |
213 | 34 # Lexer helpers: |
35 def Consume(self, typ): | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
36 if self.Peak == typ: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
37 return self.NextToken() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
38 else: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
39 self.Error('Excected: "{0}", got "{1}"'.format(typ, self.Peak)) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
40 |
213 | 41 @property |
42 def Peak(self): | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
43 return self.token.typ |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
44 |
228 | 45 @property |
46 def CurLoc(self): | |
47 return self.token.loc | |
48 | |
213 | 49 def hasConsumed(self, typ): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
50 if self.Peak == typ: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
51 self.Consume(typ) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
52 return True |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
53 return False |
213 | 54 |
55 def NextToken(self): | |
219 | 56 t = self.token |
57 if t.typ != 'END': | |
58 self.token = self.tokens.__next__() | |
59 return t | |
213 | 60 |
61 def initLex(self, source): | |
293 | 62 self.tokens = self.lexer.tokenize(source) |
219 | 63 self.token = self.tokens.__next__() |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
64 |
215 | 65 def addDeclaration(self, decl): |
66 self.currentPart.declarations.append(decl) | |
288 | 67 |
251
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
68 def parseImport(self): |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
69 self.Consume('import') |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
70 name = self.Consume('ID').val |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
71 self.mod.imports.append(name) |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
72 self.Consume(';') |
213 | 73 |
74 def parsePackage(self): | |
284 | 75 self.Consume('module') |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
76 name = self.Consume('ID') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
77 self.Consume(';') |
296 | 78 self.mod = Package(name.val, name.loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
79 self.currentPart = self.mod |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
80 while self.Peak != 'END': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
81 self.parseTopLevel() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
82 self.Consume('END') |
148 | 83 |
213 | 84 def parseTopLevel(self): |
251
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
85 if self.Peak == 'function': |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
86 self.parseFunctionDef() |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
87 elif self.Peak == 'var': |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
88 self.parseVarDef() |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
89 elif self.Peak == 'const': |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
90 self.parseConstDef() |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
91 elif self.Peak == 'type': |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
92 self.parseTypeDef() |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
93 elif self.Peak == 'import': |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
94 self.parseImport() |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
95 else: |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
232
diff
changeset
|
96 self.Error('Expected function, var, const or type') |
148 | 97 |
213 | 98 def parseDesignator(self): |
225 | 99 """ A designator designates an object """ |
100 name = self.Consume('ID') | |
289 | 101 if self.hasConsumed(':'): |
102 name2 = self.Consume('ID') | |
296 | 103 return ImportDesignator(name.val, name2.val, name.loc) |
289 | 104 else: |
296 | 105 return Designator(name.val, name.loc) |
148 | 106 |
213 | 107 # Type system |
108 def parseTypeSpec(self): | |
109 # For now, do simple type spec, just parse an ID: | |
219 | 110 #return self.parseDesignator() |
213 | 111 if self.Peak == 'struct': |
112 self.Consume('struct') | |
113 self.Consume('{') | |
114 mems = [] | |
115 while self.Peak != '}': | |
116 mem_t = self.parseTypeSpec() | |
226 | 117 mem_n = self.Consume('ID').val |
296 | 118 mems.append(StructField(mem_n, mem_t)) |
213 | 119 while self.hasConsumed(','): |
226 | 120 mem_n = self.Consume('ID').val |
296 | 121 mems.append(StructField(mem_n, mem_t)) |
213 | 122 self.Consume(';') |
123 self.Consume('}') | |
296 | 124 theT = StructureType(mems) |
213 | 125 else: |
126 theT = self.parseDesignator() | |
127 # Check for pointer suffix: | |
128 while self.hasConsumed('*'): | |
296 | 129 theT = PointerType(theT) |
213 | 130 return theT |
131 | |
132 def parseTypeDef(self): | |
133 self.Consume('type') | |
134 newtype = self.parseTypeSpec() | |
135 typename = self.Consume('ID') | |
136 self.Consume(';') | |
296 | 137 df = DefinedType(typename.val, newtype, typename.loc) |
225 | 138 self.addDeclaration(df) |
213 | 139 |
140 # Variable declarations: | |
141 def parseVarDef(self): | |
272 | 142 self.Consume('var') |
143 t = self.parseTypeSpec() | |
300 | 144 |
272 | 145 def parseVar(): |
146 name = self.Consume('ID') | |
296 | 147 v = Variable(name.val, t) |
272 | 148 v.loc = name.loc |
149 if self.hasConsumed('='): | |
150 v.ival = self.Expression() | |
151 self.addDeclaration(v) | |
152 parseVar() | |
153 while self.hasConsumed(','): | |
154 parseVar() | |
155 self.Consume(';') | |
148 | 156 |
213 | 157 def parseConstDef(self): |
280
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
158 self.Consume('const') |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
159 t = self.parseTypeSpec() |
300 | 160 |
280
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
161 def parseConst(): |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
162 name = self.Consume('ID') |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
163 self.Consume('=') |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
164 val = self.Expression() |
296 | 165 c = Constant(name.val, t, val) |
280
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
166 c.loc = name.loc |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
167 parseConst() |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
168 while self.hasConsumed(','): |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
169 parseConst() |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
170 self.Consume(';') |
288 | 171 |
213 | 172 # Procedures |
173 def parseFunctionDef(self): | |
280
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
174 loc = self.Consume('function').loc |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
175 returntype = self.parseTypeSpec() |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
176 fname = self.Consume('ID').val |
296 | 177 f = Function(fname, loc) |
280
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
178 self.addDeclaration(f) |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
179 savePart = self.currentPart |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
180 self.currentPart = f |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
181 self.Consume('(') |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
182 parameters = [] |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
183 if not self.hasConsumed(')'): |
272 | 184 def parseParameter(): |
185 typ = self.parseTypeSpec() | |
186 name = self.Consume('ID') | |
296 | 187 param = FormalParameter(name.val, typ) |
272 | 188 param.loc = name.loc |
189 self.addDeclaration(param) | |
190 parameters.append(param) | |
150 | 191 parseParameter() |
272 | 192 while self.hasConsumed(','): |
193 parseParameter() | |
194 self.Consume(')') | |
280
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
195 paramtypes = [p.typ for p in parameters] |
296 | 196 f.typ = FunctionType(paramtypes, returntype) |
280
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
197 f.body = self.parseCompoundStatement() |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
198 self.currentPart = savePart |
148 | 199 |
213 | 200 # Statements: |
148 | 201 |
213 | 202 def parseIfStatement(self): |
272 | 203 loc = self.Consume('if').loc |
204 self.Consume('(') | |
205 condition = self.Expression() | |
206 self.Consume(')') | |
207 yes = self.parseCompoundStatement() | |
208 if self.hasConsumed('else'): | |
209 no = self.parseCompoundStatement() | |
210 else: | |
211 no = None | |
296 | 212 return IfStatement(condition, yes, no, loc) |
148 | 213 |
213 | 214 def parseWhileStatement(self): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
215 loc = self.Consume('while').loc |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
216 self.Consume('(') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
217 condition = self.Expression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
218 self.Consume(')') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
219 statements = self.parseCompoundStatement() |
296 | 220 return WhileStatement(condition, statements, loc) |
149 | 221 |
213 | 222 def parseReturnStatement(self): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
223 loc = self.Consume('return').loc |
280
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
224 if self.Peak == ';': |
296 | 225 expr = Literal(0, loc) |
280
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
226 else: |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
227 expr = self.Expression() |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
228 self.Consume(';') |
296 | 229 return ReturnStatement(expr, loc) |
148 | 230 |
213 | 231 def parseCompoundStatement(self): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
232 self.Consume('{') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
233 statements = [] |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
234 while not self.hasConsumed('}'): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
235 s = self.Statement() |
228 | 236 if s is None: |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
237 continue |
166 | 238 statements.append(s) |
296 | 239 return CompoundStatement(statements) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
240 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
241 def Statement(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
242 # Determine statement type based on the pending token: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
243 if self.Peak == 'if': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
244 return self.parseIfStatement() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
245 elif self.Peak == 'while': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
246 return self.parseWhileStatement() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
247 elif self.Peak == '{': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
248 return self.parseCompoundStatement() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
249 elif self.hasConsumed(';'): |
228 | 250 pass |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
251 elif self.Peak == 'var': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
252 self.parseVarDef() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
253 elif self.Peak == 'return': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
254 return self.parseReturnStatement() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
255 else: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
256 return self.AssignmentOrCall() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
257 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
258 def AssignmentOrCall(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
259 x = self.UnaryExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
260 if self.Peak == '=': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
261 # We enter assignment mode here. |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
262 loc = self.Consume('=').loc |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
263 rhs = self.Expression() |
296 | 264 return Assignment(x, rhs, loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
265 else: |
296 | 266 return ExpressionStatement(x, x.loc) |
148 | 267 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
268 # Expression section: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
269 # We not implement these C constructs: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
270 # a(2), f = 2 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
271 # and this: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
272 # a = 2 < x : 4 ? 1; |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
273 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
274 def Expression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
275 exp = self.LogicalAndExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
276 while self.Peak == 'or': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
277 loc = self.Consume('or').loc |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
278 e2 = self.LogicalAndExpression() |
296 | 279 exp = Binop(exp, 'or', e2, loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
280 return exp |
148 | 281 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
282 def LogicalAndExpression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
283 o = self.EqualityExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
284 while self.Peak == 'and': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
285 loc = self.Consume('and').loc |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
286 o2 = self.EqualityExpression() |
296 | 287 o = Binop(o, 'and', o2, loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
288 return o |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
289 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
290 def EqualityExpression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
291 ee = self.SimpleExpression() |
300 | 292 while self.Peak in ['<', '==', '>', '>=', '<=', '!=']: |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
293 op = self.Consume(self.Peak) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
294 ee2 = self.SimpleExpression() |
296 | 295 ee = Binop(ee, op.typ, ee2, op.loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
296 return ee |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
297 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
298 def SimpleExpression(self): |
232 | 299 """ Shift operations before + and - ? """ |
300 e = self.AddExpression() | |
301 while self.Peak in ['>>', '<<']: | |
302 op = self.Consume(self.Peak) | |
303 e2 = self.AddExpression() | |
296 | 304 e = Binop(e, op.typ, e2, op.loc) |
232 | 305 return e |
306 | |
307 def AddExpression(self): | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
308 e = self.Term() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
309 while self.Peak in ['+', '-']: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
310 op = self.Consume(self.Peak) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
311 e2 = self.Term() |
296 | 312 e = Binop(e, op.typ, e2, op.loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
313 return e |
213 | 314 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
315 def Term(self): |
221 | 316 t = self.BitwiseOr() |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
317 while self.Peak in ['*', '/']: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
318 op = self.Consume(self.Peak) |
221 | 319 t2 = self.BitwiseOr() |
296 | 320 t = Binop(t, op.typ, t2, op.loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
321 return t |
221 | 322 |
323 def BitwiseOr(self): | |
324 a = self.BitwiseAnd() | |
325 while self.Peak in ['|']: | |
326 op = self.Consume(self.Peak) | |
327 b = self.BitwiseAnd() | |
296 | 328 a = Binop(a, op.typ, b, op.loc) |
221 | 329 return a |
330 | |
331 def BitwiseAnd(self): | |
332 a = self.CastExpression() | |
333 while self.Peak in ['&']: | |
334 op = self.Consume(self.Peak) | |
335 b = self.CastExpression() | |
296 | 336 a = Binop(a, op.typ, b, op.loc) |
221 | 337 return a |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
338 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
339 # Domain of unary expressions: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
340 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
341 def CastExpression(self): |
228 | 342 """ |
343 the C-style type cast conflicts with '(' expr ')' | |
344 so introduce extra keyword 'cast' | |
345 """ | |
221 | 346 if self.Peak == 'cast': |
230 | 347 loc = self.Consume('cast').loc |
221 | 348 self.Consume('<') |
349 t = self.parseTypeSpec() | |
350 self.Consume('>') | |
351 self.Consume('(') | |
232 | 352 ce = self.Expression() |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
353 self.Consume(')') |
296 | 354 return TypeCast(t, ce, loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
355 else: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
356 return self.UnaryExpression() |
230 | 357 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
358 def UnaryExpression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
359 if self.Peak in ['&', '*']: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
360 op = self.Consume(self.Peak) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
361 ce = self.CastExpression() |
225 | 362 if op.val == '*': |
296 | 363 return Deref(ce, op.loc) |
225 | 364 else: |
296 | 365 return Unop(op.typ, ce, op.loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
366 else: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
367 return self.PostFixExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
368 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
369 def PostFixExpression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
370 pfe = self.PrimaryExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
371 while self.Peak in ['[', '(', '.', '->']: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
372 if self.hasConsumed('['): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
373 pass |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
374 elif self.hasConsumed('('): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
375 # Function call |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
376 args = [] |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
377 if not self.hasConsumed(')'): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
378 args.append(self.Expression()) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
379 while self.hasConsumed(','): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
380 args.append(self.Expression()) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
381 self.Consume(')') |
296 | 382 pfe = FunctionCall(pfe, args, pfe.loc) |
225 | 383 elif self.hasConsumed('->'): |
384 field = self.Consume('ID') | |
296 | 385 pfe = Deref(pfe, pfe.loc) |
386 pfe = FieldRef(pfe, field.val, field.loc) | |
225 | 387 elif self.hasConsumed('.'): |
388 field = self.Consume('ID') | |
296 | 389 pfe = FieldRef(pfe, field.val, field.loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
390 else: |
225 | 391 raise Exception() |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
392 return pfe |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
393 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
394 def PrimaryExpression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
395 if self.hasConsumed('('): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
396 e = self.Expression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
397 self.Consume(')') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
398 return e |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
399 elif self.Peak == 'NUMBER': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
400 val = self.Consume('NUMBER') |
296 | 401 return Literal(val.val, val.loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
402 elif self.Peak == 'REAL': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
403 val = self.Consume('REAL') |
296 | 404 return Literal(val.val, val.loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
405 elif self.Peak == 'true': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
406 val = self.Consume('true') |
296 | 407 return Literal(True, val.loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
408 elif self.Peak == 'false': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
409 val = self.Consume('false') |
296 | 410 return Literal(False, val.loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
411 elif self.Peak == 'ID': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
412 d = self.parseDesignator() |
296 | 413 return VariableUse(d, d.loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
414 self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak)) |