OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 | |
7 #include "xfa/src/fxfa/fm2js/xfa_fmparse.h" | |
8 | |
9 #include <memory> | |
10 | |
11 CXFA_FMParse::CXFA_FMParse() : m_pToken(nullptr), m_pErrorInfo(0) {} | |
12 | |
13 int32_t CXFA_FMParse::Init(const CFX_WideStringC& wsFormcalc, | |
14 CXFA_FMErrorInfo* pErrorInfo) { | |
15 m_pErrorInfo = pErrorInfo; | |
16 m_lexer.reset(new CXFA_FMLexer(wsFormcalc, m_pErrorInfo)); | |
17 return 0; | |
18 } | |
19 | |
20 void CXFA_FMParse::NextToken() { | |
21 m_pToken = m_lexer->NextToken(); | |
22 while (m_pToken->m_type == TOKreserver) { | |
23 if (m_lexer->HasError()) { | |
24 break; | |
25 } | |
26 m_pToken = m_lexer->NextToken(); | |
27 } | |
28 } | |
29 | |
30 void CXFA_FMParse::Check(XFA_FM_TOKEN op) { | |
31 if (m_pToken->m_type != op) { | |
32 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
33 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, | |
34 XFA_FM_KeywordToString(op), ws_TempString.c_str()); | |
35 } | |
36 NextToken(); | |
37 } | |
38 | |
39 void CXFA_FMParse::Error(FX_DWORD lineNum, XFA_FM_ERRMSG msg, ...) { | |
40 m_pErrorInfo->linenum = lineNum; | |
41 const FX_WCHAR* lpMessageInfo = XFA_FM_ErrorMsg(msg); | |
42 va_list ap; | |
43 va_start(ap, msg); | |
44 m_pErrorInfo->message.FormatV(lpMessageInfo, ap); | |
45 va_end(ap); | |
46 } | |
47 | |
48 CFX_PtrArray* CXFA_FMParse::ParseTopExpression() { | |
49 std::unique_ptr<CXFA_FMExpression> e; | |
50 CFX_PtrArray* expression = new CFX_PtrArray(); | |
51 while (1) { | |
52 if (m_pToken->m_type == TOKeof || m_pToken->m_type == TOKendfunc || | |
53 m_pToken->m_type == TOKendif || m_pToken->m_type == TOKelseif || | |
54 m_pToken->m_type == TOKelse || m_pToken->m_type == TOKreserver) { | |
55 return expression; | |
56 } | |
57 | |
58 if (m_pToken->m_type == TOKfunc) { | |
59 e.reset(ParseFunction()); | |
60 if (e) { | |
61 expression->Add(e.release()); | |
62 } else { | |
63 break; | |
64 } | |
65 } else { | |
66 e.reset(ParseExpression()); | |
67 if (e) { | |
68 expression->Add(e.release()); | |
69 } else { | |
70 break; | |
71 } | |
72 } | |
73 } | |
74 return expression; | |
75 } | |
76 | |
77 CXFA_FMExpression* CXFA_FMParse::ParseFunction() { | |
78 std::unique_ptr<CXFA_FMExpression> e; | |
79 CFX_WideStringC ident; | |
80 std::unique_ptr<CFX_WideStringCArray> pArguments; | |
81 std::unique_ptr<CFX_PtrArray> pExpressions; | |
82 FX_DWORD line = m_pToken->m_uLinenum; | |
83 NextToken(); | |
84 if (m_pToken->m_type != TOKidentifier) { | |
85 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
86 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, | |
87 ws_TempString.c_str()); | |
88 } else { | |
89 ident = m_pToken->m_wstring; | |
90 NextToken(); | |
91 } | |
92 Check(TOKlparen); | |
93 if (m_pToken->m_type == TOKrparen) { | |
94 NextToken(); | |
95 } else { | |
96 pArguments.reset(new CFX_WideStringCArray()); | |
97 CFX_WideStringC p; | |
98 while (1) { | |
99 if (m_pToken->m_type == TOKidentifier) { | |
100 p = m_pToken->m_wstring; | |
101 pArguments->Add(p); | |
102 NextToken(); | |
103 if (m_pToken->m_type == TOKcomma) { | |
104 NextToken(); | |
105 continue; | |
106 } else if (m_pToken->m_type == TOKrparen) { | |
107 NextToken(); | |
108 break; | |
109 } else { | |
110 Check(TOKrparen); | |
111 break; | |
112 } | |
113 } else { | |
114 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
115 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, | |
116 ws_TempString.c_str()); | |
117 NextToken(); | |
118 break; | |
119 } | |
120 } | |
121 } | |
122 Check(TOKdo); | |
123 if (m_pToken->m_type == TOKendfunc) { | |
124 NextToken(); | |
125 } else { | |
126 pExpressions.reset(ParseTopExpression()); | |
127 Check(TOKendfunc); | |
128 } | |
129 if (m_pErrorInfo->message.IsEmpty()) { | |
130 e.reset(new CXFA_FMFunctionDefinition(line, 0, ident, pArguments.release(), | |
131 pExpressions.release())); | |
132 } else { | |
133 if (pArguments) | |
134 pArguments->RemoveAll(); | |
135 if (pExpressions) { | |
136 for (int i = 0; i < pExpressions->GetSize(); ++i) | |
137 delete static_cast<CXFA_FMExpression*>(pExpressions->GetAt(i)); | |
138 } | |
139 } | |
140 return e.release(); | |
141 } | |
142 | |
143 CXFA_FMExpression* CXFA_FMParse::ParseExpression() { | |
144 std::unique_ptr<CXFA_FMExpression> e; | |
145 FX_DWORD line = m_pToken->m_uLinenum; | |
146 switch (m_pToken->m_type) { | |
147 case TOKvar: | |
148 e.reset(ParseVarExpression()); | |
149 break; | |
150 case TOKnull: | |
151 case TOKnumber: | |
152 case TOKstring: | |
153 case TOKplus: | |
154 case TOKminus: | |
155 case TOKksnot: | |
156 case TOKidentifier: | |
157 case TOKlparen: | |
158 e.reset(ParseExpExpression()); | |
159 break; | |
160 case TOKif: | |
161 e.reset(ParseIfExpression()); | |
162 break; | |
163 case TOKwhile: | |
164 e.reset(ParseWhileExpression()); | |
165 break; | |
166 case TOKfor: | |
167 e.reset(ParseForExpression()); | |
168 break; | |
169 case TOKforeach: | |
170 e.reset(ParseForeachExpression()); | |
171 break; | |
172 case TOKdo: | |
173 e.reset(ParseDoExpression()); | |
174 break; | |
175 case TOKbreak: | |
176 e.reset(new CXFA_FMBreakExpression(line)); | |
177 NextToken(); | |
178 break; | |
179 case TOKcontinue: | |
180 e.reset(new CXFA_FMContinueExpression(line)); | |
181 NextToken(); | |
182 break; | |
183 default: | |
184 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
185 Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION, | |
186 ws_TempString.c_str()); | |
187 NextToken(); | |
188 break; | |
189 } | |
190 return e.release(); | |
191 } | |
192 | |
193 CXFA_FMExpression* CXFA_FMParse::ParseVarExpression() { | |
194 std::unique_ptr<CXFA_FMExpression> e; | |
195 CFX_WideStringC ident; | |
196 FX_DWORD line = m_pToken->m_uLinenum; | |
197 NextToken(); | |
198 if (m_pToken->m_type != TOKidentifier) { | |
199 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
200 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, | |
201 ws_TempString.c_str()); | |
202 } else { | |
203 ident = m_pToken->m_wstring; | |
204 NextToken(); | |
205 } | |
206 if (m_pToken->m_type == TOKassign) { | |
207 NextToken(); | |
208 e.reset(ParseExpExpression()); | |
209 } | |
210 if (m_pErrorInfo->message.IsEmpty()) { | |
211 e.reset(new CXFA_FMVarExpression(line, ident, e.release())); | |
212 } else { | |
213 e.reset(); | |
214 } | |
215 return e.release(); | |
216 } | |
217 | |
218 CXFA_FMSimpleExpression* CXFA_FMParse::ParseSimpleExpression() { | |
219 FX_DWORD line = m_pToken->m_uLinenum; | |
220 std::unique_ptr<CXFA_FMSimpleExpression> pExp1(ParseLogicalOrExpression()); | |
221 while (m_pToken->m_type == TOKassign) { | |
222 NextToken(); | |
223 std::unique_ptr<CXFA_FMSimpleExpression> pExp2(ParseLogicalOrExpression()); | |
224 if (m_pErrorInfo->message.IsEmpty()) { | |
225 pExp1.reset(new CXFA_FMAssignExpression(line, TOKassign, pExp1.release(), | |
226 pExp2.release())); | |
227 } else { | |
228 pExp1.reset(); | |
229 } | |
230 } | |
231 return pExp1.release(); | |
232 } | |
233 | |
234 CXFA_FMExpression* CXFA_FMParse::ParseExpExpression() { | |
235 FX_DWORD line = m_pToken->m_uLinenum; | |
236 std::unique_ptr<CXFA_FMSimpleExpression> pExp1(ParseSimpleExpression()); | |
237 std::unique_ptr<CXFA_FMExpression> e; | |
238 if (m_pErrorInfo->message.IsEmpty()) { | |
239 e.reset(new CXFA_FMExpExpression(line, pExp1.release())); | |
240 } else { | |
241 e.reset(); | |
242 } | |
243 return e.release(); | |
244 } | |
245 | |
246 CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalOrExpression() { | |
247 FX_DWORD line = m_pToken->m_uLinenum; | |
248 std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseLogicalAndExpression()); | |
249 for (;;) { | |
250 switch (m_pToken->m_type) { | |
251 case TOKor: | |
252 case TOKksor: { | |
253 NextToken(); | |
254 std::unique_ptr<CXFA_FMSimpleExpression> e2( | |
255 ParseLogicalAndExpression()); | |
256 if (m_pErrorInfo->message.IsEmpty()) { | |
257 e1.reset(new CXFA_FMLogicalOrExpression(line, TOKor, e1.release(), | |
258 e2.release())); | |
259 } else { | |
260 e1.reset(); | |
261 } | |
262 continue; | |
263 } | |
264 default: | |
265 break; | |
266 } | |
267 break; | |
268 } | |
269 return e1.release(); | |
270 } | |
271 | |
272 CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalAndExpression() { | |
273 FX_DWORD line = m_pToken->m_uLinenum; | |
274 std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseEqualityExpression()); | |
275 for (;;) { | |
276 switch (m_pToken->m_type) { | |
277 case TOKand: | |
278 case TOKksand: { | |
279 NextToken(); | |
280 std::unique_ptr<CXFA_FMSimpleExpression> e2(ParseEqualityExpression()); | |
281 if (m_pErrorInfo->message.IsEmpty()) { | |
282 e1.reset(new CXFA_FMLogicalAndExpression(line, TOKand, e1.release(), | |
283 e2.release())); | |
284 } else { | |
285 e1.reset(); | |
286 } | |
287 continue; | |
288 } | |
289 default: | |
290 break; | |
291 } | |
292 break; | |
293 } | |
294 return e1.release(); | |
295 } | |
296 | |
297 CXFA_FMSimpleExpression* CXFA_FMParse::ParseEqualityExpression() { | |
298 FX_DWORD line = m_pToken->m_uLinenum; | |
299 std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseRelationalExpression()); | |
300 for (;;) { | |
301 std::unique_ptr<CXFA_FMSimpleExpression> e2; | |
302 switch (m_pToken->m_type) { | |
303 case TOKeq: | |
304 case TOKkseq: | |
305 NextToken(); | |
306 e2.reset(ParseRelationalExpression()); | |
307 if (m_pErrorInfo->message.IsEmpty()) { | |
308 e1.reset(new CXFA_FMEqualityExpression(line, TOKeq, e1.release(), | |
309 e2.release())); | |
310 } else { | |
311 e1.reset(); | |
312 } | |
313 continue; | |
314 case TOKne: | |
315 case TOKksne: | |
316 NextToken(); | |
317 e2.reset(ParseRelationalExpression()); | |
318 if (m_pErrorInfo->message.IsEmpty()) { | |
319 e1.reset(new CXFA_FMEqualityExpression(line, TOKne, e1.release(), | |
320 e2.release())); | |
321 } else { | |
322 e1.reset(); | |
323 } | |
324 continue; | |
325 default: | |
326 break; | |
327 } | |
328 break; | |
329 } | |
330 return e1.release(); | |
331 } | |
332 | |
333 CXFA_FMSimpleExpression* CXFA_FMParse::ParseRelationalExpression() { | |
334 FX_DWORD line = m_pToken->m_uLinenum; | |
335 std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseAddtiveExpression()); | |
336 for (;;) { | |
337 std::unique_ptr<CXFA_FMSimpleExpression> e2; | |
338 switch (m_pToken->m_type) { | |
339 case TOKlt: | |
340 case TOKkslt: | |
341 NextToken(); | |
342 e2.reset(ParseAddtiveExpression()); | |
343 if (m_pErrorInfo->message.IsEmpty()) { | |
344 e1.reset(new CXFA_FMRelationalExpression(line, TOKlt, e1.release(), | |
345 e2.release())); | |
346 } else { | |
347 e1.reset(); | |
348 } | |
349 continue; | |
350 case TOKgt: | |
351 case TOKksgt: | |
352 NextToken(); | |
353 e2.reset(ParseAddtiveExpression()); | |
354 if (m_pErrorInfo->message.IsEmpty()) { | |
355 e1.reset(new CXFA_FMRelationalExpression(line, TOKgt, e1.release(), | |
356 e2.release())); | |
357 } else { | |
358 e1.reset(); | |
359 } | |
360 continue; | |
361 case TOKle: | |
362 case TOKksle: | |
363 NextToken(); | |
364 e2.reset(ParseAddtiveExpression()); | |
365 if (m_pErrorInfo->message.IsEmpty()) { | |
366 e1.reset(new CXFA_FMRelationalExpression(line, TOKle, e1.release(), | |
367 e2.release())); | |
368 } else { | |
369 e1.reset(); | |
370 } | |
371 continue; | |
372 case TOKge: | |
373 case TOKksge: | |
374 NextToken(); | |
375 e2.reset(ParseAddtiveExpression()); | |
376 if (m_pErrorInfo->message.IsEmpty()) { | |
377 e1.reset(new CXFA_FMRelationalExpression(line, TOKge, e1.release(), | |
378 e2.release())); | |
379 } else { | |
380 e1.reset(); | |
381 } | |
382 continue; | |
383 default: | |
384 break; | |
385 } | |
386 break; | |
387 } | |
388 return e1.release(); | |
389 } | |
390 | |
391 CXFA_FMSimpleExpression* CXFA_FMParse::ParseAddtiveExpression() { | |
392 FX_DWORD line = m_pToken->m_uLinenum; | |
393 std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseMultiplicativeExpression()); | |
394 for (;;) { | |
395 std::unique_ptr<CXFA_FMSimpleExpression> e2; | |
396 switch (m_pToken->m_type) { | |
397 case TOKplus: | |
398 NextToken(); | |
399 e2.reset(ParseMultiplicativeExpression()); | |
400 if (m_pErrorInfo->message.IsEmpty()) { | |
401 e1.reset(new CXFA_FMAdditiveExpression(line, TOKplus, e1.release(), | |
402 e2.release())); | |
403 } else { | |
404 e1.reset(); | |
405 } | |
406 continue; | |
407 case TOKminus: | |
408 NextToken(); | |
409 e2.reset(ParseMultiplicativeExpression()); | |
410 if (m_pErrorInfo->message.IsEmpty()) { | |
411 e1.reset(new CXFA_FMAdditiveExpression(line, TOKminus, e1.release(), | |
412 e2.release())); | |
413 } else { | |
414 e1.reset(); | |
415 } | |
416 continue; | |
417 default: | |
418 break; | |
419 } | |
420 break; | |
421 } | |
422 return e1.release(); | |
423 } | |
424 | |
425 CXFA_FMSimpleExpression* CXFA_FMParse::ParseMultiplicativeExpression() { | |
426 FX_DWORD line = m_pToken->m_uLinenum; | |
427 std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseUnaryExpression()); | |
428 for (;;) { | |
429 std::unique_ptr<CXFA_FMSimpleExpression> e2; | |
430 switch (m_pToken->m_type) { | |
431 case TOKmul: | |
432 NextToken(); | |
433 e2.reset(ParseUnaryExpression()); | |
434 if (m_pErrorInfo->message.IsEmpty()) { | |
435 e1.reset(new CXFA_FMMultiplicativeExpression( | |
436 line, TOKmul, e1.release(), e2.release())); | |
437 } else { | |
438 e1.reset(); | |
439 } | |
440 continue; | |
441 case TOKdiv: | |
442 NextToken(); | |
443 e2.reset(ParseUnaryExpression()); | |
444 if (m_pErrorInfo->message.IsEmpty()) { | |
445 e1.reset(new CXFA_FMMultiplicativeExpression( | |
446 line, TOKdiv, e1.release(), e2.release())); | |
447 } else { | |
448 e1.reset(); | |
449 } | |
450 continue; | |
451 default: | |
452 break; | |
453 } | |
454 break; | |
455 } | |
456 return e1.release(); | |
457 } | |
458 | |
459 CXFA_FMSimpleExpression* CXFA_FMParse::ParseUnaryExpression() { | |
460 std::unique_ptr<CXFA_FMSimpleExpression> e; | |
461 FX_DWORD line = m_pToken->m_uLinenum; | |
462 switch (m_pToken->m_type) { | |
463 case TOKplus: | |
464 NextToken(); | |
465 e.reset(ParseUnaryExpression()); | |
466 if (m_pErrorInfo->message.IsEmpty()) { | |
467 e.reset(new CXFA_FMPosExpression(line, e.release())); | |
468 } else { | |
469 e.reset(); | |
470 } | |
471 break; | |
472 case TOKminus: | |
473 NextToken(); | |
474 e.reset(ParseUnaryExpression()); | |
475 if (m_pErrorInfo->message.IsEmpty()) { | |
476 e.reset(new CXFA_FMNegExpression(line, e.release())); | |
477 } else { | |
478 e.reset(); | |
479 } | |
480 break; | |
481 case TOKksnot: | |
482 NextToken(); | |
483 e.reset(ParseUnaryExpression()); | |
484 if (m_pErrorInfo->message.IsEmpty()) { | |
485 e.reset(new CXFA_FMNotExpression(line, e.release())); | |
486 } else { | |
487 e.reset(); | |
488 } | |
489 break; | |
490 default: | |
491 e.reset(ParsePrimaryExpression()); | |
492 break; | |
493 } | |
494 return e.release(); | |
495 } | |
496 | |
497 CXFA_FMSimpleExpression* CXFA_FMParse::ParsePrimaryExpression() { | |
498 std::unique_ptr<CXFA_FMSimpleExpression> e; | |
499 FX_DWORD line = m_pToken->m_uLinenum; | |
500 switch (m_pToken->m_type) { | |
501 case TOKnumber: | |
502 e.reset(new CXFA_FMNumberExpression(line, m_pToken->m_wstring)); | |
503 NextToken(); | |
504 break; | |
505 case TOKstring: | |
506 e.reset(new CXFA_FMStringExpression(line, m_pToken->m_wstring)); | |
507 NextToken(); | |
508 break; | |
509 case TOKidentifier: { | |
510 CFX_WideStringC wsIdentifier(m_pToken->m_wstring); | |
511 NextToken(); | |
512 if (m_pToken->m_type == TOKlbracket) { | |
513 CXFA_FMSimpleExpression* s = ParseIndexExpression(); | |
514 if (s) { | |
515 e.reset(new CXFA_FMDotAccessorExpression(line, NULL, TOKdot, | |
516 wsIdentifier, s)); | |
517 } | |
518 NextToken(); | |
519 } else { | |
520 e.reset(new CXFA_FMIdentifierExpressionn(line, wsIdentifier)); | |
521 } | |
522 } break; | |
523 case TOKif: | |
524 e.reset(new CXFA_FMIdentifierExpressionn(line, m_pToken->m_wstring)); | |
525 NextToken(); | |
526 break; | |
527 case TOKnull: | |
528 e.reset(new CXFA_FMNullExpression(line)); | |
529 NextToken(); | |
530 break; | |
531 case TOKlparen: | |
532 e.reset(ParseParenExpression()); | |
533 break; | |
534 default: | |
535 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
536 Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION, | |
537 ws_TempString.c_str()); | |
538 NextToken(); | |
539 break; | |
540 } | |
541 e.reset(ParsePostExpression(e.release())); | |
542 if (!(m_pErrorInfo->message.IsEmpty())) | |
543 e.reset(); | |
544 return e.release(); | |
545 } | |
546 | |
547 CXFA_FMSimpleExpression* CXFA_FMParse::ParsePostExpression( | |
548 CXFA_FMSimpleExpression* e) { | |
549 FX_DWORD line = m_pToken->m_uLinenum; | |
550 while (1) { | |
551 switch (m_pToken->m_type) { | |
552 case TOKlparen: { | |
553 NextToken(); | |
554 std::unique_ptr<CFX_PtrArray> pArray; | |
555 if (m_pToken->m_type != TOKrparen) { | |
556 pArray.reset(new CFX_PtrArray()); | |
557 while (m_pToken->m_type != TOKrparen) { | |
558 CXFA_FMSimpleExpression* e = ParseSimpleExpression(); | |
559 if (e) { | |
560 pArray->Add(e); | |
561 } | |
562 if (m_pToken->m_type == TOKcomma) { | |
563 NextToken(); | |
564 } else if (m_pToken->m_type == TOKeof || | |
565 m_pToken->m_type == TOKreserver) { | |
566 break; | |
567 } | |
568 } | |
569 if (m_pToken->m_type != TOKrparen) { | |
570 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
571 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, | |
572 XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str()); | |
573 } | |
574 } | |
575 if (m_pErrorInfo->message.IsEmpty()) { | |
576 e = new CXFA_FMCallExpression(line, e, pArray.release(), FALSE); | |
577 NextToken(); | |
578 if (m_pToken->m_type != TOKlbracket) { | |
579 continue; | |
580 } | |
581 CXFA_FMSimpleExpression* s = ParseIndexExpression(); | |
582 if (s) { | |
583 e = new CXFA_FMDotAccessorExpression(line, e, TOKcall, | |
584 FX_WSTRC(L""), s); | |
585 } else { | |
586 delete e; | |
587 e = nullptr; | |
588 } | |
589 } else { | |
590 if (pArray) { | |
591 for (int32_t i = 0; i < pArray->GetSize(); ++i) | |
592 delete static_cast<CXFA_FMSimpleExpression*>(pArray->GetAt(i)); | |
593 } | |
594 delete e; | |
595 e = nullptr; | |
596 } | |
597 } break; | |
598 case TOKdot: | |
599 NextToken(); | |
600 if (m_pToken->m_type == TOKidentifier) { | |
601 CFX_WideStringC tempStr = m_pToken->m_wstring; | |
602 FX_DWORD tempLine = m_pToken->m_uLinenum; | |
603 NextToken(); | |
604 if (m_pToken->m_type == TOKlparen) { | |
605 CXFA_FMSimpleExpression* pExpAccessor; | |
606 CXFA_FMSimpleExpression* pExpCall; | |
607 pExpAccessor = e; | |
608 NextToken(); | |
609 std::unique_ptr<CFX_PtrArray> pArray; | |
610 if (m_pToken->m_type != TOKrparen) { | |
611 pArray.reset(new CFX_PtrArray()); | |
612 while (m_pToken->m_type != TOKrparen) { | |
613 CXFA_FMSimpleExpression* exp = ParseSimpleExpression(); | |
614 pArray->Add(exp); | |
615 if (m_pToken->m_type == TOKcomma) { | |
616 NextToken(); | |
617 } else if (m_pToken->m_type == TOKeof || | |
618 m_pToken->m_type == TOKreserver) { | |
619 break; | |
620 } | |
621 } | |
622 if (m_pToken->m_type != TOKrparen) { | |
623 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
624 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, | |
625 XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str()); | |
626 } | |
627 } | |
628 if (m_pErrorInfo->message.IsEmpty()) { | |
629 CXFA_FMSimpleExpression* pIdentifier = | |
630 new CXFA_FMIdentifierExpressionn(tempLine, tempStr); | |
631 pExpCall = new CXFA_FMCallExpression(line, pIdentifier, | |
632 pArray.release(), TRUE); | |
633 e = new CXFA_FMMethodCallExpression(line, pExpAccessor, pExpCall); | |
634 NextToken(); | |
635 if (m_pToken->m_type != TOKlbracket) { | |
636 continue; | |
637 } | |
638 CXFA_FMSimpleExpression* s = ParseIndexExpression(); | |
639 if (s) { | |
640 e = new CXFA_FMDotAccessorExpression(line, e, TOKcall, | |
641 FX_WSTRC(L""), s); | |
642 } else { | |
643 delete e; | |
644 e = nullptr; | |
645 } | |
646 } else { | |
647 if (pArray) { | |
648 for (int32_t i = 0; i < pArray->GetSize(); ++i) { | |
649 delete static_cast<CXFA_FMSimpleExpression*>( | |
650 pArray->GetAt(i)); | |
651 } | |
652 } | |
653 delete e; | |
654 e = nullptr; | |
655 } | |
656 } else if (m_pToken->m_type == TOKlbracket) { | |
657 std::unique_ptr<CXFA_FMSimpleExpression> s(ParseIndexExpression()); | |
658 if (!(m_pErrorInfo->message.IsEmpty())) { | |
659 delete e; | |
660 return nullptr; | |
661 } | |
662 e = new CXFA_FMDotAccessorExpression(tempLine, e, TOKdot, tempStr, | |
663 s.release()); | |
664 } else { | |
665 CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression( | |
666 tempLine, ACCESSOR_NO_INDEX, NULL, FALSE); | |
667 e = new CXFA_FMDotAccessorExpression(line, e, TOKdot, tempStr, s); | |
668 continue; | |
669 } | |
670 } else { | |
671 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
672 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, | |
673 ws_TempString.c_str()); | |
674 return e; | |
675 } | |
676 break; | |
677 case TOKdotdot: | |
678 NextToken(); | |
679 if (m_pToken->m_type == TOKidentifier) { | |
680 CFX_WideStringC tempStr = m_pToken->m_wstring; | |
681 FX_DWORD tempLine = m_pToken->m_uLinenum; | |
682 NextToken(); | |
683 if (m_pToken->m_type == TOKlbracket) { | |
684 std::unique_ptr<CXFA_FMSimpleExpression> s(ParseIndexExpression()); | |
685 if (!(m_pErrorInfo->message.IsEmpty())) { | |
686 delete e; | |
687 return nullptr; | |
688 } | |
689 e = new CXFA_FMDotDotAccessorExpression(tempLine, e, TOKdotdot, | |
690 tempStr, s.release()); | |
691 } else { | |
692 CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression( | |
693 tempLine, ACCESSOR_NO_INDEX, NULL, FALSE); | |
694 e = new CXFA_FMDotDotAccessorExpression(line, e, TOKdotdot, tempStr, | |
695 s); | |
696 continue; | |
697 } | |
698 } else { | |
699 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
700 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, | |
701 ws_TempString.c_str()); | |
702 return e; | |
703 } | |
704 break; | |
705 case TOKdotscream: | |
706 NextToken(); | |
707 if (m_pToken->m_type == TOKidentifier) { | |
708 CFX_WideStringC tempStr = m_pToken->m_wstring; | |
709 FX_DWORD tempLine = m_pToken->m_uLinenum; | |
710 NextToken(); | |
711 if (m_pToken->m_type == TOKlbracket) { | |
712 std::unique_ptr<CXFA_FMSimpleExpression> s(ParseIndexExpression()); | |
713 if (!(m_pErrorInfo->message.IsEmpty())) { | |
714 delete e; | |
715 return nullptr; | |
716 } | |
717 e = new CXFA_FMDotAccessorExpression(tempLine, e, TOKdotscream, | |
718 tempStr, s.release()); | |
719 } else { | |
720 CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression( | |
721 tempLine, ACCESSOR_NO_INDEX, NULL, FALSE); | |
722 e = new CXFA_FMDotAccessorExpression(line, e, TOKdotscream, tempStr, | |
723 s); | |
724 continue; | |
725 } | |
726 } else { | |
727 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
728 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, | |
729 ws_TempString.c_str()); | |
730 return e; | |
731 } | |
732 break; | |
733 case TOKdotstar: { | |
734 CXFA_FMSimpleExpression* s = | |
735 new CXFA_FMIndexExpression(line, ACCESSOR_NO_INDEX, NULL, FALSE); | |
736 e = new CXFA_FMDotAccessorExpression(line, e, TOKdotstar, | |
737 FX_WSTRC(L"*"), s); | |
738 } break; | |
739 default: | |
740 return e; | |
741 } | |
742 NextToken(); | |
743 } | |
744 return e; | |
745 } | |
746 | |
747 CXFA_FMSimpleExpression* CXFA_FMParse::ParseIndexExpression() { | |
748 std::unique_ptr<CXFA_FMSimpleExpression> pExp; | |
749 FX_DWORD line = m_pToken->m_uLinenum; | |
750 NextToken(); | |
751 std::unique_ptr<CXFA_FMSimpleExpression> s; | |
752 XFA_FM_AccessorIndex accessorIndex = ACCESSOR_NO_RELATIVEINDEX; | |
753 if (m_pToken->m_type == TOKmul) { | |
754 pExp.reset( | |
755 new CXFA_FMIndexExpression(line, accessorIndex, s.release(), TRUE)); | |
756 NextToken(); | |
757 if (m_pToken->m_type != TOKrbracket) { | |
758 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
759 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, | |
760 XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str()); | |
761 pExp.reset(); | |
762 } | |
763 return pExp.release(); | |
764 } | |
765 if (m_pToken->m_type == TOKplus) { | |
766 accessorIndex = ACCESSOR_POSITIVE_INDEX; | |
767 NextToken(); | |
768 } else if (m_pToken->m_type == TOKminus) { | |
769 accessorIndex = ACCESSOR_NEGATIVE_INDEX; | |
770 NextToken(); | |
771 } | |
772 s.reset(ParseSimpleExpression()); | |
773 if (m_pToken->m_type != TOKrbracket) { | |
774 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
775 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, | |
776 XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str()); | |
777 } else { | |
778 pExp.reset( | |
779 new CXFA_FMIndexExpression(line, accessorIndex, s.release(), FALSE)); | |
780 } | |
781 return pExp.release(); | |
782 } | |
783 | |
784 CXFA_FMSimpleExpression* CXFA_FMParse::ParseParenExpression() { | |
785 Check(TOKlparen); | |
786 | |
787 if (m_pToken->m_type == TOKrparen) { | |
788 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_NON_EMPTY_EXPRESSION); | |
789 NextToken(); | |
790 return nullptr; | |
791 } | |
792 | |
793 FX_DWORD line = m_pToken->m_uLinenum; | |
794 std::unique_ptr<CXFA_FMSimpleExpression> pExp1(ParseLogicalOrExpression()); | |
795 | |
796 while (m_pToken->m_type == TOKassign) { | |
797 NextToken(); | |
798 std::unique_ptr<CXFA_FMSimpleExpression> pExp2(ParseLogicalOrExpression()); | |
799 if (m_pErrorInfo->message.IsEmpty()) { | |
800 pExp1.reset(new CXFA_FMAssignExpression(line, TOKassign, pExp1.release(), | |
801 pExp2.release())); | |
802 } else { | |
803 pExp1.reset(); | |
804 } | |
805 } | |
806 Check(TOKrparen); | |
807 return pExp1.release(); | |
808 } | |
809 | |
810 CXFA_FMExpression* CXFA_FMParse::ParseBlockExpression() { | |
811 FX_DWORD line = m_pToken->m_uLinenum; | |
812 CXFA_FMExpression* e = nullptr; | |
813 std::unique_ptr<CFX_PtrArray> expression(new CFX_PtrArray()); | |
814 while (1) { | |
815 switch (m_pToken->m_type) { | |
816 case TOKeof: | |
817 case TOKendif: | |
818 case TOKelseif: | |
819 case TOKelse: | |
820 case TOKendwhile: | |
821 case TOKendfor: | |
822 case TOKend: | |
823 case TOKendfunc: | |
824 case TOKreserver: | |
825 break; | |
826 case TOKfunc: | |
827 e = ParseFunction(); | |
828 if (e) { | |
829 expression->Add(e); | |
830 } | |
831 continue; | |
832 default: | |
833 e = ParseExpression(); | |
834 if (e) { | |
835 expression->Add(e); | |
836 } | |
837 continue; | |
838 } | |
839 break; | |
840 } | |
841 std::unique_ptr<CXFA_FMBlockExpression> pExp; | |
842 if (m_pErrorInfo->message.IsEmpty()) { | |
843 pExp.reset(new CXFA_FMBlockExpression(line, expression.release())); | |
844 } else { | |
845 for (int i = 0; i < expression->GetSize(); ++i) | |
846 delete static_cast<CXFA_FMExpression*>(expression->GetAt(i)); | |
847 } | |
848 return pExp.release(); | |
849 } | |
850 | |
851 CXFA_FMExpression* CXFA_FMParse::ParseIfExpression() { | |
852 FX_DWORD line = m_pToken->m_uLinenum; | |
853 const FX_WCHAR* pStartPos = m_lexer->SavePos(); | |
854 NextToken(); | |
855 Check(TOKlparen); | |
856 std::unique_ptr<CXFA_FMSimpleExpression> pExpression; | |
857 while (m_pToken->m_type != TOKrparen) { | |
858 pExpression.reset(ParseSimpleExpression()); | |
859 if (m_pToken->m_type != TOKcomma) | |
860 break; | |
861 NextToken(); | |
862 } | |
863 Check(TOKrparen); | |
864 if (m_pToken->m_type != TOKthen) { | |
865 m_lexer->SetCurrentLine(line); | |
866 m_pToken = new CXFA_FMToken(line); | |
867 m_pToken->m_type = TOKidentifier; | |
868 m_pToken->m_wstring = FX_WSTRC(L"if"); | |
869 m_lexer->SetToken(m_pToken); | |
870 m_lexer->RestorePos(pStartPos); | |
871 return ParseExpExpression(); | |
872 } | |
873 Check(TOKthen); | |
874 std::unique_ptr<CXFA_FMExpression> pIfExpression(ParseBlockExpression()); | |
875 std::unique_ptr<CXFA_FMExpression> pElseExpression; | |
876 switch (m_pToken->m_type) { | |
877 case TOKeof: | |
878 case TOKendif: | |
879 Check(TOKendif); | |
880 break; | |
881 case TOKif: | |
882 pElseExpression.reset(ParseIfExpression()); | |
883 Check(TOKendif); | |
884 break; | |
885 case TOKelseif: | |
886 pElseExpression.reset(ParseIfExpression()); | |
887 break; | |
888 case TOKelse: | |
889 NextToken(); | |
890 pElseExpression.reset(ParseBlockExpression()); | |
891 Check(TOKendif); | |
892 break; | |
893 default: | |
894 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
895 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IFEND, ws_TempString.c_str()); | |
896 NextToken(); | |
897 break; | |
898 } | |
899 std::unique_ptr<CXFA_FMIfExpression> pExp; | |
900 if (m_pErrorInfo->message.IsEmpty()) { | |
901 pExp.reset(new CXFA_FMIfExpression(line, pExpression.release(), | |
902 pIfExpression.release(), | |
903 pElseExpression.release())); | |
904 } | |
905 return pExp.release(); | |
906 } | |
907 | |
908 CXFA_FMExpression* CXFA_FMParse::ParseWhileExpression() { | |
909 FX_DWORD line = m_pToken->m_uLinenum; | |
910 NextToken(); | |
911 std::unique_ptr<CXFA_FMSimpleExpression> pCondition(ParseParenExpression()); | |
912 Check(TOKdo); | |
913 std::unique_ptr<CXFA_FMExpression> pExpression(ParseBlockExpression()); | |
914 Check(TOKendwhile); | |
915 std::unique_ptr<CXFA_FMExpression> e; | |
916 if (m_pErrorInfo->message.IsEmpty()) { | |
917 e.reset(new CXFA_FMWhileExpression(line, pCondition.release(), | |
918 pExpression.release())); | |
919 } | |
920 return e.release(); | |
921 } | |
922 | |
923 CXFA_FMSimpleExpression* CXFA_FMParse::ParseSubassignmentInForExpression() { | |
924 std::unique_ptr<CXFA_FMSimpleExpression> e; | |
925 switch (m_pToken->m_type) { | |
926 case TOKidentifier: | |
927 e.reset(ParseSimpleExpression()); | |
928 break; | |
929 default: | |
930 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
931 Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION, | |
932 ws_TempString.c_str()); | |
933 NextToken(); | |
934 break; | |
935 } | |
936 return e.release(); | |
937 } | |
938 | |
939 CXFA_FMExpression* CXFA_FMParse::ParseForExpression() { | |
940 CFX_WideStringC wsVariant; | |
941 FX_DWORD line = m_pToken->m_uLinenum; | |
942 NextToken(); | |
943 if (m_pToken->m_type != TOKidentifier) { | |
944 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
945 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, | |
946 XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str()); | |
947 } | |
948 wsVariant = m_pToken->m_wstring; | |
949 NextToken(); | |
950 std::unique_ptr<CXFA_FMSimpleExpression> pAssignment; | |
951 if (m_pToken->m_type == TOKassign) { | |
952 NextToken(); | |
953 pAssignment.reset(ParseSimpleExpression()); | |
954 } else { | |
955 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
956 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, | |
957 XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str()); | |
958 } | |
959 int32_t iDirection = 0; | |
960 if (m_pToken->m_type == TOKupto) { | |
961 iDirection = 1; | |
962 } else if (m_pToken->m_type == TOKdownto) { | |
963 iDirection = -1; | |
964 } else { | |
965 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
966 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, L"upto or downto", | |
967 (const FX_WCHAR*)ws_TempString); | |
968 } | |
969 NextToken(); | |
970 std::unique_ptr<CXFA_FMSimpleExpression> pAccessor(ParseSimpleExpression()); | |
971 std::unique_ptr<CXFA_FMSimpleExpression> pStep; | |
972 if (m_pToken->m_type == TOKstep) { | |
973 NextToken(); | |
974 pStep.reset(ParseSimpleExpression()); | |
975 } | |
976 Check(TOKdo); | |
977 std::unique_ptr<CXFA_FMExpression> pList(ParseBlockExpression()); | |
978 Check(TOKendfor); | |
979 std::unique_ptr<CXFA_FMExpression> e; | |
980 if (m_pErrorInfo->message.IsEmpty()) { | |
981 e.reset(new CXFA_FMForExpression(line, wsVariant, pAssignment.release(), | |
982 pAccessor.release(), iDirection, | |
983 pStep.release(), pList.release())); | |
984 } | |
985 return e.release(); | |
986 } | |
987 | |
988 CXFA_FMExpression* CXFA_FMParse::ParseForeachExpression() { | |
989 std::unique_ptr<CXFA_FMExpression> e; | |
990 CFX_WideStringC wsIdentifier; | |
991 std::unique_ptr<CFX_PtrArray> pAccessors; | |
992 std::unique_ptr<CXFA_FMExpression> pList; | |
993 FX_DWORD line = m_pToken->m_uLinenum; | |
994 NextToken(); | |
995 if (m_pToken->m_type != TOKidentifier) { | |
996 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
997 Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, | |
998 XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str()); | |
999 } | |
1000 wsIdentifier = m_pToken->m_wstring; | |
1001 NextToken(); | |
1002 Check(TOKin); | |
1003 Check(TOKlparen); | |
1004 if (m_pToken->m_type == TOKrparen) { | |
1005 CFX_WideString ws_TempString = m_pToken->m_wstring; | |
1006 Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION, | |
1007 ws_TempString.c_str()); | |
1008 NextToken(); | |
1009 } else { | |
1010 pAccessors.reset(new CFX_PtrArray()); | |
1011 while (m_pToken->m_type != TOKrparen) { | |
1012 CXFA_FMSimpleExpression* s = ParseSimpleExpression(); | |
1013 if (s) { | |
1014 pAccessors->Add(s); | |
1015 } | |
1016 if (m_pToken->m_type == TOKcomma) { | |
1017 NextToken(); | |
1018 } else { | |
1019 break; | |
1020 } | |
1021 } | |
1022 Check(TOKrparen); | |
1023 } | |
1024 Check(TOKdo); | |
1025 pList.reset(ParseBlockExpression()); | |
1026 Check(TOKendfor); | |
1027 if (m_pErrorInfo->message.IsEmpty()) { | |
1028 e.reset(new CXFA_FMForeachExpression( | |
1029 line, wsIdentifier, pAccessors.release(), pList.release())); | |
1030 } else { | |
1031 if (pAccessors) { | |
1032 for (int i = 0; i < pAccessors->GetSize(); ++i) | |
1033 delete static_cast<CXFA_FMSimpleExpression*>(pAccessors->GetAt(i)); | |
1034 } | |
1035 } | |
1036 return e.release(); | |
1037 } | |
1038 | |
1039 CXFA_FMExpression* CXFA_FMParse::ParseDoExpression() { | |
1040 std::unique_ptr<CXFA_FMExpression> e; | |
1041 FX_DWORD line = m_pToken->m_uLinenum; | |
1042 NextToken(); | |
1043 e.reset(ParseBlockExpression()); | |
1044 Check(TOKend); | |
1045 if (m_pErrorInfo->message.IsEmpty()) { | |
1046 e.reset(new CXFA_FMDoExpression(line, e.release())); | |
1047 } else { | |
1048 e.reset(); | |
1049 } | |
1050 return e.release(); | |
1051 } | |
OLD | NEW |