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