PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/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
  1. <?php
  2. namespace App\Service;
  3. use App\Service\Exception\AriphmeticException;
  4. class CalculatorService
  5. {
  6. /**
  7. * @param array $data
  8. * @return array
  9. */
  10. public function resolve(array $data): array
  11. {
  12. return [];
  13. }
  14. /**
  15. * @throws AriphmeticException
  16. */
  17. function calculate($statement)
  18. {
  19. if (!is_string($statement)) {
  20. throw new AriphmeticException('Wrong type', 1);
  21. }
  22. $calcQueue = [];
  23. $operStack = [];
  24. $operPriority = [
  25. '(' => 0,
  26. ')' => 0,
  27. '+' => 1,
  28. '-' => 1,
  29. '*' => 2,
  30. '/' => 2,
  31. ];
  32. $token = '';
  33. foreach (str_split($statement) as $char) {
  34. if ($char >= '0' && $char <= '9') {
  35. $token .= $char;
  36. } else {
  37. if (strlen($token)) {
  38. $calcQueue[] = $token;
  39. $token = '';
  40. }
  41. if (isset($operPriority[$char])) {
  42. if (')' == $char) {
  43. while (!empty($operStack)) {
  44. $oper = array_pop($operStack);
  45. if ('(' == $oper) {
  46. break;
  47. }
  48. $calcQueue[] = $oper;
  49. }
  50. if ('(' != $oper) {
  51. throw new AriphmeticException('Unexpected ")"', 2);
  52. }
  53. } else {
  54. while (!empty($operStack) && '(' != $char) {
  55. $oper = array_pop($operStack);
  56. if ($operPriority[$char] > $operPriority[$oper]) {
  57. $operStack[] = $oper;
  58. break;
  59. }
  60. if ('(' != $oper) {
  61. $calcQueue[] = $oper;
  62. }
  63. }
  64. $operStack[] = $char;
  65. }
  66. } elseif (strpos(' ', $char) !== FALSE) {
  67. } else {
  68. throw new AriphmeticException('Unexpected symbol "' . $char . '"', 3);
  69. }
  70. }
  71. }
  72. if (strlen($token)) {
  73. $calcQueue[] = $token;
  74. $token = '';
  75. }
  76. if (!empty($operStack)) {
  77. while ($oper = array_pop($operStack)) {
  78. if ('(' == $oper) {
  79. throw new AriphmeticException('Unexpected "("', 4);
  80. }
  81. $calcQueue[] = $oper;
  82. }
  83. }
  84. $calcStack = array();
  85. foreach ($calcQueue as $token) {
  86. switch ($token) {
  87. case '+':
  88. $arg2 = array_pop($calcStack);
  89. $arg1 = array_pop($calcStack);
  90. $calcStack[] = $arg1 + $arg2;
  91. break;
  92. case '-':
  93. $arg2 = array_pop($calcStack);
  94. $arg1 = array_pop($calcStack);
  95. $calcStack[] = $arg1 - $arg2;
  96. break;
  97. case '*':
  98. $arg2 = array_pop($calcStack);
  99. $arg1 = array_pop($calcStack);
  100. $calcStack[] = $arg1 * $arg2;
  101. break;
  102. case '/':
  103. $arg2 = array_pop($calcStack);
  104. $arg1 = array_pop($calcStack);
  105. $calcStack[] = $arg1 / $arg2;
  106. break;
  107. default:
  108. $calcStack[] = $token;
  109. }
  110. }
  111. return array_pop($calcStack);
  112. }
  113. }