[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/phpexcel/PHPExcel/Calculation/ -> FormulaParser.php (source)

   1  <?php
   2  
   3  /*
   4  PARTLY BASED ON:
   5      Copyright (c) 2007 E. W. Bachtal, Inc.
   6  
   7      Permission is hereby granted, free of charge, to any person obtaining a copy of this software
   8      and associated documentation files (the "Software"), to deal in the Software without restriction,
   9      including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10      and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
  11      subject to the following conditions:
  12  
  13        The above copyright notice and this permission notice shall be included in all copies or substantial
  14        portions of the Software.
  15  
  16      The software is provided "as is", without warranty of any kind, express or implied, including but not
  17      limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In
  18      no event shall the authors or copyright holders be liable for any claim, damages or other liability,
  19      whether in an action of contract, tort or otherwise, arising from, out of or in connection with the
  20      software or the use or other dealings in the software.
  21  
  22      http://ewbi.blogs.com/develops/2007/03/excel_formula_p.html
  23      http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html
  24  */
  25  
  26  /**
  27   * PHPExcel_Calculation_FormulaParser
  28   *
  29   * Copyright (c) 2006 - 2015 PHPExcel
  30   *
  31   * This library is free software; you can redistribute it and/or
  32   * modify it under the terms of the GNU Lesser General Public
  33   * License as published by the Free Software Foundation; either
  34   * version 2.1 of the License, or (at your option) any later version.
  35   *
  36   * This library is distributed in the hope that it will be useful,
  37   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  38   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  39   * Lesser General Public License for more details.
  40   *
  41   * You should have received a copy of the GNU Lesser General Public
  42   * License along with this library; if not, write to the Free Software
  43   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  44   *
  45   * @category   PHPExcel
  46   * @package    PHPExcel_Calculation
  47   * @copyright  Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  48   * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  49   * @version    ##VERSION##, ##DATE##
  50   */
  51  
  52  
  53  class PHPExcel_Calculation_FormulaParser
  54  {
  55      /* Character constants */
  56      const QUOTE_DOUBLE  = '"';
  57      const QUOTE_SINGLE  = '\'';
  58      const BRACKET_CLOSE = ']';
  59      const BRACKET_OPEN  = '[';
  60      const BRACE_OPEN    = '{';
  61      const BRACE_CLOSE   = '}';
  62      const PAREN_OPEN    = '(';
  63      const PAREN_CLOSE   = ')';
  64      const SEMICOLON     = ';';
  65      const WHITESPACE    = ' ';
  66      const COMMA         = ',';
  67      const ERROR_START   = '#';
  68  
  69      const OPERATORS_SN             = "+-";
  70      const OPERATORS_INFIX         = "+-*/^&=><";
  71      const OPERATORS_POSTFIX     = "%";
  72  
  73      /**
  74       * Formula
  75       *
  76       * @var string
  77       */
  78      private $formula;
  79  
  80      /**
  81       * Tokens
  82       *
  83       * @var PHPExcel_Calculation_FormulaToken[]
  84       */
  85      private $tokens = array();
  86  
  87      /**
  88       * Create a new PHPExcel_Calculation_FormulaParser
  89       *
  90       * @param     string        $pFormula    Formula to parse
  91       * @throws     PHPExcel_Calculation_Exception
  92       */
  93      public function __construct($pFormula = '')
  94      {
  95          // Check parameters
  96          if (is_null($pFormula)) {
  97              throw new PHPExcel_Calculation_Exception("Invalid parameter passed: formula");
  98          }
  99  
 100          // Initialise values
 101          $this->formula = trim($pFormula);
 102          // Parse!
 103          $this->parseToTokens();
 104      }
 105  
 106      /**
 107       * Get Formula
 108       *
 109       * @return string
 110       */
 111      public function getFormula()
 112      {
 113          return $this->formula;
 114      }
 115  
 116      /**
 117       * Get Token
 118       *
 119       * @param     int        $pId    Token id
 120       * @return    string
 121       * @throws  PHPExcel_Calculation_Exception
 122       */
 123      public function getToken($pId = 0)
 124      {
 125          if (isset($this->tokens[$pId])) {
 126              return $this->tokens[$pId];
 127          } else {
 128              throw new PHPExcel_Calculation_Exception("Token with id $pId does not exist.");
 129          }
 130      }
 131  
 132      /**
 133       * Get Token count
 134       *
 135       * @return string
 136       */
 137      public function getTokenCount()
 138      {
 139          return count($this->tokens);
 140      }
 141  
 142      /**
 143       * Get Tokens
 144       *
 145       * @return PHPExcel_Calculation_FormulaToken[]
 146       */
 147      public function getTokens()
 148      {
 149          return $this->tokens;
 150      }
 151  
 152      /**
 153       * Parse to tokens
 154       */
 155      private function parseToTokens()
 156      {
 157          // No attempt is made to verify formulas; assumes formulas are derived from Excel, where
 158          // they can only exist if valid; stack overflows/underflows sunk as nulls without exceptions.
 159  
 160          // Check if the formula has a valid starting =
 161          $formulaLength = strlen($this->formula);
 162          if ($formulaLength < 2 || $this->formula{0} != '=') {
 163              return;
 164          }
 165  
 166          // Helper variables
 167          $tokens1    = $tokens2     = $stack = array();
 168          $inString    = $inPath     = $inRange     = $inError = false;
 169          $token        = $previousToken    = $nextToken    = null;
 170  
 171          $index    = 1;
 172          $value    = '';
 173  
 174          $ERRORS             = array("#NULL!", "#DIV/0!", "#VALUE!", "#REF!", "#NAME?", "#NUM!", "#N/A");
 175          $COMPARATORS_MULTI     = array(">=", "<=", "<>");
 176  
 177          while ($index < $formulaLength) {
 178              // state-dependent character evaluation (order is important)
 179  
 180              // double-quoted strings
 181              // embeds are doubled
 182              // end marks token
 183              if ($inString) {
 184                  if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) {
 185                      if ((($index + 2) <= $formulaLength) && ($this->formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE)) {
 186                          $value .= PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE;
 187                          ++$index;
 188                      } else {
 189                          $inString = false;
 190                          $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_TEXT);
 191                          $value = "";
 192                      }
 193                  } else {
 194                      $value .= $this->formula{$index};
 195                  }
 196                  ++$index;
 197                  continue;
 198              }
 199  
 200              // single-quoted strings (links)
 201              // embeds are double
 202              // end does not mark a token
 203              if ($inPath) {
 204                  if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) {
 205                      if ((($index + 2) <= $formulaLength) && ($this->formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE)) {
 206                          $value .= PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE;
 207                          ++$index;
 208                      } else {
 209                          $inPath = false;
 210                      }
 211                  } else {
 212                      $value .= $this->formula{$index};
 213                  }
 214                  ++$index;
 215                  continue;
 216              }
 217  
 218              // bracked strings (R1C1 range index or linked workbook name)
 219              // no embeds (changed to "()" by Excel)
 220              // end does not mark a token
 221              if ($inRange) {
 222                  if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_CLOSE) {
 223                      $inRange = false;
 224                  }
 225                  $value .= $this->formula{$index};
 226                  ++$index;
 227                  continue;
 228              }
 229  
 230              // error values
 231              // end marks a token, determined from absolute list of values
 232              if ($inError) {
 233                  $value .= $this->formula{$index};
 234                  ++$index;
 235                  if (in_array($value, $ERRORS)) {
 236                      $inError = false;
 237                      $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_ERROR);
 238                      $value = "";
 239                  }
 240                  continue;
 241              }
 242  
 243              // scientific notation check
 244              if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_SN, $this->formula{$index}) !== false) {
 245                  if (strlen($value) > 1) {
 246                      if (preg_match("/^[1-9]{1}(\.[0-9]+)?E{1}$/", $this->formula{$index}) != 0) {
 247                          $value .= $this->formula{$index};
 248                          ++$index;
 249                          continue;
 250                      }
 251                  }
 252              }
 253  
 254              // independent character evaluation (order not important)
 255  
 256              // establish state-dependent character evaluations
 257              if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) {
 258                  if (strlen($value > 0)) {
 259                      // unexpected
 260                      $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN);
 261                      $value = "";
 262                  }
 263                  $inString = true;
 264                  ++$index;
 265                  continue;
 266              }
 267  
 268              if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) {
 269                  if (strlen($value) > 0) {
 270                      // unexpected
 271                      $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN);
 272                      $value = "";
 273                  }
 274                  $inPath = true;
 275                  ++$index;
 276                  continue;
 277              }
 278  
 279              if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_OPEN) {
 280                  $inRange = true;
 281                  $value .= PHPExcel_Calculation_FormulaParser::BRACKET_OPEN;
 282                  ++$index;
 283                  continue;
 284              }
 285  
 286              if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::ERROR_START) {
 287                  if (strlen($value) > 0) {
 288                      // unexpected
 289                      $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN);
 290                      $value = "";
 291                  }
 292                  $inError = true;
 293                  $value .= PHPExcel_Calculation_FormulaParser::ERROR_START;
 294                  ++$index;
 295                  continue;
 296              }
 297  
 298              // mark start and end of arrays and array rows
 299              if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_OPEN) {
 300                  if (strlen($value) > 0) {
 301                      // unexpected
 302                      $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN);
 303                      $value = "";
 304                  }
 305  
 306                  $tmp = new PHPExcel_Calculation_FormulaToken("ARRAY", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START);
 307                  $tokens1[] = $tmp;
 308                  $stack[] = clone $tmp;
 309  
 310                  $tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START);
 311                  $tokens1[] = $tmp;
 312                  $stack[] = clone $tmp;
 313  
 314                  ++$index;
 315                  continue;
 316              }
 317  
 318              if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::SEMICOLON) {
 319                  if (strlen($value) > 0) {
 320                      $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);
 321                      $value = "";
 322                  }
 323  
 324                  $tmp = array_pop($stack);
 325                  $tmp->setValue("");
 326                  $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP);
 327                  $tokens1[] = $tmp;
 328  
 329                  $tmp = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT);
 330                  $tokens1[] = $tmp;
 331  
 332                  $tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START);
 333                  $tokens1[] = $tmp;
 334                  $stack[] = clone $tmp;
 335  
 336                  ++$index;
 337                  continue;
 338              }
 339  
 340              if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_CLOSE) {
 341                  if (strlen($value) > 0) {
 342                      $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);
 343                      $value = "";
 344                  }
 345  
 346                  $tmp = array_pop($stack);
 347                  $tmp->setValue("");
 348                  $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP);
 349                  $tokens1[] = $tmp;
 350  
 351                  $tmp = array_pop($stack);
 352                  $tmp->setValue("");
 353                  $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP);
 354                  $tokens1[] = $tmp;
 355  
 356                  ++$index;
 357                  continue;
 358              }
 359  
 360              // trim white-space
 361              if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) {
 362                  if (strlen($value) > 0) {
 363                      $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);
 364                      $value = "";
 365                  }
 366                  $tokens1[] = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE);
 367                  ++$index;
 368                  while (($this->formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) && ($index < $formulaLength)) {
 369                      ++$index;
 370                  }
 371                  continue;
 372              }
 373  
 374              // multi-character comparators
 375              if (($index + 2) <= $formulaLength) {
 376                  if (in_array(substr($this->formula, $index, 2), $COMPARATORS_MULTI)) {
 377                      if (strlen($value) > 0) {
 378                          $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);
 379                          $value = "";
 380                      }
 381                      $tokens1[] = new PHPExcel_Calculation_FormulaToken(substr($this->formula, $index, 2), PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL);
 382                      $index += 2;
 383                      continue;
 384                  }
 385              }
 386  
 387              // standard infix operators
 388              if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_INFIX, $this->formula{$index}) !== false) {
 389                  if (strlen($value) > 0) {
 390                      $tokens1[] =new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);
 391                      $value = "";
 392                  }
 393                  $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX);
 394                  ++$index;
 395                  continue;
 396              }
 397  
 398              // standard postfix operators (only one)
 399              if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_POSTFIX, $this->formula{$index}) !== false) {
 400                  if (strlen($value) > 0) {
 401                      $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);
 402                      $value = "";
 403                  }
 404                  $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX);
 405                  ++$index;
 406                  continue;
 407              }
 408  
 409              // start subexpression or function
 410              if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_OPEN) {
 411                  if (strlen($value) > 0) {
 412                      $tmp = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START);
 413                      $tokens1[] = $tmp;
 414                      $stack[] = clone $tmp;
 415                      $value = "";
 416                  } else {
 417                      $tmp = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START);
 418                      $tokens1[] = $tmp;
 419                      $stack[] = clone $tmp;
 420                  }
 421                  ++$index;
 422                  continue;
 423              }
 424  
 425              // function, subexpression, or array parameters, or operand unions
 426              if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::COMMA) {
 427                  if (strlen($value) > 0) {
 428                      $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);
 429                      $value = "";
 430                  }
 431  
 432                  $tmp = array_pop($stack);
 433                  $tmp->setValue("");
 434                  $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP);
 435                  $stack[] = $tmp;
 436  
 437                  if ($tmp->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) {
 438                      $tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_UNION);
 439                  } else {
 440                      $tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT);
 441                  }
 442                  ++$index;
 443                  continue;
 444              }
 445  
 446              // stop subexpression
 447              if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_CLOSE) {
 448                  if (strlen($value) > 0) {
 449                      $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);
 450                      $value = "";
 451                  }
 452  
 453                  $tmp = array_pop($stack);
 454                  $tmp->setValue("");
 455                  $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP);
 456                  $tokens1[] = $tmp;
 457  
 458                  ++$index;
 459                  continue;
 460              }
 461  
 462              // token accumulation
 463              $value .= $this->formula{$index};
 464              ++$index;
 465          }
 466  
 467          // dump remaining accumulation
 468          if (strlen($value) > 0) {
 469              $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);
 470          }
 471  
 472          // move tokenList to new set, excluding unnecessary white-space tokens and converting necessary ones to intersections
 473          $tokenCount = count($tokens1);
 474          for ($i = 0; $i < $tokenCount; ++$i) {
 475              $token = $tokens1[$i];
 476              if (isset($tokens1[$i - 1])) {
 477                  $previousToken = $tokens1[$i - 1];
 478              } else {
 479                  $previousToken = null;
 480              }
 481              if (isset($tokens1[$i + 1])) {
 482                  $nextToken = $tokens1[$i + 1];
 483              } else {
 484                  $nextToken = null;
 485              }
 486  
 487              if (is_null($token)) {
 488                  continue;
 489              }
 490  
 491              if ($token->getTokenType() != PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE) {
 492                  $tokens2[] = $token;
 493                  continue;
 494              }
 495  
 496              if (is_null($previousToken)) {
 497                  continue;
 498              }
 499  
 500              if (! (
 501                      (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||
 502                      (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||
 503                      ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)
 504                    ) ) {
 505                  continue;
 506              }
 507  
 508              if (is_null($nextToken)) {
 509                  continue;
 510              }
 511  
 512              if (! (
 513                      (($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) ||
 514                      (($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) ||
 515                      ($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)
 516                    ) ) {
 517                  continue;
 518              }
 519  
 520              $tokens2[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_INTERSECTION);
 521          }
 522  
 523          // move tokens to final list, switching infix "-" operators to prefix when appropriate, switching infix "+" operators
 524          // to noop when appropriate, identifying operand and infix-operator subtypes, and pulling "@" from function names
 525          $this->tokens = array();
 526  
 527          $tokenCount = count($tokens2);
 528          for ($i = 0; $i < $tokenCount; ++$i) {
 529              $token = $tokens2[$i];
 530              if (isset($tokens2[$i - 1])) {
 531                  $previousToken = $tokens2[$i - 1];
 532              } else {
 533                  $previousToken = null;
 534              }
 535              if (isset($tokens2[$i + 1])) {
 536                  $nextToken = $tokens2[$i + 1];
 537              } else {
 538                  $nextToken = null;
 539              }
 540  
 541              if (is_null($token)) {
 542                  continue;
 543              }
 544  
 545              if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "-") {
 546                  if ($i == 0) {
 547                      $token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX);
 548                  } elseif ((($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) &&
 549                      ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||
 550                      (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) &&
 551                      ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||
 552                      ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) ||
 553                      ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)) {
 554                      $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH);
 555                  } else {
 556                      $token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX);
 557                  }
 558  
 559                  $this->tokens[] = $token;
 560                  continue;
 561              }
 562  
 563              if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "+") {
 564                  if ($i == 0) {
 565                      continue;
 566                  } elseif ((($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) &&
 567                      ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||
 568                      (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) &&
 569                      ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||
 570                      ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) ||
 571                      ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)) {
 572                      $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH);
 573                  } else {
 574                      continue;
 575                  }
 576  
 577                  $this->tokens[] = $token;
 578                  continue;
 579              }
 580  
 581              if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX &&
 582                  $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) {
 583                  if (strpos("<>=", substr($token->getValue(), 0, 1)) !== false) {
 584                      $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL);
 585                  } elseif ($token->getValue() == "&") {
 586                      $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_CONCATENATION);
 587                  } else {
 588                      $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH);
 589                  }
 590  
 591                  $this->tokens[] = $token;
 592                  continue;
 593              }
 594  
 595              if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND &&
 596                  $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) {
 597                  if (!is_numeric($token->getValue())) {
 598                      if (strtoupper($token->getValue()) == "TRUE" || strtoupper($token->getValue() == "FALSE")) {
 599                          $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL);
 600                      } else {
 601                          $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_RANGE);
 602                      }
 603                  } else {
 604                      $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NUMBER);
 605                  }
 606  
 607                  $this->tokens[] = $token;
 608                  continue;
 609              }
 610  
 611              if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) {
 612                  if (strlen($token->getValue() > 0)) {
 613                      if (substr($token->getValue(), 0, 1) == "@") {
 614                          $token->setValue(substr($token->getValue(), 1));
 615                      }
 616                  }
 617              }
 618  
 619              $this->tokens[] = $token;
 620          }
 621      }
 622  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1