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