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