Skip to content

Commit

Permalink
v2.7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
denissimon committed Sep 12, 2019
1 parent e8a9f50 commit 802e13c
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 25 deletions.
55 changes: 32 additions & 23 deletions FormulaParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*
* @license MIT (https://github.com/denissimon/formula-parser/blob/master/LICENSE)
*
* @version 2.6.1-2019.07.16
* @version 2.7.0-2019.09.12
*/

namespace FormulaParser;
Expand All @@ -27,7 +27,7 @@ class FormulaParser implements IFormulaParser
protected $formula, $original_formula = "";
protected $precision = "";
protected $expression = "";
protected $correct = 1;
protected $correct = true;
protected $error_type = 0;
protected $variables = [];
protected $valid_variables = ['x', 'y', 'z', 'a', 'b'];
Expand Down Expand Up @@ -152,7 +152,7 @@ private function calculate1(array $array)
$a = pow($array[$i-1], $array[$i+1]);
}
} else {
$this->correct = 0;
$this->correct = false;
break;
}
unset($array[$i-1], $array[$i+1]);
Expand All @@ -178,7 +178,7 @@ private function calculate2(array $array)
&& ($array[$i] === '*' || $array[$i] === '/')) {
$this->checkInf($array[$i-1], $array[$i+1]);
if (!is_numeric($array[$i-1]) || !is_numeric($array[$i+1])) {
$this->correct = 0;
$this->correct = false;
break;
}
if ($array[$i] === '*') {
Expand Down Expand Up @@ -215,7 +215,7 @@ private function calculate3(array $array)
&& ($array[$i] === '+' || $array[$i] === '-')) {
$this->checkInf($array[$i-1], $array[$i+1]);
if (!is_numeric($array[$i-1]) || !is_numeric($array[$i+1])) {
$this->correct = 0;
$this->correct = false;
break;
}
if ($array[$i] === '+') {
Expand Down Expand Up @@ -263,7 +263,7 @@ private function calculateFunction($function, &$str, &$strlen, $i)

$this->checkInf($arg);
if (!is_numeric($arg)) {
$this->correct = 0;
$this->correct = false;
} else {
if ($function == 'exp') {
$result = pow(M_E, $arg);
Expand Down Expand Up @@ -340,7 +340,7 @@ private function combine($array) {
if ($array_im1 === '-' && $array_im2 !== '-') {
$new_array[] = $array_ip1;
} elseif ($array_im1 === '-' && $array_im3 === '-') {
$this->correct = 0;
$this->correct = false;
break;
} else {
$new_array[] = $item.$array_ip1;
Expand Down Expand Up @@ -444,10 +444,11 @@ private function parse($str)
} elseif (in_array($str_i, $this->valid_variables) && count($this->variables)) {
if (array_key_exists($str_i, $this->variables)
&& is_numeric($this->variables[$str_i])) {
$count++;
$main_array[$count] = (float) $this->variables[$str_i];
$count++;
} else {
$this->correct = 0;
$this->correct = false;
$this->error_type = 4;
break;
}
Expand All @@ -472,7 +473,7 @@ private function parse($str)
$count++;
} else {
// Nothing matches
$this->correct = 0;
$this->correct = false;
if (!$this->validate())
$this->error_type = 1;
break;
Expand All @@ -493,13 +494,15 @@ private function parse($str)
$main_array = $this->calculate2($main_array);
$main_array = $this->calculate3($main_array);

if (count($main_array) != 1)
$this->correct = 0;
if (count($main_array) != 1) {
$this->correct = false;
return 0;
}
}

if (!isset($main_array[0]) || strstr('+-*/^', (string) $main_array[0])
|| substr_count((string) $main_array[0], '.') > 1) {
$this->correct = 0;
$this->correct = false;
return 0;
}

Expand Down Expand Up @@ -553,7 +556,8 @@ private function checkExp($expression, $length, $cursor, $base)
if (substr($exp, -1) == '.')
$exp = substr($exp, 0, -1);
if (!is_numeric($exp) || strstr($exp, '.')) {
$this->correct = $response->result = 0;
$this->correct = false;
$response->result = 0;
} else {
$response->result = pow(abs($base),$exp) * pow(-1,$exp);
}
Expand Down Expand Up @@ -632,7 +636,7 @@ private function group(&$formula, $opt = 'init') {
[$this, 'match'], $formula);
// Variables
if (count($this->variables) > 0) {
$valid_variables = implode("|", $this->valid_variables);
$valid_variables = implode("|", $this->valid_variables);
$formula = preg_replace_callback('/[\+\-\*\/\^ ]('.$valid_variables.')[ \+\-\*\/\^]/',
[$this, 'match1'], $formula);
}
Expand Down Expand Up @@ -675,7 +679,7 @@ public function getResult()
{
// Check that the formula is not empty
if (!isset($this->formula[0])) {
$this->correct = 0;
$this->correct = false;
$this->error_type = 2;
}

Expand All @@ -684,7 +688,7 @@ public function getResult()
if (strlen($this->valid_variables[$i]) != 1
|| !preg_match('/^([a-z])$/', $this->valid_variables[$i]) === 1
|| $this->valid_variables[$i] == "e") {
$this->correct = 0;
$this->correct = false;
$this->error_type = 4;
}
}
Expand All @@ -697,31 +701,35 @@ public function getResult()

// Check for an equality of opening and closing parentheses
if ($open_parentheses_count != $close_parentheses_count) {
$this->correct = 0;
$this->correct = false;
$this->error_type = 3;
}

// Check the syntax is correct when using parentheses
if (preg_match('/(\)( )?[^\)\+\-\*\/\^ ])|(\(( )*?\))|([^nstgp\(\+\-\*\/\^ ]( )?\()/',
$this->formula)) {
$this->correct = 0;
$this->correct = false;
}

$processing_formula = $this->formula;

// Begin a general parse
while ((strstr($processing_formula, '(') || strstr($processing_formula, ')'))
&& $this->correct) {
$start_cursor_pos = 0; $end_cursor_pos = 0;
$start_cursor_pos = 0;
$end_cursor_pos = 0;

$this->group($processing_formula, '');

$temp = $processing_formula;

while (strstr($temp, '(')) {
$strlen_temp = strlen($temp);
for ($i=0; $i<=$strlen_temp-1; $i++) {
if (isset($temp[$i]) && $temp[$i] == '(') {
$temp = substr($temp, $i+1);
$start_cursor_pos = $start_cursor_pos + $i+1;
$temp = substr($temp, $i+1);
break;
}
}
}
Expand Down Expand Up @@ -750,9 +758,10 @@ public function getResult()
.$temp.substr($processing_formula, $length - $end_cursor_pos+1);
}

$this->formula = $processing_formula;

$result = $this->parse($this->formula);
if ($this->correct) {
$this->formula = $processing_formula;
$result = $this->parse($this->formula);
}

if ($this->correct) {
return ['done', $this->round_($result, $this->precision)];
Expand Down
14 changes: 12 additions & 2 deletions History.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## v2.7.0

* Optimized the algorithm
* Fixed parsing variables, e.g. 3 * 6x => Syntax error
* Updated: unit tests

## v2.6.1

* Fixed PHP message "strstr(): Non-string needles will be interpreted as strings in the future." in some cases

## v2.6.0

* Refactored: code to PHP 7.3.5
Expand All @@ -7,13 +17,13 @@
## v2.5.0

* Improved the algorithm: it gets better with this release!
* Added: ability to override default valid variables, that will allow to set variables with names not only x, y, z, a, b.
* Added: ability to override default valid variables, which will allow to set variables not only with the names x, y, z, a, b.
* Added: History.md
* Updated: readme

## v2.4.0

* Improved: now are available several consecutive operators, e.g. 10/--++2
* Improved: now several consecutive operators are available, e.g. 10/--++2
* Improved: a decimal number can be given as 1. or .1 which is equal to 1.0 or 0.1
* Added: constant Inf
* Added: processing of NaN
Expand Down
2 changes: 2 additions & 0 deletions tests/FormulaParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ public function errorData() {
['1.2.3', 'Syntax error'],
['.y', 'Syntax error', ['y' => '4']],
['y', 'Syntax error', []],
['3 * x6', 'Syntax error', ['x' => '1']],
['3 * 6x', 'Syntax error', ['x' => '1']],
[' ', 'Empty string'],
['_', 'Invalid character'],
['X', 'Invalid character', ['x' => '4']],
Expand Down

0 comments on commit 802e13c

Please sign in to comment.