formula priority fix

This commit is contained in:
Yuri Kuznetsov
2024-02-29 14:42:25 +02:00
parent bbff632fbc
commit 55dd4ecf74
2 changed files with 96 additions and 50 deletions
+46 -49
View File
@@ -858,10 +858,10 @@ class Parser
foreach ($this->priorityList as $operationList) {
foreach ($operationList as $operator) {
$startFrom = 1;
$offset = -1;
while (true) {
$index = strpos($expression, $operator, $startFrom);
$index = strrpos($expression, $operator, $offset);
if ($index === false) {
break;
@@ -871,66 +871,63 @@ class Parser
break;
}
$startFrom = $index + 1;
$offset = -(strlen($expression) - $index) - 1;
}
if ($index !== false) {
$possibleRightOperator = null;
if ($index === false) {
continue;
}
if (strlen($operator) === 1) {
if ($index < strlen($expression) - 1) {
$possibleRightOperator = trim($operator . $expression[$index + 1]);
}
$possibleRightOperator = null;
if (strlen($operator) === 1) {
if ($index < strlen($expression) - 1) {
$possibleRightOperator = trim($operator . $expression[$index + 1]);
}
}
if (
$possibleRightOperator &&
$possibleRightOperator != $operator &&
!empty($this->operatorMap[$possibleRightOperator])
) {
continue;
if (
$possibleRightOperator &&
$possibleRightOperator != $operator &&
!empty($this->operatorMap[$possibleRightOperator])
) {
continue;
}
$possibleLeftOperator = null;
if (strlen($operator) === 1) {
if ($index > 0) {
$possibleLeftOperator = trim($expression[$index - 1] . $operator);
}
}
$possibleLeftOperator = null;
if (
$possibleLeftOperator &&
$possibleLeftOperator != $operator &&
!empty($this->operatorMap[$possibleLeftOperator])
) {
continue;
}
if (strlen($operator) === 1) {
if ($index > 0) {
$possibleLeftOperator = trim($expression[$index - 1] . $operator);
}
}
$firstPart = substr($expression, 0, $index);
$secondPart = substr($expression, $index + strlen($operator));
if (
$possibleLeftOperator &&
$possibleLeftOperator != $operator &&
!empty($this->operatorMap[$possibleLeftOperator])
) {
continue;
}
$modifiedFirstPart = $modifiedSecondPart = '';
$firstPart = substr($expression, 0, $index);
$secondPart = substr($expression, $index + strlen($operator));
$isString = $this->processString($firstPart, $modifiedFirstPart);
$modifiedFirstPart = $modifiedSecondPart = '';
$this->processString($secondPart, $modifiedSecondPart);
$isString = $this->processString($firstPart, $modifiedFirstPart);
if (
substr_count($modifiedFirstPart, '(') === substr_count($modifiedFirstPart, ')') &&
substr_count($modifiedSecondPart, '(') === substr_count($modifiedSecondPart, ')') &&
!$isString
) {
if ($minIndex === null || $index > $minIndex) {
$minIndex = $index;
$this->processString($secondPart, $modifiedSecondPart);
if (
substr_count($modifiedFirstPart, '(') === substr_count($modifiedFirstPart, ')') &&
substr_count($modifiedSecondPart, '(') === substr_count($modifiedSecondPart, ')') &&
!$isString
) {
if ($minIndex === null) {
$minIndex = $index;
$firstOperator = $operator;
}
else if ($index < $minIndex) {
$minIndex = $index;
$firstOperator = $operator;
}
$firstOperator = $operator;
}
}
}
+50 -1
View File
@@ -71,7 +71,56 @@ class EvaluatorTest extends \PHPUnit\Framework\TestCase
{
$expression = "5 - (2 + 1)";
$actual = $this->evaluator->process($expression);
$this->assertEquals(2, $actual);
$this->assertEquals(5 - (2 + 1), $actual);
}
public function testEvaluateMathExpression2(): void
{
$expression = "5 - 2 + 1";
$actual = $this->evaluator->process($expression);
$this->assertEquals(5 - 2 + 1, $actual);
}
public function testEvaluateMathExpression3(): void
{
$expression = "5 - 2 - 1";
$actual = $this->evaluator->process($expression);
$this->assertEquals(5 - 2 - 1, $actual);
}
public function testEvaluateMathExpression4(): void
{
$expression = "5-2-1";
$actual = $this->evaluator->process($expression);
$this->assertEquals(5 - 2 - 1, $actual);
}
public function testEvaluateMathExpression5(): void
{
$expression = "5 * 2 / 3.0";
$actual = $this->evaluator->process($expression);
$this->assertEquals(5 * 2 / 3.0, $actual);
}
public function testEvaluateMathExpression6(): void
{
$expression = "5 * 2 + 3 * 4";
$actual = $this->evaluator->process($expression);
$this->assertEquals(5 * 2 + 3 * 4, $actual);
}
public function testEvaluateMathExpression7(): void
{
$expression = "5 * (2 + 3) * 4";
$actual = $this->evaluator->process($expression);
$this->assertEquals(5 * (2 + 3) * 4, $actual);
}
public function testEvaluateMathExpression8(): void
{
$expression = "5 * (2 + 3) * 4 - (5 - 4)";
$actual = $this->evaluator->process($expression);
$this->assertEquals(5 * (2 + 3) * 4 - (5 - 4), $actual);
}
public function testEvaluateList1()