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