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