<?php
// Staring straight up into the sky ... oh my my
class Calculator{
private $token_type = 0;
private $token = "";
private $exp_ptr = 0;
public $parse_string = "";
function __construct($str){
$this->exp_ptr = 0;
$this->tok_type = ENDPARSE;
$this->token = "";
}
private function isoperator($tok){
}
private function isdigit($tok){
}
public function get_token(){
$tok = "";
$this->token_type = UNDEFTOK;
$this->token = "";
if($this->parse_string == ""){
$this->token_type = UNDEFTOK;
$this->token = "";
return;
}
if($this->exp_ptr == strlen($this->parse_string)){ $this->token_type = ENDPARSE;
$this->token = "";
return;
}
$tok = substr($this->parse_string, $this->exp_ptr, 1); if($this->isoperator($tok)){
$this->token_type = OPERATORTOK;
$this->token = $tok;
$this->exp_ptr++;
}elseif($this->isdigit($tok)){
$this->token_type = NUMBERTOK;
while($this->isdigit($tok)){
$this->token = $this->token.$tok;
$this->exp_ptr++;
$tok = substr($this->parse_string, $this->exp_ptr, 1); }
}else{
return;
}
}
public function compute(){
$result = 0.0;
$this->get_token();
if($this->token == ""){
echo "Выражение отсутствует";
return 0.0;
}
$this->addOrSubtractMembers($result);
return $result;
}
// Сложить или вычесть два члена
public function addOrSubtractMembers(&$result){
$op = "";
$temp = 0.0;
$this->multiplyOrDivide($result);
$op = $this->token;
While ($op == "+" || $op == "-") {
$this->get_token();
$this->multiplyOrDivide($temp);
switch ($op) {
case "-":
$result = $result - $temp;
break;
case "+":
$result = $result + $temp;
break;
}
$op = $this->token;
}
}
// Перемножить или поделить
public function multiplyOrDivide(&$result){
$op = "";
$temp = 0.0;
$this->processingDegree($result);
$op = $this->token;
While ($op == "*" || $op == "/" || $op == "%") {
$this->get_token();
$this->processingDegree($temp);
switch ($op) {
case "*":
$result = $result * $temp;
break;
case "/":
if($temp == 0){
echo "Делим на ноль";
}
$result = $result / $temp;
break;
case "%":
$result = $result % $temp;
break;
}
$op = $this->token;
}
return;
}
// обработка степени
public function processingDegree(&$result){
$op = "";
$temp = 0.0;
$ex = 0.0;
$this->unaryOperation($result);
if($this->token == "^"){
$this->get_token();
$this->processingDegree($temp);
$ex = $result;
if($temp == 0){
$result = 0.0;
return;
}
$result = pow($result, $temp); }
return;
}
// Унарный + или -
public function unaryOperation(&$result){
$op = "";
if($this->token_type == OPERATORTOK && $this->token == "+" || $this->token == "-" ){
$op = $this->token;
$this->get_token();
}
$this->processingBrackets($result);
if($op == "-"){
$result = -1 * $result;
}
return;
}
// Выражения в скобках
public function processingBrackets(&$result){
if($this->token == "("){
$this->get_token();
$this->addOrSubtractMembers($result);
if($this->token != ")"){
exit("Не хватает скобок"); }
$this->get_token();
} else {
$this->receiveValueNumber($result);
}
}
// Получить значение числа
public function receiveValueNumber(&$result){
switch ($this->token_type) {
case NUMBERTOK:
$result = (double)$this->token;
$this->get_token();
return;
default:
exit("Что-то пошло не так receiveValueNumber()\t\$this->token = {$this->token}\t\$this->token_type = {$this->token_type}"); }
}
}
function test(&$tst){
$tst++;
}
$test = new Calculator("6+5/8+15*9/8*9/8*(55+6*5)");
echo "{$test->parse_string} = ".$test->compute()."\n";
$test2 = new Calculator("6 + 5^2*8 + 6 / 89*8 - 9+3");
echo "{$test2->parse_string} = ".$test2->compute()."\n";
$test3 = new Calculator("6.6 + 5.2^5.5555+6/8*9.9^55.66");
echo "{$test3->parse_string} = ".$test3->compute()."\n";
$test4 = new Calculator("6.6 * (2+(6+(9/8)*6/(5+9)))");
echo "{$test4->parse_string} = ".$test4->compute()."\n";
?>