Home | History | Annotate | Download | only in fm2js
      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"
      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 }
     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 }
     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 }
     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 }
     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 }
     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 }
     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 }
     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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
   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 }
   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 }
   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 }
   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