69 if ($pFormula === null) {
70 throw new Exception(
'Invalid parameter passed: formula');
74 $this->formula = trim($pFormula);
96 if (isset($this->tokens[$pId])) {
97 return $this->tokens[$pId];
100 throw new Exception(
"Token with id $pId does not exist.");
110 return count($this->tokens);
132 $formulaLength = strlen($this->formula);
133 if ($formulaLength < 2 || $this->formula[0] !=
'=') {
138 $tokens1 = $tokens2 = $stack = [];
139 $inString = $inPath = $inRange = $inError =
false;
140 $token = $previousToken = $nextToken = null;
145 $ERRORS = [
'#NULL!',
'#DIV/0!',
'#VALUE!',
'#REF!',
'#NAME?',
'#NUM!',
'#N/A'];
146 $COMPARATORS_MULTI = [
'>=',
'<=',
'<>'];
148 while (
$index < $formulaLength) {
155 if ($this->formula[
$index] == self::QUOTE_DOUBLE) {
156 if (((
$index + 2) <= $formulaLength) && ($this->formula[
$index + 1] == self::QUOTE_DOUBLE)) {
157 $value .= self::QUOTE_DOUBLE;
165 $value .= $this->formula[
$index];
176 if ($this->formula[
$index] == self::QUOTE_SINGLE) {
177 if (((
$index + 2) <= $formulaLength) && ($this->formula[
$index + 1] == self::QUOTE_SINGLE)) {
178 $value .= self::QUOTE_SINGLE;
184 $value .= $this->formula[
$index];
195 if ($this->formula[
$index] == self::BRACKET_CLOSE) {
198 $value .= $this->formula[
$index];
207 $value .= $this->formula[
$index];
209 if (in_array($value, $ERRORS)) {
219 if (strpos(self::OPERATORS_SN, $this->formula[
$index]) !==
false) {
220 if (strlen($value) > 1) {
221 if (preg_match(
'/^[1-9]{1}(\\.\\d+)?E{1}$/', $this->formula[$index]) != 0) {
222 $value .= $this->formula[
$index];
233 if ($this->formula[$index] == self::QUOTE_DOUBLE) {
234 if (strlen($value) > 0) {
245 if ($this->formula[$index] == self::QUOTE_SINGLE) {
246 if (strlen($value) > 0) {
257 if ($this->formula[$index] == self::BRACKET_OPEN) {
259 $value .= self::BRACKET_OPEN;
265 if ($this->formula[$index] == self::ERROR_START) {
266 if (strlen($value) > 0) {
272 $value .= self::ERROR_START;
279 if ($this->formula[$index] == self::BRACE_OPEN) {
280 if (strlen($value) > 0) {
288 $stack[] = clone $tmp;
292 $stack[] = clone $tmp;
299 if ($this->formula[$index] == self::SEMICOLON) {
300 if (strlen($value) > 0) {
305 $tmp = array_pop($stack);
315 $stack[] = clone $tmp;
322 if ($this->formula[$index] == self::BRACE_CLOSE) {
323 if (strlen($value) > 0) {
328 $tmp = array_pop($stack);
333 $tmp = array_pop($stack);
344 if ($this->formula[$index] == self::WHITESPACE) {
345 if (strlen($value) > 0) {
351 while (($this->formula[$index] == self::WHITESPACE) && ($index < $formulaLength)) {
359 if (($index + 2) <= $formulaLength) {
360 if (in_array(substr($this->formula, $index, 2), $COMPARATORS_MULTI)) {
361 if (strlen($value) > 0) {
373 if (strpos(self::OPERATORS_INFIX, $this->formula[$index]) !==
false) {
374 if (strlen($value) > 0) {
385 if (strpos(self::OPERATORS_POSTFIX, $this->formula[$index]) !==
false) {
386 if (strlen($value) > 0) {
397 if ($this->formula[$index] == self::PAREN_OPEN) {
398 if (strlen($value) > 0) {
401 $stack[] = clone $tmp;
406 $stack[] = clone $tmp;
414 if ($this->formula[$index] == self::COMMA) {
415 if (strlen($value) > 0) {
420 $tmp = array_pop($stack);
436 if ($this->formula[$index] == self::PAREN_CLOSE) {
437 if (strlen($value) > 0) {
442 $tmp = array_pop($stack);
453 $value .= $this->formula[
$index];
458 if (strlen($value) > 0) {
463 $tokenCount = count($tokens1);
464 for (
$i = 0;
$i < $tokenCount; ++
$i) {
466 if (isset($tokens1[
$i - 1])) {
467 $previousToken = $tokens1[
$i - 1];
469 $previousToken = null;
471 if (isset($tokens1[
$i + 1])) {
472 $nextToken = $tokens1[
$i + 1];
487 if ($previousToken === null) {
501 if ($nextToken === null) {
522 $tokenCount = count($tokens2);
523 for (
$i = 0;
$i < $tokenCount; ++
$i) {
525 if (isset($tokens2[
$i - 1])) {
526 $previousToken = $tokens2[
$i - 1];
528 $previousToken = null;
530 if (isset($tokens2[
$i + 1])) {
531 $nextToken = $tokens2[
$i + 1];
586 if (strpos(
'<>=', substr(
$token->getValue(), 0, 1)) !==
false) {
588 } elseif (
$token->getValue() ==
'&') {
603 if (!is_numeric(
$token->getValue())) {
604 if (strtoupper(
$token->getValue()) ==
'TRUE' || strtoupper(
$token->getValue()) ==
'FALSE') {
619 if (strlen(
$token->getValue()) > 0) {
620 if (substr(
$token->getValue(), 0, 1) ==
'@') {