/api/src/Service/CalculatorService.php
https://gitlab.com/emmaelboristayot/sidexa · PHP · 121 lines · 106 code · 8 blank · 7 comment · 27 complexity · f24ca3e1ec35808310e79cd5faeddf1c MD5 · raw file
- <?php
- namespace App\Service;
- use App\Service\Exception\AriphmeticException;
- class CalculatorService
- {
- /**
- * @param array $data
- * @return array
- */
- public function resolve(array $data): array
- {
- return [];
- }
- /**
- * @throws AriphmeticException
- */
- function calculate($statement)
- {
- if (!is_string($statement)) {
- throw new AriphmeticException('Wrong type', 1);
- }
- $calcQueue = [];
- $operStack = [];
- $operPriority = [
- '(' => 0,
- ')' => 0,
- '+' => 1,
- '-' => 1,
- '*' => 2,
- '/' => 2,
- ];
- $token = '';
- foreach (str_split($statement) as $char) {
- if ($char >= '0' && $char <= '9') {
- $token .= $char;
- } else {
- if (strlen($token)) {
- $calcQueue[] = $token;
- $token = '';
- }
- if (isset($operPriority[$char])) {
- if (')' == $char) {
- while (!empty($operStack)) {
- $oper = array_pop($operStack);
- if ('(' == $oper) {
- break;
- }
- $calcQueue[] = $oper;
- }
- if ('(' != $oper) {
- throw new AriphmeticException('Unexpected ")"', 2);
- }
- } else {
- while (!empty($operStack) && '(' != $char) {
- $oper = array_pop($operStack);
- if ($operPriority[$char] > $operPriority[$oper]) {
- $operStack[] = $oper;
- break;
- }
- if ('(' != $oper) {
- $calcQueue[] = $oper;
- }
- }
- $operStack[] = $char;
- }
- } elseif (strpos(' ', $char) !== FALSE) {
- } else {
- throw new AriphmeticException('Unexpected symbol "' . $char . '"', 3);
- }
- }
- }
- if (strlen($token)) {
- $calcQueue[] = $token;
- $token = '';
- }
- if (!empty($operStack)) {
- while ($oper = array_pop($operStack)) {
- if ('(' == $oper) {
- throw new AriphmeticException('Unexpected "("', 4);
- }
- $calcQueue[] = $oper;
- }
- }
- $calcStack = array();
- foreach ($calcQueue as $token) {
- switch ($token) {
- case '+':
- $arg2 = array_pop($calcStack);
- $arg1 = array_pop($calcStack);
- $calcStack[] = $arg1 + $arg2;
- break;
- case '-':
- $arg2 = array_pop($calcStack);
- $arg1 = array_pop($calcStack);
- $calcStack[] = $arg1 - $arg2;
- break;
- case '*':
- $arg2 = array_pop($calcStack);
- $arg1 = array_pop($calcStack);
- $calcStack[] = $arg1 * $arg2;
- break;
- case '/':
- $arg2 = array_pop($calcStack);
- $arg1 = array_pop($calcStack);
- $calcStack[] = $arg1 / $arg2;
- break;
- default:
- $calcStack[] = $token;
- }
- }
- return array_pop($calcStack);
- }
- }