all files / calculate/base/ parser.js

85.62% Statements 756/883
79.77% Branches 611/766
96.3% Functions 26/27
85.62% Lines 756/883
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290   1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275× 1275×       1275× 1275× 1275× 1275×   8824× 8824×   8822×     8822×   8822× 1085× 1084×   8821× 3530× 3530× 94×   15× 15×       11× 11×                 10× 10× 10×   34×     3496×   8787× 8787× 8785× 8785× 8785× 7008×   8785× 8785× 8785× 8785×   8785× 791× 791× 790× 789×   790× 790× 790×         8785× 8784× 8784×                                     8782× 8782× 8782× 14592× 14592×     14592×   14591× 14591×       14591×   14591× 14591×                     14591×     8781×   8780× 8780× 1777×   8780×   42×         16536× 16536× 16536× 16536× 16536× 16536× 16536× 16536× 16536× 16536× 16536× 16536× 147×     16389×   16387× 205691×   205691×                                                                                   205691×     16803× 16803× 16803× 16803×   188888×   1788× 1788×   187100× 8400× 52555× 52555×     178700×     41017× 41017×   137683×   59813× 59813×   77870×     25397× 25397×     52473× 51275×   52473× 638× 638×   52473× 144×   52473×       16387× 16387×   16387× 16387×   22332× 22332× 22332× 22332× 22331× 22331× 1438× 1438× 1438× 1435× 1435×     22331× 22331×     22331× 31016× 19500× 19500× 665× 665×         665×         22331×   8787× 8787× 8787× 8787× 8787× 8787× 8787× 8787× 1779× 1779× 2304× 1779×   2304× 2304×   2302× 2302× 2302× 2302× 2302× 2302× 2302×   2302×     8785× 8785×   1777× 3157× 7849×     1777×   23371× 23371× 23371×   23371×   23370×   23368×   23366×     23366× 23366× 23366× 23366× 23366× 23366× 23366× 23366× 23366× 23366× 23366× 23366× 23366×   23366×   23366× 23366× 23366× 23366× 23366× 23366× 23366× 23366× 23366×   23366× 23366×   23366× 23366×   23366× 23366×   23366×   140453×     140453× 140453× 140453× 140453× 327381×   140453× 140453× 140453× 246× 246× 246× 246×   140207× 83× 83× 131× 11× 11× 11×     83×   140124×     140124×     140453× 140453× 3164× 140× 140× 1980× 1980× 140×   1840× 11×     1829×     140×   3164× 3164× 3164× 3350× 3350× 3350× 3350× 3350× 3350× 3350× 3350× 3350× 3350× 3350× 362× 362×     362× 362×   2988× 133× 133× 133× 1629×   1620×   1629×   133×     133× 133×   2855× 26× 26×     26× 26×     2829× 2829×   3898× 18×   3898×   2829×     2829× 2829× 663× 663×   2166×   32× 32× 32× 32×     2134× 2134× 2163×   2134× 97× 97× 95×   97× 95×     2134× 33× 33× 51×   33× 33×   33×                 33× 33× 33×     2101× 2101× 38×   2101× 2101×   2101×   2134× 2134×   2829×               3350×       3350× 3350× 3350× 10×   3350× 91× 91×     91× 91×   3259× 200× 200×     200× 200×   3059× 52× 52× 52× 772× 11×   761× 11×   772×   52×     52× 52×     52×   3007× 1055× 1055× 1055×   926× 81×   926×   1055×   1055×     1055× 1055×   1952×   1952× 95× 95× 95×     1952× 1952× 1952× 1952×       405×     405×     405× 405×   1952× 1952× 93×     93×   1952× 2648×   1952×                         1949× 1949× 1949× 1949×       1952×     1952× 1854×   1952×     1952× 1952× 1952×     3350× 3350× 3350× 477×   3350× 389×   3350× 3350× 3350×       137289× 54095× 54095× 54095× 54095× 54095× 167215× 7156×     7156× 7156× 7156× 7148×   7156× 11× 11×       160059× 457× 457×   159602×   130521×     29081× 29081×       54095× 24546×       140453×           894764× 3099203× 41110×     853654×   362× 362× 362× 362× 3183× 55×   3128× 55×   3073× 362× 362×       362×   200× 200× 200× 200× 2560× 50×   2510× 50×   2460× 200× 200×       200×   8788× 8112×   8788×   8781×   8781× 8781× 8781× 8781× 8739×     42× 42× 42× 41×   41× 41× 41×   8780×   8994× 8994× 8994× 1754×     7240× 8032× 8032× 8032× 83018×     83018×   8032×   8031× 8031× 41548×   8031× 8031× 8031× 7752× 7752× 7752×       7752× 7752× 37× 37× 37×     7752× 7752× 7752× 7752×                                                         7752× 7752× 7752× 7752× 7752× 3054× 2911×           7752×       279×     278× 278× 248×   278× 278× 278×   278× 278×   8030×     8992× 8992×   7752× 7609×   7752×   7752×     7752× 7752× 7752× 7752× 7752× 7752× 3054× 2911× 2910× 2910×                       4698× 4698× 12846× 12846× 8335×   4511× 4511×   12846× 12846× 11844× 11844×     12846× 12846× 4698× 4698×       7752× 7752×           9784× 9784× 9784×   9784×   9784× 9784× 19046× 19046× 19046×   19045× 136×   18909× 34×   19046× 18875× 18875×       18875×   18875×           19046× 171× 171× 171×   19046× 171× 171×     18875× 18875× 25399×     19046× 19046×     19046× 19046×   19046× 1400×       1400×     1395×     1400× 1362× 1362×       1400× 38× 38× 38× 38× 38× 38×       38×   38×     1400×     9784×   9784×   9784×   1305× 1305×     1305× 1304×     1302× 32× 32× 32× 32×       1302× 147×   1302× 43× 43×                     1302×           1304×                                                      
define(["require", "exports", "./index", "../common/index", "@syncfusion/ej2-base"], function (require, exports, index_1, index_2, ej2_base_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var Parser = (function () {
        function Parser(parent) {
            this.emptyStr = '';
            this.storedStringText = this.emptyStr;
            this.sheetToken = '!';
            this.tokenAdd = 'a';
            this.tokenSubtract = 's';
            this.tokenMultiply = 'm';
            this.tokenDivide = 'd';
            this.tokenLess = 'l';
            this.charEm = 'r';
            this.charEp = 'x';
            this.tokenGreater = 'g';
            this.tokenEqual = 'e';
            this.tokenLessEq = 'k';
            this.tokenGreaterEq = 'j';
            this.tokenNotEqual = 'o';
            this.tokenAnd = 'c';
            this.tokenEm = 'v';
            this.tokenEp = 't';
            this.tokenOr = String.fromCharCode(126);
            this.charAnd = 'i';
            this.charLess = '<';
            this.charGreater = '>';
            this.charEqual = '=';
            this.charLessEq = 'f';
            this.charGreaterEq = 'h';
            this.charNoEqual = 'z';
            this.stringGreaterEq = '>=';
            this.stringLessEq = '<=';
            this.stringNoEqual = '<>';
            this.stringAnd = '&';
            this.stringOr = '^';
            this.charOr = 'w';
            this.charAdd = '+';
            this.charSubtract = '-';
            this.charMultiply = '*';
            this.charDivide = '/';
            this.fixedReference = '$';
            this.spaceString = ' ';
            this.ignoreBracet = false;
            this.isError = false;
            this.isFormulaParsed = false;
            this.findNamedRange = false;
            this.stringsColl = new Map();
            this.tokens = [
                this.tokenAdd, this.tokenSubtract, this.tokenMultiply, this.tokenDivide, this.tokenLess,
                this.tokenGreater, this.tokenEqual, this.tokenLessEq, this.tokenGreaterEq, this.tokenNotEqual, this.tokenAnd, this.tokenOr
            ];
            this.charNOTop = String.fromCharCode(167);
            this.specialSym = ['~', '@', '#', '?'];
            this.isFailureTriggered = false;
            this.parent = parent;
        }
        Parser.prototype.parse = function (text, fkey) {
            var _this = this;
            if (this.parent.isTextEmpty(text)) {
                return text;
            }
            Iif (index_2.isExternalFileLink(text)) {
                return this.parent.getErrorStrings()[index_2.CommonErrors.Ref];
            }
            if (this.parent.getFormulaCharacter() !== String.fromCharCode(0) && this.parent.getFormulaCharacter() === text[0]) {
                text = text.substring(1);
            }
            if (this.parent.namedRanges.size > 0 || this.parent.storedData.size > 0) {
                text = this.checkForNamedRangeAndKeyValue(text);
                this.findNamedRange = false;
            }
            text = text.replace(/[-+*/&^]+/g, function (operators) {
                var firstOp = '';
                while (1 < operators.length) {
                    switch (operators.substring(0, 2)) {
                        case '++':
                            operators = '+' + operators.substring(2);
                            break;
                        case '--':
                            operators = '+' + operators.substring(2);
                            break;
                        case '+-':
                            operators = '-' + operators.substring(2);
                            break;
                        case '-+':
                            operators = '-' + operators.substring(2);
                            break;
                        case '*+':
                            operators = '*' + operators.substring(2);
                            break;
                        case '/+':
                            operators = '/' + operators.substring(2);
                            break;
                        case '^+':
                            operators = '^' + operators.substring(2);
                            break;
                        case '&+':
                            operators = '&' + operators.substring(2);
                            break;
                        case '*-':
                        case '/-':
                        case '^-':
                        case '&-':
                            firstOp = operators.substring(0, 1);
                            operators = operators.substring(1);
                            break;
                        default:
                            throw new index_1.FormulaError(_this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.InvalidExpression], true);
                    }
                }
                return firstOp + operators;
            });
            text = text.split('-' + '(' + '-').join('(');
            var formulaString = this.storeStrings(text);
            text = this.storedStringText;
            var i = 0;
            if (ej2_base_1.isNullOrUndefined(formulaString)) {
                text = text.split(' ').join('');
            }
            text = text.split('=>').join('>=');
            text = text.split('=<').join('<=');
            Eif (text[text.length - 1] !== this.parent.arithMarker || this.indexOfAny(text, this.tokens) !== (text.length - 2)) {
                text = text.toUpperCase();
            }
            if (text.indexOf(this.sheetToken) > -1) {
                var family = this.parent.getSheetFamilyItem(this.parent.grid);
                if (family.sheetNameToParentObject != null && family.sheetNameToParentObject.size > 0) {
                    if (text[0] !== this.sheetToken.toString()) {
                        text = this.parent.setTokensForSheets(text);
                    }
                    var sheetToken = this.parent.getSheetToken(text.split(this.parent.tic).join(this.emptyStr));
                    var scopedRange = this.checkScopedRange(text.split('"').join(this.emptyStr).split(this.sheetToken).join(''));
                    Iif (ej2_base_1.isNullOrUndefined(sheetToken) && sheetToken !== '' && this.parent.namedRanges.size > 0 && scopedRange !== '') {
                        text = scopedRange;
                    }
                }
            }
            text = this.markLibraryFormulas(text);
            try {
                text = this.formulaAutoCorrection(text);
            }
            catch (ex) {
                var args = {
                    message: ex.message, exception: ex, isForceCalculable: ex.formulaCorrection,
                    computeForceCalculate: false
                };
                Eif (!args.isForceCalculable) {
                    throw this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.InvalidExpression];
                }
                if (!this.isFailureTriggered) {
                    this.parent.trigger('onFailure', args);
                    this.isFailureTriggered = true;
                }
                if (args.isForceCalculable && args.computeForceCalculate) {
                    text = this.formulaAutoCorrection(text, args);
                    this.parent.storedData.get(fkey).formulaText = '=' + text;
                }
                else {
                    throw this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.InvalidExpression];
                }
            }
            Eif (!this.ignoreBracet) {
                i = text.indexOf(')');
                while (i > -1) {
                    var k = text.substring(0, i).lastIndexOf('(');
                    Iif (k === -1) {
                        throw new index_1.FormulaError(this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.MismatchedParentheses]);
                    }
                    if (k === i - 1) {
                        throw new index_1.FormulaError(this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.EmptyExpression]);
                    }
                    var s = this.emptyStr;
                    Iif (this.ignoreBracet) {
                        s = this.parent.substring(text, k, i - k + 1);
                    }
                    else {
                        s = this.parent.substring(text, k + 1, i - k - 1);
                    }
                    try {
                        text = text.substring(0, k) + this.parseSimple(s) + text.substring(i + 1);
                    }
                    catch (ex) {
                        var args = this.exceptionArgs(ex);
                        if (!this.isFailureTriggered) {
                            this.parent.trigger('onFailure', args);
                            this.isFailureTriggered = true;
                        }
                        var errorMessage = (typeof args.exception === 'string') ? args.exception : args.message;
                        return (this.parent.getErrorLine(ex) ? '' : '#' + this.parent.getErrorLine(ex) + ': ') + errorMessage;
                    }
                    i = text.indexOf(')');
                }
            }
            if (!this.ignoreBracet && text.indexOf('(') > -1) {
                throw new index_1.FormulaError(this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.MismatchedParentheses]);
            }
            text = this.parseSimple(text);
            if (formulaString !== null && formulaString.size > 0) {
                text = this.setStrings(text, formulaString);
            }
            return text;
        };
        Parser.prototype.exceptionArgs = function (ex) {
            return {
                message: ex.message, exception: ex, isForceCalculable: ex.formulaCorrection,
                computeForceCalculate: false
            };
        };
        Parser.prototype.formulaAutoCorrection = function (formula, args) {
            var arithemeticArr = ['*', '+', '-', '/', '^', '&'];
            var logicalSym = ['>', '=', '<'];
            var i = 0;
            var form = '';
            var op = '';
            var firstOp = '';
            var secondprevOp = '';
            var secondnextOp = '';
            var firstDigit = '';
            var secondDigit = '';
            var countDigit = 0;
            if (this.parent.formulaErrorStrings.indexOf(formula) > -1) {
                return formula;
            }
            else {
                if (this.indexOfAny(formula, this.specialSym) > -1) {
                    throw new index_1.FormulaError(this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.InvalidExpression], false);
                }
                while (i < formula.length) {
                    formula = formula.split('-*').join('-').split('/*').join('/').split('*/').join('*').split('-/').join('-').
                        split('*+').join('*').split('+*').join('+');
                    Iif ((this.parent.isDigit(formula[i]) && ((formula.length > i + 1)
                        && (this.indexOfAny(formula[i + 1], arithemeticArr) > -1)) && ((formula.length > i + 2)
                        && (!ej2_base_1.isNullOrUndefined(formula[i + 2]) && this.indexOfAny(formula[i + 2], arithemeticArr) > -1))) &&
                        (formula[i + 2] !== '-' || (formula[i + 1] !== '*' && formula[i + 1] !== '/' && formula[i + 1] !== '^' && formula[i + 1] !== '&'))) {
                        if (args && args.computeForceCalculate) {
                            if (this.parent.isDigit(formula[i])) {
                                if (countDigit < 1) {
                                    firstDigit = formula[i];
                                    firstOp = formula[i + 1];
                                    if (ej2_base_1.isNullOrUndefined(firstOp)) {
                                        firstOp = this.emptyStr;
                                    }
                                    firstOp = firstOp === '&' ? '' : firstOp;
                                    countDigit = countDigit + 1;
                                    form = form + firstDigit + firstOp;
                                }
                                else if (countDigit < 2) {
                                    secondDigit = formula[i];
                                    secondprevOp = formula[i - 1];
                                    secondnextOp = formula[i + 1];
                                    countDigit = 0;
                                    if (secondprevOp === '-') {
                                        secondnextOp = ej2_base_1.isNullOrUndefined(secondnextOp) ? this.emptyStr : secondnextOp;
                                        secondnextOp = secondnextOp === '&' ? '' : secondnextOp;
                                        form = form + secondprevOp + secondDigit + secondnextOp;
                                    }
                                    else {
                                        secondnextOp = ej2_base_1.isNullOrUndefined(secondnextOp) ? this.emptyStr : secondnextOp;
                                        form = form + secondDigit + secondnextOp;
                                    }
                                }
                                i = i + 2;
                            }
                            else {
                                form = (formula[i] === '-') ? form + formula[i] : form;
                                i = i + 1;
                            }
                        }
                        else {
                            throw this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.ImproperFormula];
                        }
                    }
                    else if ((this.parent.isDigit(formula[i]) || formula[i] === this.parent.rightBracket ||
                        this.parent.storedData.has(formula[i].toUpperCase())) && (ej2_base_1.isNullOrUndefined(formula[i + 1]) ||
                        this.indexOfAny(formula[i + 1], arithemeticArr) > -1)) {
                        op = ej2_base_1.isNullOrUndefined(formula[i + 1]) ? this.emptyStr : formula[i + 1];
                        op = op === '&' && formula[i + 2] !== '-' ? '' : op;
                        form = formula[i - 1] === '-' ? form + formula[i - 1] + formula[i] + op : form + formula[i] + op;
                        i = i + 2;
                    }
                    else if (this.indexOfAny(formula[i], logicalSym) > -1 && !ej2_base_1.isNullOrUndefined(formula[i - 1]) &&
                        !ej2_base_1.isNullOrUndefined(formula[i + 1])) {
                        form = form + formula[i];
                        i = i + 1;
                    }
                    else if (formula[i] === 'q') {
                        while (formula[i] !== this.parent.leftBracket) {
                            form = form + formula[i];
                            i = i + 1;
                        }
                    }
                    else if (formula[i] === this.parent.leftBracket || formula[i] === this.parent.rightBracket ||
                        formula[i] === '{' || formula[i] === '}' || formula[i] === '(' ||
                        formula[i] === ')') {
                        form = form + formula[i];
                        i = i + 1;
                    }
                    else if (this.parent.isUpperChar(formula[i]) || formula[i].indexOf(':') > -1 || formula[i]
                        === this.parent.getParseArgumentSeparator() || (formula[i] === '%' && this.parent.isDigit(formula[i - 1]))) {
                        form = form + formula[i];
                        i = i + 1;
                    }
                    else if (formula[i] === this.parent.tic || formula[i] === ' ' || formula[i] ===
                        this.parent.getParseDecimalSeparator() || formula[i] === this.sheetToken || formula[i] === '$' ||
                        formula[i] === '_') {
                        form = form + formula[i];
                        i = i + 1;
                    }
                    else {
                        if (this.parent.isDigit(formula[i])) {
                            form = formula[i - 1] === '-' ? form + formula[i - 1] + formula[i] : form + formula[i];
                        }
                        if (formula[i] === '-' || formula[i] === '+') {
                            form = form + formula[i];
                            form = form.split('++').join('+').split('+-').join('-').split('-+').join('-');
                        }
                        if (formula[i] === '/' || formula[i] === '*' || formula[i] === '^') {
                            form = form + formula[i];
                        }
                        i = i + 1;
                    }
                }
            }
            form = form === this.emptyStr ? formula : form;
            if (this.indexOfAny(form[form.length - 1], arithemeticArr) > -1) {
                form = form.substring(0, form.length - 1);
            }
            form = form.split('--').join('-').split('-+').join('-').split('+-').join('-');
            return form;
        };
        Parser.prototype.checkScopedRange = function (text) {
            var _this = this;
            var scopedRange = this.emptyStr;
            var b = 'NaN';
            var id = this.parent.getSheetID(this.parent.grid);
            var sheet = this.parent.getSheetFamilyItem(this.parent.grid);
            if (text[0] === this.sheetToken.toString()) {
                var i = text.indexOf(this.sheetToken, 1);
                var v = parseInt(text.substr(1, i - 1), 10);
                if (i > 1 && !this.parent.isNaN(v)) {
                    text = text.substring(i + 1);
                    id = v;
                }
            }
            var token = '!' + id.toString();
            Iif (sheet === null || sheet.sheetNameToToken == null) {
                return b;
            }
            sheet.sheetNameToToken.forEach(function (value, key) {
                if (sheet.sheetNameToToken.get(key).toString() === token + '!') {
                    var s_1 = _this.emptyStr;
                    _this.parent.namedRanges.forEach(function (value, key) {
                        Eif (!ej2_base_1.isNullOrUndefined(_this.parent.parentObject)) {
                            s_1 = _this.parent.parentObject.getActiveSheet().name + _this.sheetToken + text.toUpperCase();
                        }
                        else {
                            s_1 = sheet.sheetNameToToken.get(key).toUpperCase();
                        }
                        if (_this.parent.getNamedRanges().has(s_1)) {
                            scopedRange = (_this.parent.getNamedRanges().get(s_1)).toUpperCase();
                            b = scopedRange;
                        }
                    });
                }
            });
            return b;
        };
        Parser.prototype.storeStrings = function (tempString) {
            var i = 0;
            var j = 0;
            var id = 0;
            var key = '';
            var storedString = null;
            var condition;
            var ticLoc = tempString.indexOf(this.parent.tic);
            if (ticLoc > -1) {
                i = tempString.indexOf(this.parent.tic);
                while (i > -1 && tempString.length > 0) {
                    if (storedString === null) {
                        storedString = this.stringsColl;
                    }
                    j = i + 1 < tempString.length ? tempString.indexOf(this.parent.tic, i + 1) : -1;
                    if (j === -1) {
                        throw new index_1.FormulaError(this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.MismatchedTics]);
                    }
                    condition = this.parent.substring(tempString, i, j - i + 1);
                    key = this.parent.tic + this.spaceString + id.toString() + this.parent.tic;
                    storedString = storedString.set(key, condition);
                    tempString = tempString.substring(0, i) + key + tempString.substring(j + 1);
                    i = i + key.length;
                    Eif (i <= tempString.length) {
                        i = tempString.indexOf(this.parent.tic, i);
                    }
                    id++;
                }
            }
            this.storedStringText = tempString;
            return storedString;
        };
        Parser.prototype.setStrings = function (text, formulaString) {
            for (var i = 0; i < formulaString.size; i++) {
                formulaString.forEach(function (value, key) {
                    text = text.split(key).join(value);
                });
            }
            return text;
        };
        Parser.prototype.parseSimple = function (formulaText) {
            var needToContinue = true;
            var text = formulaText;
            if (text.length > 0 && text[0] === '+') {
                text = text.substring(1);
            }
            if (text === '#DIV/0!') {
                return '#DIV/0!';
            }
            if (text === '#NAME?') {
                return '#NAME?';
            }
            if (text === '') {
                return text;
            }
            Iif (this.parent.formulaErrorStrings.indexOf(text) > -1) {
                return text;
            }
            text = text.split(this.stringLessEq).join(this.charLessEq);
            text = text.split(this.stringGreaterEq).join(this.charGreaterEq);
            text = text.split(this.stringNoEqual).join(this.charNoEqual);
            text = text.split(this.stringAnd).join(this.charAnd);
            text = text.split(this.stringOr).join(this.charOr);
            text = text.split(this.fixedReference).join(this.emptyStr);
            needToContinue = true;
            var expTokenArray = [this.tokenEp, this.tokenEm];
            var mulTokenArray = [this.tokenMultiply, this.tokenDivide];
            var addTokenArray = [this.tokenAdd, this.tokenSubtract];
            var mulCharArray = [this.charMultiply, this.charDivide];
            var addCharArray = [this.charAdd, this.charSubtract];
            var compareTokenArray = [this.tokenLess, this.tokenGreater, this.tokenEqual, this.tokenLessEq,
                this.tokenGreaterEq, this.tokenNotEqual];
            var compareCharArray = [this.charLess, this.charGreater, this.charEqual, this.charLessEq,
                this.charGreaterEq, this.charNoEqual];
            var expCharArray = [this.charEp, this.charEm];
            var andTokenArray = [this.tokenAnd];
            var andCharArray = [this.charAnd];
            var orCharArray = [this.charOr];
            var orTokenArray = [this.tokenOr];
            text = this.parseSimpleOperators(text, expTokenArray, expCharArray);
            text = this.parseSimpleOperators(text, orTokenArray, orCharArray);
            Eif (needToContinue) {
                text = this.parseSimpleOperators(text, mulTokenArray, mulCharArray);
            }
            Eif (needToContinue) {
                text = this.parseSimpleOperators(text, addTokenArray, addCharArray);
            }
            Eif (needToContinue) {
                text = this.parseSimpleOperators(text, compareTokenArray, compareCharArray);
            }
            Eif (needToContinue) {
                text = this.parseSimpleOperators(text, andTokenArray, andCharArray);
            }
            return text;
        };
        Parser.prototype.parseSimpleOperators = function (formulaText, markers, operators) {
            Iif (this.parent.getErrorStrings().indexOf(formulaText) > -1) {
                return formulaText;
            }
            var text = formulaText;
            var i = 0;
            var op = '';
            for (var c = 0; c < operators.length; c++) {
                op = op + operators[c];
            }
            text = text.split('---').join('-').split('--').join('+').split(this.parent.getParseArgumentSeparator() + '-').join(this.parent.getParseArgumentSeparator() + 'u').split(this.parent.leftBracket + '-').join(this.parent.leftBracket + 'u').split('=-').join('=u');
            text = text.split(',+').join(',').split(this.parent.leftBracket + '+').join(this.parent.leftBracket).split('=+').join('=').split('>+').join('>').split('<+').join('<').split('/+').join('/').split('*+').join('*').split('++').join('+').split('*-').join('*u').split('/-').join('/u').split('w-').join('wu').split('i-').join('iu').toString();
            if (text.length > 0 && text[0] === '-') {
                text = text.substring(1).split('-').join(this.tokenOr);
                text = '0-' + text;
                text = this.parseSimpleOperators(text, [this.tokenSubtract], [this.charSubtract]);
                text = text.split(this.tokenOr).join('-');
            }
            else if (text.length > 0 && text.indexOf('u') > -1) {
                var textValue = text.split(this.parent.getParseArgumentSeparator());
                for (var i_1 = 0; i_1 < textValue.length; i_1++) {
                    if (textValue[i_1].startsWith('u')) {
                        var textExp = textValue[i_1].split('u').join('0-');
                        textExp = this.parseSimpleOperators(textExp, [this.tokenSubtract], [this.charSubtract]);
                        textValue[i_1] = textExp;
                    }
                }
                text = textValue.join(this.parent.getParseArgumentSeparator());
            }
            else Iif (text.length > 0 && text[0] === '+') {
                text = text.substring(1);
            }
            else Iif (text.length > 0 && text[text.length - 1] === '+') {
                text = text.substring(0, text.length - 1);
            }
            try {
                if (this.indexOfAny(text, operators) > -1) {
                    if (text.includes(' ')) {
                        var newText = '';
                        for (var index = 0; index < text.length; index++) {
                            var currChar = text[index];
                            if (operators.indexOf(currChar) >= 0) {
                                newText = newText.trim() + currChar;
                            }
                            else if (currChar === ' ' && operators.indexOf(newText[newText.length - 1]) >= 0) {
                                continue;
                            }
                            else {
                                newText += currChar;
                            }
                        }
                        text = newText;
                    }
                    i = this.indexOfAny(text, operators);
                    var decimalSep = this.parent.getParseDecimalSeparator();
                    while (i > -1) {
                        var left = '';
                        var right = '';
                        var leftIndex = 0;
                        var rightIndex = 0;
                        var isLeftBool = false;
                        var arithOp = ['*', '+', '-', '/', 'w', '=', '<', '>'];
                        var isNotOperator = text[i] === this.charNOTop;
                        var j = 0;
                        Eif (!isNotOperator) {
                            j = i - 1;
                            if (text[j] === this.parent.arithMarker) {
                                var k = this.findLeftMarker(text.substring(0, j - 1));
                                Iif (k < 0) {
                                    throw new index_1.FormulaError(this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.CannotParse]);
                                }
                                left = this.parent.substring(text, k + 1, j - k - 1);
                                leftIndex = k + 1;
                            }
                            else if (text[j] === this.parent.rightBracket) {
                                var bracketCount = 0;
                                var k = j - 1;
                                while (k > 0 && (text[k] !== 'q' || bracketCount !== 0)) {
                                    if (text[k] === 'q') {
                                        bracketCount--;
                                    }
                                    else if (text[k] === this.parent.rightBracket) {
                                        bracketCount++;
                                    }
                                    k--;
                                }
                                Iif (k < 0) {
                                    throw new index_1.FormulaError(this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.CannotParse]);
                                }
                                left = this.parent.substring(text, k, j - k + 1);
                                leftIndex = k;
                            }
                            else if (text[j] === this.parent.tic[0]) {
                                var l = text.substring(0, j - 1).lastIndexOf(this.parent.tic);
                                Iif (l < 0) {
                                    throw new index_1.FormulaError(this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.CannotParse]);
                                }
                                left = this.parent.substring(text, l, j - l + 1);
                                leftIndex = l;
                            }
                            else {
                                var period = false;
                                while (j > -1 && (this.parent.isDigit(text[j]) ||
                                    (!period && (text[j] === decimalSep || text[j] === '%')))) {
                                    if (!this.parent.isDigit(text[j]) && text[j] !== '%') {
                                        period = true;
                                    }
                                    j = j - 1;
                                }
                                Iif (j > -1 && period && text[j] === decimalSep) {
                                    throw new index_1.FormulaError(this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.NumberContains2DecimalPoints]);
                                }
                                j = j + 1;
                                if (j === 0 || (j > 0 && !this.parent.isUpperChar(text[j - 1]))) {
                                    left = 'n' + this.parent.substring(text, j, i - j);
                                    leftIndex = j;
                                }
                                else if (j > 0 && text[j - 1] === 'E' && ((text.substring(j - 4, j) === 'TRUE' && (!ej2_base_1.isNullOrUndefined(text[j - 5]) ? arithOp.indexOf(text[j - 5]) > -1 : true)) ||
                                    (text.substring(j - 5, j) === 'FALSE' && (!ej2_base_1.isNullOrUndefined(text[j - 6]) ? arithOp.indexOf(text[j - 6]) > -1 : true))) && (text.substring(j + 1, j + 5) === 'TRUE' || text.substring(j + 1, j + 6) === 'FALSE')) {
                                    j = text.substring(j - 4, j) === 'TRUE' ? j - 4 : j - 5;
                                    left = text.substring(j, i) === 'TRUE' ? 'n1' : (text.substring(j, i) === 'FALSE' ? 'n0' : left);
                                    leftIndex = j;
                                    isLeftBool = true;
                                }
                                else {
                                    j = j - 1;
                                    while (j > -1 && (this.parent.isUpperChar(text[j]) || this.parent.isDigit(text[j]))) {
                                        j = j - 1;
                                    }
                                    if (j > -1 && text[j] === this.sheetToken) {
                                        j = j - 1;
                                        while (j > -1 && text[j] !== this.sheetToken) {
                                            j = j - 1;
                                        }
                                        if (j > -1 && text[j] === this.sheetToken) {
                                            j = j - 1;
                                        }
                                    }
                                    if (j > -1 && text[j] === ':') {
                                        j = j - 1;
                                        while (j > -1 && this.parent.isDigit(text[j])) {
                                            j = j - 1;
                                        }
                                        while (j > -1 && this.parent.isUpperChar(text[j])) {
                                            j = j - 1;
                                        }
                                        Iif (j > -1 && text[j] === this.sheetToken) {
                                            j--;
                                            while (j > -1 && text[j] !== this.sheetToken) {
                                                j--;
                                            }
                                            if (j > -1 && text[j] === this.sheetToken) {
                                                j--;
                                            }
                                        }
                                        j = j + 1;
                                        left = this.parent.substring(text, j, i - j);
                                        left = this.parent.getCellFrom(left);
                                    }
                                    else {
                                        var uFound = false;
                                        if (j > 0 && !this.parent.isUpperChar(text[j])) {
                                            uFound = text[j] === 'u' && text[j - 1] === this.parent.getParseArgumentSeparator();
                                        }
                                        Eif (!uFound) {
                                            j = j + 1;
                                        }
                                        left = this.parent.substring(text, j, i - j);
                                    }
                                    this.parent.updateDependentCell(left);
                                    leftIndex = j;
                                }
                                if ((this.parent.namedRanges.size > 0 && this.parent.namedRanges.has(left.toUpperCase())) ||
                                    (this.parent.storedData.has(left.toUpperCase()))) {
                                    left = 'n' + this.checkForNamedRangeAndKeyValue(left);
                                }
                            }
                        }
                        else {
                            leftIndex = i;
                        }
                        Iif (i === text.length - 1) {
                            throw new index_1.FormulaError(this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.ExpressionCannotEndWithAnOperator]);
                        }
                        else {
                            j = i + 1;
                            var uFound = text[j] === 'u';
                            if (uFound) {
                                j = j + 1;
                            }
                            if (text[j] === this.parent.tic[0]) {
                                var k = text.substring(j + 1).indexOf(this.parent.tic);
                                Iif (k < 0) {
                                    throw this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.CannotParse];
                                }
                                right = this.parent.substring(text, j, k + 2);
                                rightIndex = k + j + 2;
                            }
                            else if (text[j] === this.parent.arithMarker) {
                                var k = this.findRightMarker(text.substring(j + 1));
                                Iif (k < 0) {
                                    throw new index_1.FormulaError(this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.CannotParse]);
                                }
                                right = this.parent.substring(text, j + 1, k);
                                rightIndex = k + j + 2;
                            }
                            else if (text[j] === 'q') {
                                var bracketCount = 0;
                                var k = j + 1;
                                while (k < text.length && (text[k] !== this.parent.rightBracket || bracketCount !== 0)) {
                                    if (text[k] === this.parent.rightBracket) {
                                        bracketCount++;
                                    }
                                    else if (text[k] === 'q') {
                                        bracketCount--;
                                    }
                                    k++;
                                }
                                Iif (k === text.length) {
                                    throw this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.CannotParse];
                                }
                                right = this.parent.substring(text, j, k - j + 1);
                                Iif (uFound) {
                                    right = 'u' + right;
                                }
                                rightIndex = k + 1;
                            }
                            else if (this.parent.isDigit(text[j]) || text[j] === decimalSep) {
                                var period = (text[j] === decimalSep);
                                j = j + 1;
                                while (j < text.length && (this.parent.isDigit(text[j]) ||
                                    (!period && text[j] === decimalSep))) {
                                    if (text[j] === decimalSep) {
                                        period = true;
                                    }
                                    j = j + 1;
                                }
                                if (j < text.length && text[j] === '%') {
                                    j += 1;
                                }
                                Iif (period && j < text.length && text[j] === decimalSep) {
                                    throw this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.NumberContains2DecimalPoints];
                                }
                                right = 'n' + this.parent.substring(text, i + 1, j - i - 1);
                                rightIndex = j;
                            }
                            else Eif (this.parent.isUpperChar(text[j]) || text[j] === this.sheetToken ||
                                text[j] === 'u') {
                                if (text[j] === this.sheetToken) {
                                    j = j + 1;
                                    while (j < text.length && text[j] !== this.sheetToken) {
                                        j = j + 1;
                                    }
                                }
                                j = j + 1;
                                var jTemp = 0;
                                var inbracket = false;
                                while (j < text.length && (this.parent.isUpperChar(text[j]) || text[j] === '_'
                                    || text[j] === decimalSep || text[j] === '[' || text[j] === ']' ||
                                    text[j] === '#' || text[j] === ' ' || text[j] === '%' || text[j] ===
                                    decimalSep && inbracket)) {
                                    Iif (j !== text.length - 1 && text[j] === '[' && text[j + 1] === '[') {
                                        inbracket = true;
                                    }
                                    Iif (j !== text.length - 1 && text[j] === ']' && text[j + 1] === ']') {
                                        inbracket = false;
                                    }
                                    j++;
                                    jTemp++;
                                }
                                var noCellReference = (j === text.length) || !this.parent.isDigit(text[j]);
                                if (jTemp > 1) {
                                    while (j < text.length && (this.parent.isUpperChar(text[j]) ||
                                        this.parent.isDigit(text[j]) || text[j] === ' ' || text[j] === '_')) {
                                        j++;
                                    }
                                    noCellReference = true;
                                }
                                while (j < text.length && this.parent.isDigit(text[j])) {
                                    j = j + 1;
                                }
                                if (j < text.length && text[j] === ':') {
                                    j = j + 1;
                                    Iif (j < text.length && text[j] === this.sheetToken) {
                                        j++;
                                        while (j < text.length && text[j] !== this.sheetToken) {
                                            j = j + 1;
                                        }
                                        if (j < text.length && text[j] === this.sheetToken) {
                                            j++;
                                        }
                                    }
                                    while (j < text.length && this.parent.isUpperChar(text[j])) {
                                        j = j + 1;
                                    }
                                    while (j < text.length && this.parent.isDigit(text[j])) {
                                        j = j + 1;
                                    }
                                    j = j - 1;
                                    right = this.parent.substring(text, i + 1, j - i);
                                    right = this.parent.getCellFrom(right);
                                }
                                else {
                                    j = j - 1;
                                    right = this.parent.substring(text, i + 1, j - i);
                                    uFound = text[j] === 'u';
                                    Iif (uFound) {
                                        right = 'u' + right;
                                    }
                                }
                                Iif (noCellReference && right.startsWith(this.sheetToken)) {
                                    noCellReference = !this.parent.isCellReference(right);
                                }
                                if (!noCellReference) {
                                    this.parent.updateDependentCell(right);
                                }
                                if ((this.parent.namedRanges.size > 0 && this.parent.namedRanges.has(right.toUpperCase()))
                                    || (this.parent.storedData.has(right.toUpperCase()))) {
                                    right = 'n' + this.checkForNamedRangeAndKeyValue(right);
                                }
                                var isPrevArithOp = ['*', '+', '-', '/', 'w'].indexOf(text[j - right.length]) > -1;
                                right = right === 'TRUE' && (isLeftBool || isPrevArithOp) ? 'n1' : (right === 'FALSE' && (isLeftBool || isPrevArithOp) ? 'n0' : right);
                                rightIndex = j + 1;
                            }
                        }
                        var p = op.indexOf(text[i]);
                        var s = this.parent.arithMarker + left + right + markers[p] + this.parent.arithMarker;
                        if (leftIndex > 0) {
                            s = text.substring(0, leftIndex) + s;
                        }
                        if (rightIndex < text.length) {
                            s = s + text.substring(rightIndex);
                        }
                        s = s.split(this.parent.arithMarker2).join(this.parent.arithMarker.toString());
                        text = s;
                        i = this.indexOfAny(text, operators);
                    }
                }
                else {
                    if (text.length > 0 && (this.parent.isUpperChar(text[0]) || text[0] === this.sheetToken)) {
                        var isCharacter = true;
                        var checkLetter = true;
                        var oneTokenFound = false;
                        var textLen = text.length;
                        for (var k = 0; k < textLen; ++k) {
                            if (text[k] === this.sheetToken) {
                                Iif (k > 0 && !oneTokenFound) {
                                    throw this.parent.getErrorStrings()[index_2.CommonErrors.Ref];
                                }
                                oneTokenFound = true;
                                k++;
                                while (k < textLen && this.parent.isDigit(text[k])) {
                                    k++;
                                }
                                if (k === textLen || text[k] !== this.sheetToken) {
                                    isCharacter = false;
                                    break;
                                }
                            }
                            else {
                                if (!checkLetter && this.parent.isChar(text[k])) {
                                    isCharacter = false;
                                    break;
                                }
                                if (this.parent.isChar(text[k]) || this.parent.isDigit(text[k]) || text[k] ===
                                    this.sheetToken) {
                                    checkLetter = this.parent.isUpperChar(text[k]);
                                }
                                else {
                                    isCharacter = false;
                                    break;
                                }
                            }
                        }
                        if (isCharacter) {
                            this.parent.updateDependentCell(text);
                        }
                    }
                }
                return text;
            }
            catch (ex) {
                return ex;
            }
        };
        Parser.prototype.indexOfAny = function (text, operators) {
            for (var i = 0; i < text.length; i++) {
                if (operators.indexOf(text[i]) > -1) {
                    return i;
                }
            }
            return -1;
        };
        Parser.prototype.findLeftMarker = function (text) {
            var ret = -1;
            Eif (text.indexOf(this.parent.arithMarker) > -1) {
                var bracketLevel = 0;
                for (var i = text.length - 1; i >= 0; --i) {
                    if (text[i] === this.parent.rightBracket) {
                        bracketLevel--;
                    }
                    else if (text[i] === this.parent.leftBracket) {
                        bracketLevel++;
                    }
                    else if (text[i] === this.parent.arithMarker && bracketLevel === 0) {
                        ret = i;
                        break;
                    }
                }
            }
            return ret;
        };
        Parser.prototype.findRightMarker = function (text) {
            var ret = -1;
            Eif (text.indexOf(this.parent.arithMarker) > -1) {
                var bracketLevel = 0;
                for (var j = 0; j < text.length; ++j) {
                    if (text[j] === this.parent.rightBracket) {
                        bracketLevel--;
                    }
                    else if (text[j] === this.parent.leftBracket) {
                        bracketLevel++;
                    }
                    else if (text[j] === this.parent.arithMarker && bracketLevel === 0) {
                        ret = j;
                        break;
                    }
                }
            }
            return ret;
        };
        Parser.prototype.parseFormula = function (formula, fKey) {
            if (formula.length > 0 && formula[0] === this.parent.getFormulaCharacter()) {
                formula = formula.substring(1);
            }
            if (formula.indexOf('#REF!') > -1) {
                return this.parent.getErrorStrings()[index_2.CommonErrors.Ref];
            }
            if (formula.length > 0 && formula[0] === '+') {
                formula = formula.substring(1);
            }
            try {
                this.isFailureTriggered = false;
                this.isError = false;
                formula = this.parse(formula.trim(), fKey);
                this.isFormulaParsed = true;
            }
            catch (ex) {
                var args = this.exceptionArgs(ex);
                Eif (!this.isFailureTriggered) {
                    this.parent.trigger('onFailure', args);
                    this.isFailureTriggered = true;
                }
                var errorMessage = (typeof args.exception === 'string') ? args.exception : args.message;
                formula = (ej2_base_1.isNullOrUndefined(this.parent.getErrorLine(ex)) ? '' : '#' + this.parent.getErrorLine(ex) + ': ') + errorMessage;
                this.isError = true;
            }
            return formula;
        };
        Parser.prototype.markLibraryFormulas = function (formula) {
            var bracCount = 0;
            var rightParens = formula.indexOf(')');
            if (rightParens === -1) {
                formula = this.markNamedRanges(formula);
            }
            else {
                while (rightParens > -1) {
                    var parenCount = 0;
                    var leftParens = rightParens - 1;
                    while (leftParens > -1 && (formula[leftParens] !== '(' || parenCount !== 0)) {
                        Iif (formula[leftParens] === ')') {
                            parenCount++;
                        }
                        leftParens--;
                    }
                    if (leftParens === -1) {
                        throw new index_1.FormulaError(this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.MismatchedParentheses]);
                    }
                    var i = leftParens - 1;
                    while (i > -1 && (this.parent.isChar(formula[i]))) {
                        i--;
                    }
                    var len = leftParens - i - 1;
                    var libFormula = this.parent.substring(formula, i + 1, len);
                    if (len > 0 && !ej2_base_1.isNullOrUndefined(this.parent.getFunction(libFormula))) {
                        var substr = this.parent.substring(formula, leftParens, rightParens - leftParens + 1);
                        var argsSep = this.parent.getParseArgumentSeparator();
                        Iif (libFormula === 'AREAS') {
                            this.ignoreBracet = true;
                        }
                        else {
                            this.ignoreBracet = false;
                            if (libFormula.includes('IFS') && libFormula !== 'COUNTIFS' && substr.includes('{')) {
                                var leftBraceIdx = substr.indexOf('{');
                                var criteriaStr = this.parent.substring(substr, leftBraceIdx, substr.indexOf('}') - leftBraceIdx + 1);
                                substr = substr.split(criteriaStr).join(criteriaStr.split(argsSep).join(this.parent.tic + this.parent.tic));
                            }
                        }
                        try {
                            var args = void 0;
                            substr = substr.split('(').join('').split(')').join('');
                            substr = '(' + this.formulaAutoCorrection(substr, args) + ')';
                        }
                        catch (ex) {
                            var args = {
                                message: ex.message, exception: ex,
                                isForceCalculable: ex.formulaCorrection, computeForceCalculate: false
                            };
                            if (!args.isForceCalculable) {
                                throw this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.ImproperFormula];
                            }
                            if (!this.isFailureTriggered) {
                                this.parent.trigger('onFailure', args);
                                this.isFailureTriggered = true;
                                bracCount = bracCount + 1;
                            }
                            args.computeForceCalculate = bracCount > 0 ? true : args.computeForceCalculate;
                            if (args.isForceCalculable) {
                                if (args.computeForceCalculate) {
                                    substr = substr.split('(').join('').split(')').join('');
                                    substr = '(' + this.formulaAutoCorrection(substr, args) + ')';
                                }
                                else {
                                    throw this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.ImproperFormula];
                                }
                            }
                            else {
                                throw this.parent.formulaErrorStrings[index_2.FormulasErrorsStrings.ImproperFormula];
                            }
                        }
                        substr = this.markNamedRanges(substr);
                        substr = this.swapInnerParens(substr);
                        substr = this.addParensToArgs(substr);
                        var id = substr.lastIndexOf(argsSep);
                        if (id === -1) {
                            if (substr.length > 2 && substr[0] === '(' && substr[substr.length - 1] === ')') {
                                Iif (substr[1] !== '{' && substr[1] !== '(') {
                                    substr = substr.substring(0, substr.length - 1) + '}' + substr.substring(substr.length - 1);
                                    substr = substr[0] + '{' + substr.substring(1);
                                }
                            }
                        }
                        formula = formula.substring(0, i + 1) + 'q' + this.parent.substring(formula, i + 1, len) +
                            (substr.split('(').join(this.parent.leftBracket))
                                .split(')').join(this.parent.rightBracket) + formula.substring(rightParens + 1);
                    }
                    else if (len > 0) {
                        return this.parent.getErrorStrings()[index_2.CommonErrors.Name];
                    }
                    else {
                        var s = this.emptyStr;
                        if (leftParens > 0) {
                            s = formula.substring(0, leftParens);
                        }
                        s = s + '{' + this.parent.substring(formula, leftParens + 1, rightParens - leftParens - 1) + '}';
                        Eif (rightParens < formula.length) {
                            s = s + formula.substring(rightParens + 1);
                        }
                        s = this.markNamedRanges(s);
                        formula = s;
                    }
                    rightParens = formula.indexOf(')');
                }
            }
            formula = (formula.split('{').join('(')).split('}').join(')');
            return formula;
        };
        Parser.prototype.swapInnerParens = function (fSubstr) {
            if (fSubstr.length > 2) {
                fSubstr = fSubstr[0] + fSubstr.substr(1, fSubstr.length - 2).split('(').join('{').split(')').join('}') + fSubstr[fSubstr.length - 1];
            }
            return fSubstr;
        };
        Parser.prototype.addParensToArgs = function (fSubstr) {
            Iif (fSubstr.length === 0) {
                return this.emptyStr;
            }
            var rightSides = [];
            rightSides.push(this.parent.getParseArgumentSeparator());
            rightSides.push(this.parent.rightBracket);
            var id = fSubstr.lastIndexOf(this.parent.getParseArgumentSeparator());
            var k = 0;
            if (id === -1) {
                if (fSubstr.length > 2 && fSubstr[0] === '(' && fSubstr[fSubstr.length - 1] === ')') {
                    if (fSubstr[1] !== '{' && fSubstr[1] !== '(') {
                        fSubstr = fSubstr.substring(0, fSubstr.length - 1) + '}' + fSubstr.substring(fSubstr.length - 1);
                        fSubstr = fSubstr[0] + '{' + fSubstr.substring(1);
                    }
                    else {
                        var marker = ['+', '-', '*', '/'];
                        id = this.lastIndexOfAny(fSubstr, marker);
                        Eif (k === 0 && fSubstr[fSubstr.length - 1] === ')') {
                            k = fSubstr.length - 1;
                        }
                        Eif (k > 0) {
                            Iif (fSubstr[id + 1] !== '{' && fSubstr[id - 1] === '}') {
                                fSubstr = fSubstr.substr(0, k) + '}' + fSubstr.substr(k);
                                fSubstr = fSubstr.substr(0, id + 1) + '{' + fSubstr.substr(id + 1);
                            }
                        }
                    }
                }
            }
            else {
                var oneTimeOnly = true;
                while (id > -1) {
                    var j = this.indexOfAny(fSubstr.substring(id + 1, fSubstr.length), rightSides);
                    if (j >= 0) {
                        j = id + j + 1;
                    }
                    else Eif (j === -1 && fSubstr[fSubstr.length - 1] === ')') {
                        j = fSubstr.length - 1;
                    }
                    Eif (j > 0) {
                        if (fSubstr[id + 1] !== '{' && fSubstr[j - 1] !== '}' && fSubstr[j - 1] !== '¢') {
                            fSubstr = fSubstr.substr(0, j).trim() + '}' + fSubstr.substr(j);
                            fSubstr = fSubstr.substr(0, id + 1) + '{' + fSubstr.substr(id + 1).trim();
                        }
                    }
                    id = fSubstr.substr(0, id).lastIndexOf(this.parent.getParseArgumentSeparator());
                    if (oneTimeOnly && id === -1 && fSubstr[0] === '(') {
                        id = 0;
                        oneTimeOnly = false;
                    }
                }
            }
            fSubstr = fSubstr.split('{}').join(this.emptyStr);
            return fSubstr;
        };
        Parser.prototype.lastIndexOfAny = function (text, operators) {
            for (var i = text.length - 1; i > -1; i--) {
                if (operators.indexOf(text[i]) > -1) {
                    return i;
                }
            }
            return -1;
        };
        Parser.prototype.markNamedRanges = function (formula) {
            var markers = [')', this.parent.getParseArgumentSeparator(), '}', '+', '-', '*', '/', '<', '>', '=', '&', ':'];
            var i = (formula.length > 0 && (formula[0] === '(' || formula[0] === '{')) ? 1 : 0;
            if (formula.indexOf('#N/A') > -1) {
                formula = formula.split('#N/A').join('#N~A');
            }
            if (formula.indexOf('#DIV/0!') > -1) {
                formula = formula.split('#DIV/0!').join('#DIV~0!');
            }
            var end = this.indexOfAny(formula.substring(i), markers);
            while (end > -1 && end + i < formula.length) {
                var scopedRange = this.emptyStr;
                var s = null;
                if ((this.parent.substring(formula, i, end)).indexOf('[') > -1) {
                    s = this.getTableRange(this.parent.substring(formula, i, end));
                }
                else if (this.parent.storedData.has(this.parent.substring(formula, i, end))) {
                    s = this.checkForNamedRangeAndKeyValue(this.parent.substring(formula, i, end));
                }
                else if (this.parent.namedRanges.has(this.parent.substring(formula, i, end))) {
                    s = this.checkForNamedRangeAndKeyValue(this.parent.substring(formula, i, end));
                }
                if (ej2_base_1.isNullOrUndefined(s)) {
                    scopedRange = this.checkScopedRange(this.parent.substring(formula, i, end));
                    Iif (scopedRange !== 'NaN') {
                        this.findNamedRange = true;
                        s = scopedRange;
                    }
                    else if (this.parent.substring(formula, i, end).startsWith(this.sheetToken.toString())) {
                    }
                    Iif (!ej2_base_1.isNullOrUndefined(s) && this.findNamedRange) {
                        if (s.indexOf(this.fixedReference) > -1) {
                            s = s.split(this.fixedReference).join(this.emptyStr);
                        }
                    }
                }
                if (!ej2_base_1.isNullOrUndefined(s)) {
                    s = s.toUpperCase();
                    s = this.parent.setTokensForSheets(s);
                    s = this.markLibraryFormulas(s);
                }
                if (!ej2_base_1.isNullOrUndefined(s) && s !== this.emptyStr) {
                    formula = formula.substring(0, i) + s + formula.substring(i + end);
                    i += s.length + 1;
                }
                else {
                    i += end + 1;
                    while (i < formula.length && !this.parent.isUpperChar(formula[i]) && formula[i] !== this.sheetToken) {
                        i++;
                    }
                }
                end = i;
                Iif (i < formula.length - 1 && formula[i] === '{') {
                    i = i + 1;
                }
                end = this.indexOfAny(formula.substring(i), markers);
                while (end === 0 && i < formula.length - 1) {
                    i++;
                    end = this.indexOfAny(formula.substring(i), markers);
                }
                if ((end === -1 || formula.substring(i).indexOf('[') > -1) && i < formula.length) {
                    Iif (formula.substring(i).indexOf('[') > -1) {
                        s = this.getTableRange(formula.substring(i));
                    }
                    else {
                        if (this.parent.storedData.has(formula.substring(i))) {
                            s = this.parent.storedData.size > 0 ? this.checkForNamedRangeAndKeyValue(formula.substring(i)) : s;
                        }
                        else {
                            s = this.parent.namedRanges.size > 0 ? this.checkForNamedRangeAndKeyValue(formula.substring(i)) : s;
                        }
                    }
                    if (ej2_base_1.isNullOrUndefined(s)) {
                        scopedRange = this.checkScopedRange(formula.substring(i));
                        Iif (scopedRange !== 'NaN') {
                            s = scopedRange;
                        }
                    }
                    if (!ej2_base_1.isNullOrUndefined(s) && s !== this.emptyStr) {
                        s = s.toUpperCase();
                        s = this.parent.setTokensForSheets(s);
                        s = this.markLibraryFormulas(s);
                        Eif (s != null) {
                            var val = formula.substring(i);
                            Iif (val[val.length - 1] === ')') {
                                formula = formula.substring(0, i) + s + ')';
                            }
                            else {
                                formula = formula.substring(0, i) + s;
                            }
                            i += s.toString().length + 1;
                        }
                    }
                    end = (i < formula.length) ? this.indexOfAny(formula.substring(i), markers) : -1;
                }
            }
            if (formula.indexOf('#N~A') > -1) {
                formula = formula.split('#N~A').join('#N/A');
            }
            if (formula.indexOf('#DIV~0!') > -1) {
                formula = formula.split('#DIV~0!').join('#DIV/0!');
            }
            return formula;
        };
        Parser.prototype.checkForNamedRangeAndKeyValue = function (text) {
            var scopedRange = this.emptyStr;
            if (text.indexOf('[') > -1) {
                var namerangeValue = this.getTableRange(text);
                Eif (!ej2_base_1.isNullOrUndefined(namerangeValue)) {
                    this.findNamedRange = true;
                    text = namerangeValue;
                }
            }
            scopedRange = this.checkScopedRange(text);
            if (scopedRange !== 'NaN') {
                this.findNamedRange = true;
                text = scopedRange;
            }
            else {
                if (text.indexOf(this.sheetToken) > -1) {
                    var sheet = this.parent.getSheetFamilyItem(this.parent.grid);
                    var value = text.split('"').join(this.emptyStr);
                    value = value.substr(0, value.indexOf(this.sheetToken));
                    Iif (sheet.sheetNameToToken.has(value.toUpperCase())) {
                        var sheetIndex = parseInt(sheet.sheetNameToToken.get(value.toUpperCase()).split(this.sheetToken).join(this.emptyStr));
                    }
                }
                if (this.parent.storedData.size > 0 && this.parent.storedData.has(text)) {
                    text = 'A' + this.parent.colIndex(text);
                }
                if (this.parent.namedRanges.size > 0 && this.parent.namedRanges.has(text.toUpperCase())) {
                    Eif (!ej2_base_1.isNullOrUndefined(this.parent.parentObject)) {
                        text = this.parse(this.parent.namedRanges.get(text.toUpperCase()));
                    }
                    else {
                        text = this.parse(this.parent.namedRanges.get(text.toUpperCase()));
                        text = this.parent.setTokensForSheets(text);
                        if (text.indexOf(this.fixedReference) > -1) {
                            text.split(this.fixedReference).join(this.emptyStr);
                        }
                        this.findNamedRange = true;
                    }
                }
                if (this.findNamedRange) {
                    Eif (text[0] !== '!' && text[0] !== 'q' && text[0] !== 'bq') {
                        text = this.parent.setTokensForSheets(text);
                        Iif (text.indexOf(this.fixedReference) > -1) {
                            text = text.split(this.fixedReference).join(this.emptyStr);
                        }
                    }
                }
            }
            return text;
        };
        Parser.prototype.getTableRange = function (text) {
            text = text.replace(' ', this.emptyStr).toUpperCase();
            var name = text.replace(']', this.emptyStr).replace('#DATA', this.emptyStr);
            var tableName = name;
            Iif (name.indexOf(this.parent.getParseArgumentSeparator()) > -1) {
                tableName = name.substring(0, name.indexOf(this.parent.getParseArgumentSeparator())).replace('[', this.emptyStr);
                name = name.replace('[', this.emptyStr).replace(this.parent.getParseArgumentSeparator(), '_');
            }
            var range = this.emptyStr;
            return name.toUpperCase();
        };
        Parser.prototype.findNextEndIndex = function (formula, loc) {
            var count = 0;
            var l = loc;
            var found = false;
            while (!found && loc < formula.length) {
                if (formula[l] === '[') {
                    count++;
                }
                else if (formula[l] === ']') {
                    count--;
                    if (count === 0) {
                        found = true;
                    }
                }
                loc++;
            }
            loc = loc - l;
            return loc;
        };
        ;
        return Parser;
    }());
    exports.Parser = Parser;
});