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