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