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