<?php $str = "1 + 2 * 3"; $res = calc_str($str); echo $res."\n"; function calc_str($str){ $stack = []; $polish = []; while ($str != "") { $t = get($str); while (count($stack) > 0){ $s_top = $stack[count($stack)-1]; if (priority($t) > priority($s_top))break; $polish[] = array_pop($stack); } $stack[] = $t; } while (count($stack) > 0) $polish[] = array_pop($stack); echo "[".implode(" ", $polish)."]\n"; foreach ($polish as $t){ if (preg_match('#^\d+$#', $t)){ $stack[] = intval($t); continue; } $b = array_pop($stack); $a = array_pop($stack); switch ($t) { case '+': $c = $a + $b; break; case '-': $c = $a - $b; break; case '*': $c = $a * $b; break; case '/': $c = $a / $b; break; default: throw new Exception("未知の文字:$t"); } $stack[] = $c; } return array_pop($stack); } function priority($c) { $pri = ['num'=>3, '*'=>2, '/'=>2, '+'=>1, '-'=>1]; return isset($pri[$c]) ? $pri[$c] : $pri['num']; } function get(&$str) { $str = trim($str); $c = substr($str, 0, 1); if (strpos("+-*/", $c) !== false){ $str = substr($str, 1); return $c; } if (preg_match('#^(\d+)#', $str, $m)){ $str = substr ($str, strlen($m[1])); return $m[1]; } throw new Exception("未知の文字: $c"); }