1 #include "stdafx.h"
2 #include "ExpressionParser.h"
3
4 static ExpressionInternal* expression(Tokenizer& tokenizer);
5
6 static bool allowFunctionCall = true;
7
allowFunctionCallExpression(bool allow)8 void allowFunctionCallExpression(bool allow)
9 {
10 allowFunctionCall = allow;
11 }
12
primaryExpression(Tokenizer & tokenizer)13 static ExpressionInternal* primaryExpression(Tokenizer& tokenizer)
14 {
15 const Token &tok = tokenizer.peekToken();
16
17 switch (tok.type)
18 {
19 case TokenType::Float:
20 tokenizer.eatToken();
21 return new ExpressionInternal(tok.floatValue);
22 case TokenType::Identifier:
23 {
24 const std::wstring stringValue = tok.getStringValue();
25 tokenizer.eatToken();
26 if (stringValue == L".")
27 return new ExpressionInternal(OperatorType::MemoryPos);
28 else
29 return new ExpressionInternal(stringValue,OperatorType::Identifier);
30 }
31 case TokenType::String:
32 tokenizer.eatToken();
33 return new ExpressionInternal(tok.getStringValue(),OperatorType::String);
34 case TokenType::Integer:
35 tokenizer.eatToken();
36 return new ExpressionInternal(tok.intValue);
37 case TokenType::LParen:
38 {
39 tokenizer.eatToken();
40 ExpressionInternal* exp = expression(tokenizer);
41
42 if (tokenizer.nextToken().type != TokenType::RParen)
43 {
44 delete exp;
45 return nullptr;
46 }
47
48 return exp;
49 }
50 case TokenType::Invalid:
51 default:
52 break;
53 }
54
55 return nullptr;
56 }
57
postfixExpression(Tokenizer & tokenizer)58 static ExpressionInternal* postfixExpression(Tokenizer& tokenizer)
59 {
60 if (allowFunctionCall &&
61 tokenizer.peekToken(0).type == TokenType::Identifier &&
62 tokenizer.peekToken(1).type == TokenType::LParen)
63 {
64 const std::wstring functionName = tokenizer.nextToken().getStringValue();
65 tokenizer.eatToken();
66
67 std::vector<ExpressionInternal*> parameters;
68 while (tokenizer.peekToken().type != TokenType::RParen)
69 {
70 if (parameters.size() != 0 && tokenizer.nextToken().type != TokenType::Comma)
71 {
72 for (ExpressionInternal* exp: parameters)
73 delete exp;
74 return nullptr;
75 }
76
77 ExpressionInternal* exp = expression(tokenizer);
78 if (exp == nullptr)
79 {
80 for (ExpressionInternal* exp: parameters)
81 delete exp;
82 return nullptr;
83 }
84
85 parameters.push_back(exp);
86 }
87
88 tokenizer.eatToken();
89
90 return new ExpressionInternal(functionName,parameters);
91 }
92
93 return primaryExpression(tokenizer);
94 }
95
unaryExpression(Tokenizer & tokenizer)96 static ExpressionInternal* unaryExpression(Tokenizer& tokenizer)
97 {
98 ExpressionInternal* exp = postfixExpression(tokenizer);
99 if (exp != nullptr)
100 return exp;
101
102 const TokenType opType = tokenizer.nextToken().type;
103 exp = postfixExpression(tokenizer);
104 if (exp == nullptr)
105 return nullptr;
106
107 switch (opType)
108 {
109 case TokenType::Plus:
110 return exp;
111 case TokenType::Minus:
112 return new ExpressionInternal(OperatorType::Neg,exp);
113 case TokenType::Tilde:
114 return new ExpressionInternal(OperatorType::BitNot,exp);
115 case TokenType::Exclamation:
116 return new ExpressionInternal(OperatorType::LogNot,exp);
117 case TokenType::Degree:
118 return new ExpressionInternal(OperatorType::ToString,exp);
119 default:
120 delete exp;
121 return nullptr;
122 }
123 }
124
multiplicativeExpression(Tokenizer & tokenizer)125 static ExpressionInternal* multiplicativeExpression(Tokenizer& tokenizer)
126 {
127 ExpressionInternal* exp = unaryExpression(tokenizer);
128 if (exp == nullptr)
129 return nullptr;
130
131 while (true)
132 {
133 OperatorType op = OperatorType::Invalid;
134 switch (tokenizer.peekToken().type)
135 {
136 case TokenType::Mult:
137 op = OperatorType::Mult;
138 break;
139 case TokenType::Div:
140 op = OperatorType::Div;
141 break;
142 case TokenType::Mod:
143 op = OperatorType::Mod;
144 break;
145 default:
146 break;
147 }
148
149 if (op == OperatorType::Invalid)
150 break;
151
152 tokenizer.eatToken();
153
154 ExpressionInternal* exp2 = unaryExpression(tokenizer);
155 if (exp2 == nullptr)
156 {
157 delete exp;
158 return nullptr;
159 }
160
161 exp = new ExpressionInternal(op,exp,exp2);
162 }
163
164 return exp;
165 }
166
additiveExpression(Tokenizer & tokenizer)167 static ExpressionInternal* additiveExpression(Tokenizer& tokenizer)
168 {
169 ExpressionInternal* exp = multiplicativeExpression(tokenizer);
170 if (exp == nullptr)
171 return nullptr;
172
173 while (true)
174 {
175 OperatorType op = OperatorType::Invalid;
176 switch (tokenizer.peekToken().type)
177 {
178 case TokenType::Plus:
179 op = OperatorType::Add;
180 break;
181 case TokenType::Minus:
182 op = OperatorType::Sub;
183 break;
184 default:
185 break;
186 }
187
188 if (op == OperatorType::Invalid)
189 break;
190
191 tokenizer.eatToken();
192
193 ExpressionInternal* exp2 = multiplicativeExpression(tokenizer);
194 if (exp2 == nullptr)
195 {
196 delete exp;
197 return nullptr;
198 }
199
200 exp = new ExpressionInternal(op,exp,exp2);
201 }
202
203 return exp;
204 }
205
shiftExpression(Tokenizer & tokenizer)206 static ExpressionInternal* shiftExpression(Tokenizer& tokenizer)
207 {
208 ExpressionInternal* exp = additiveExpression(tokenizer);
209 if (exp == nullptr)
210 return nullptr;
211
212 while (true)
213 {
214 OperatorType op = OperatorType::Invalid;
215 switch (tokenizer.peekToken().type)
216 {
217 case TokenType::LeftShift:
218 op = OperatorType::LeftShift;
219 break;
220 case TokenType::RightShift:
221 op = OperatorType::RightShift;
222 break;
223 default:
224 break;
225 }
226
227 if (op == OperatorType::Invalid)
228 break;
229
230 tokenizer.eatToken();
231
232 ExpressionInternal* exp2 = additiveExpression(tokenizer);
233 if (exp2 == nullptr)
234 {
235 delete exp;
236 return nullptr;
237 }
238
239 exp = new ExpressionInternal(op,exp,exp2);
240 }
241
242 return exp;
243 }
244
relationalExpression(Tokenizer & tokenizer)245 static ExpressionInternal* relationalExpression(Tokenizer& tokenizer)
246 {
247 ExpressionInternal* exp = shiftExpression(tokenizer);
248 if (exp == nullptr)
249 return nullptr;
250
251 while (true)
252 {
253 OperatorType op = OperatorType::Invalid;
254 switch (tokenizer.peekToken().type)
255 {
256 case TokenType::Less:
257 op = OperatorType::Less;
258 break;
259 case TokenType::LessEqual:
260 op = OperatorType::LessEqual;
261 break;
262 case TokenType::Greater:
263 op = OperatorType::Greater;
264 break;
265 case TokenType::GreaterEqual:
266 op = OperatorType::GreaterEqual;
267 break;
268 default:
269 break;
270 }
271
272 if (op == OperatorType::Invalid)
273 break;
274
275 tokenizer.eatToken();
276
277 ExpressionInternal* exp2 = shiftExpression(tokenizer);
278 if (exp2 == nullptr)
279 {
280 delete exp;
281 return nullptr;
282 }
283
284 exp = new ExpressionInternal(op,exp,exp2);
285 }
286
287 return exp;
288 }
289
equalityExpression(Tokenizer & tokenizer)290 static ExpressionInternal* equalityExpression(Tokenizer& tokenizer)
291 {
292 ExpressionInternal* exp = relationalExpression(tokenizer);
293 if (exp == nullptr)
294 return nullptr;
295
296 while (true)
297 {
298 OperatorType op = OperatorType::Invalid;
299 switch (tokenizer.peekToken().type)
300 {
301 case TokenType::Equal:
302 op = OperatorType::Equal;
303 break;
304 case TokenType::NotEqual:
305 op = OperatorType::NotEqual;
306 break;
307 default:
308 break;
309 }
310
311 if (op == OperatorType::Invalid)
312 break;
313
314 tokenizer.eatToken();
315
316 ExpressionInternal* exp2 = relationalExpression(tokenizer);
317 if (exp2 == nullptr)
318 {
319 delete exp;
320 return nullptr;
321 }
322
323 exp = new ExpressionInternal(op,exp,exp2);
324 }
325
326 return exp;
327 }
328
andExpression(Tokenizer & tokenizer)329 static ExpressionInternal* andExpression(Tokenizer& tokenizer)
330 {
331 ExpressionInternal* exp = equalityExpression(tokenizer);
332 if (exp == nullptr)
333 return nullptr;
334
335 while (tokenizer.peekToken().type == TokenType::BitAnd)
336 {
337 tokenizer.eatToken();
338
339 ExpressionInternal* exp2 = equalityExpression(tokenizer);
340 if (exp2 == nullptr)
341 {
342 delete exp;
343 return nullptr;
344 }
345
346 exp = new ExpressionInternal(OperatorType::BitAnd,exp,exp2);
347 }
348
349 return exp;
350 }
351
exclusiveOrExpression(Tokenizer & tokenizer)352 static ExpressionInternal* exclusiveOrExpression(Tokenizer& tokenizer)
353 {
354 ExpressionInternal* exp = andExpression(tokenizer);
355 if (exp == nullptr)
356 return nullptr;
357
358 while (tokenizer.peekToken().type == TokenType::Caret)
359 {
360 tokenizer.eatToken();
361
362 ExpressionInternal* exp2 = andExpression(tokenizer);
363 if (exp2 == nullptr)
364 {
365 delete exp;
366 return nullptr;
367 }
368
369 exp = new ExpressionInternal(OperatorType::Xor,exp,exp2);
370 }
371
372 return exp;
373 }
374
inclusiveOrExpression(Tokenizer & tokenizer)375 static ExpressionInternal* inclusiveOrExpression(Tokenizer& tokenizer)
376 {
377 ExpressionInternal* exp = exclusiveOrExpression(tokenizer);
378 if (exp == nullptr)
379 return nullptr;
380
381 while (tokenizer.peekToken().type == TokenType::BitOr)
382 {
383 tokenizer.eatToken();
384
385 ExpressionInternal* exp2 = exclusiveOrExpression(tokenizer);
386 if (exp2 == nullptr)
387 {
388 delete exp;
389 return nullptr;
390 }
391
392 exp = new ExpressionInternal(OperatorType::BitOr,exp,exp2);
393 }
394
395 return exp;
396 }
397
logicalAndExpression(Tokenizer & tokenizer)398 static ExpressionInternal* logicalAndExpression(Tokenizer& tokenizer)
399 {
400 ExpressionInternal* exp = inclusiveOrExpression(tokenizer);
401 if (exp == nullptr)
402 return nullptr;
403
404 while (tokenizer.peekToken().type == TokenType::LogAnd)
405 {
406 tokenizer.eatToken();
407
408 ExpressionInternal* exp2 = inclusiveOrExpression(tokenizer);
409 if (exp2 == nullptr)
410 {
411 delete exp;
412 return nullptr;
413 }
414
415 exp = new ExpressionInternal(OperatorType::LogAnd,exp,exp2);
416 }
417
418 return exp;
419 }
420
logicalOrExpression(Tokenizer & tokenizer)421 static ExpressionInternal* logicalOrExpression(Tokenizer& tokenizer)
422 {
423 ExpressionInternal* exp = logicalAndExpression(tokenizer);
424 if (exp == nullptr)
425 return nullptr;
426
427 while (tokenizer.peekToken().type == TokenType::LogOr)
428 {
429 tokenizer.eatToken();
430
431 ExpressionInternal* exp2 = logicalAndExpression(tokenizer);
432 if (exp2 == nullptr)
433 {
434 delete exp;
435 return nullptr;
436 }
437
438 exp = new ExpressionInternal(OperatorType::LogOr,exp,exp2);
439 }
440
441 return exp;
442 }
443
conditionalExpression(Tokenizer & tokenizer)444 static ExpressionInternal* conditionalExpression(Tokenizer& tokenizer)
445 {
446 ExpressionInternal* exp = logicalOrExpression(tokenizer);
447 if (exp == nullptr)
448 return nullptr;
449
450 // check a ? b : c
451 if (tokenizer.peekToken().type != TokenType::Question)
452 return exp;
453
454 tokenizer.eatToken();
455 ExpressionInternal* second = expression(tokenizer);
456
457 if (second != nullptr && tokenizer.nextToken().type == TokenType::Colon)
458 {
459 ExpressionInternal* third = expression(tokenizer);
460 if (third != nullptr)
461 return new ExpressionInternal(OperatorType::TertiaryIf,exp,second,third);
462
463 delete third;
464 }
465
466 delete second;
467 delete exp;
468 return nullptr;
469 }
470
expression(Tokenizer & tokenizer)471 static ExpressionInternal* expression(Tokenizer& tokenizer)
472 {
473 return conditionalExpression(tokenizer);
474 }
475
parseExpression(Tokenizer & tokenizer,bool inUnknownOrFalseBlock)476 Expression parseExpression(Tokenizer& tokenizer, bool inUnknownOrFalseBlock)
477 {
478 TokenizerPosition pos = tokenizer.getPosition();
479
480 // parse expression, revert tokenizer to previous position
481 // if it failed
482 ExpressionInternal* exp = expression(tokenizer);
483 if (exp == nullptr)
484 tokenizer.setPosition(pos);
485
486 Expression result;
487 result.setExpression(exp, inUnknownOrFalseBlock);
488 return result;
489 }
490