Я нашел ошибку в вашем парсере. В вашем последнем большом else
блоке вам нужно заменить
$current = end($stack);
if($operators[$tokens[$i]] == $operators[$current]) {
$rpn .= array_pop($stack);
$stack[] = $tokens[$i];
} else {
$stack[] = $tokens[$i];
}
с
while(!empty($stack) && end($stack) != '(' && $operators[$tokens[$i]] >= $operators[end($stack)]) {
$rpn .= array_pop($stack);
}
$stack[] = $tokens[$i];
После этого изменения ваши два тестовых примера работают нормально. (Я использовал эту ссылку для исправления вашего кода. Я прекратил проверять ваш код после устранения проблемы в вашем вопросе, поэтому внутри может быть больше ошибок - я не все проверял!)
РЕДАКТИРОВАТЬ: важно заменить "==" на "> =". Если у вас всегда будет только два уровня приоритета, замена if
на цикл не обязательна.