<?php
// Staring straight up into the sky ... oh my my
$token_type = UNDEFTOK;
$token = "";
$exp_ptr = 0;
function returnPpiopitet($op){
switch ($op) {
case "(":
return 0;
case ")":
return 1;
case "+":
case "-":
return 2;
case "*":
case "/":
return 3;
case "^":
return 4;
default:
return -1;
}
}
function isoperator($tok){
}
function isdigit($tok){
}
function getToken($op){
global $exp_ptr;
global $token, $token_type;
$tok = "";
$token_type = UNDEFTOK;
$token = "";
if($op == ""){
$token_type = UNDEFTOK;
$token = "";
return;
}
$token_type = ENDPARSE;
$token = "";
return;
}
$tok = substr($op, $exp_ptr, 1); if(isoperator($tok)){
$token_type = OPERATORTOK;
$token = $tok;
$exp_ptr++;
}elseif(isdigit($tok)){
$token_type = NUMBERTOK;
while(isdigit($tok)){
$token = $token.$tok;
$exp_ptr++;
$tok = substr($op, $exp_ptr, 1); }
}else{
return;
}
}
function convertReversePolishNotation(&$stringExpression){
global $token, $token_type, $exp_ptr;
$token_type = UNDEFTOK;
$token = "";
$exp_ptr = 0;
$stack = new SplStack();
$conversionResults = array(); $stringExpression = preg_replace("/\s+/", "", $stringExpression); // Изъёбство для обхода унарного минуса -а заменяется на 0-а
// -(а+в) на (0-1)*(а+в)
$stringExpression = preg_replace("/(^-[\d\.]{1,})/u", "(0$1)", $stringExpression); $stringExpression = preg_replace("/([\/\*\-\+\^\(])(\-[\d\.]{1,})/u", "$1(0$2)", $stringExpression); $stringExpression = preg_replace("/([\/\*\-\+\^])(\-)\(/u", "$1(0\${2}1)*(", $stringExpression);
exit("Несовпадение скобок"); exit("Несколько операторов подряд"); }elseif(preg_match_all("/[^\+\-\*\/\^\(\)\d\.]/u", $stringExpression, $match)){ exit("Неизвестные символы"); }elseif(preg_match_all("/\d\(|\)\d|\)\(/u", $stringExpression, $match)){ exit("Пропущен оператор"); }
while($token_type != ENDPARSE){
getToken($stringExpression);
if($token_type == OPERATORTOK && $token == ")"){
while(($op = $stack->pop()) != "("){
}
}
if($token_type == NUMBERTOK) {
}
if($token_type == OPERATORTOK && $token == "("){
$stack->push($token);
}
if($token_type == OPERATORTOK && ($token == "+" || $token == "-" || $token == "*" || $token == "/" || $token == "^")){
if($stack->count() == 0){ $stack->push($token);
} else {
if(returnPpiopitet($token) > returnPpiopitet($stack->top())){
$stack->push($token);
} else {
while($stack->count() !=0 && returnPpiopitet
($stack->top()) >= returnPpiopitet
($token)){ }
$stack->push($token);
}
}
}
}
while($stack->count() !=0){ }
return $conversionResults;
}
function compute(&$stringExpression){
$conversionResults = convertReversePolishNotation($stringExpression);
$stack = new SplStack();
while(count($conversionResults) !=0){ if(returnPpiopitet($op)>=0){
switch($op){
case "+":
$op1 = $stack->pop();
$op2 = $stack->pop();
$stack->push((double)$op2 + (double)$op1);
break;
case "-":
$op1 = $stack->pop();
$op2 = $stack->pop();
$stack->push((double)$op2 - (double)$op1);
break;
case "*":
$op1 = $stack->pop();
$op2 = $stack->pop();
$stack->push((double)$op2 * (double)$op1);
break;
case "/":
$op1 = $stack->pop();
$op2 = $stack->pop();
if($op2 == 0){
}
$stack->push((double)$op2 / (double)$op1);
break;
case "^":
$op1 = $stack->pop();
$op2 = $stack->pop();
$stack->push(pow((double
)$op2, (double
)$op1)); break;
}
}else{
$stack->push($op);
}
}
return $stack->pop();
}
$str = "6+5/8+15*9/8*9/8*(55+6*5)";
$rez = compute($str);
echo $str." = ".$rez."\n";
$str = "6 + 5^2*8 + 6 / 89*8 - 9+3";
$rez = compute($str);
echo $str." = ".$rez."\n";
$str = "6.6 + 5.2^5.5555+6/8*9.9^55.66";
$rez = compute($str);
echo $str." = ".$rez."\n";
$str = "6.6 * (2+(6+(9/8)*6/(5+9)))";
$rez = compute($str);
echo $str." = ".$rez."\n";
$str = "5 * (-3 + 8)";
$rez = compute($str);
echo $str." = ".$rez."\n";
$str = "-5+-6*-(-5+-9)/-8+6*8*(-9--6)/-8^-6";
echo $str;
$rez = compute($str);
echo " = ".$rez."\n";
?>
PD9waHAKCS8vIFN0YXJpbmcgc3RyYWlnaHQgdXAgaW50byB0aGUgc2t5IC4uLiBvaCBteSBteQoJZXJyb3JfcmVwb3J0aW5nKC0xKTsKCW1iX2ludGVybmFsX2VuY29kaW5nKCd1dGYtOCcpOwoJCglkZWZpbmUoICdVTkRFRlRPSycsICcwJyApOwoJZGVmaW5lKCAnTlVNQkVSVE9LJywgJzEnICk7CglkZWZpbmUoICdPUEVSQVRPUlRPSycsICcyJyApOwoJZGVmaW5lKCAnRU5EUEFSU0UnLCAnMycgKTsKCgkkdG9rZW5fdHlwZSA9IFVOREVGVE9LOwoJJHRva2VuID0gIiI7CgkkZXhwX3B0ciA9IDA7CgoJZnVuY3Rpb24gcmV0dXJuUHBpb3BpdGV0KCRvcCl7CgkJc3dpdGNoICgkb3ApIHsKCQkJY2FzZSAiKCI6CgkJCQlyZXR1cm4gMDsKCQkJY2FzZSAiKSI6CgkJCQlyZXR1cm4gMTsKCQkJY2FzZSAiKyI6CgkJCWNhc2UgIi0iOgoJCQkJcmV0dXJuIDI7CgkJCWNhc2UgIioiOgoJCQljYXNlICIvIjoKCQkJCXJldHVybiAzOwoJCQljYXNlICJeIjoKCQkJCXJldHVybiA0OwoJCQlkZWZhdWx0OgoJCQkJcmV0dXJuIC0xOwoJCX0KCX0KCglmdW5jdGlvbiBpc29wZXJhdG9yKCR0b2spewoJCXJldHVybiBwcmVnX21hdGNoX2FsbCgiL1tcK1wtXCpcL1xeXChcKV0vdSIsICR0b2ssICR0ZW1wKTsKCX0KCQoJZnVuY3Rpb24gaXNkaWdpdCgkdG9rKXsKCQlyZXR1cm4gcHJlZ19tYXRjaF9hbGwoIi9bXGRcLl0vdSIsICR0b2ssICR0ZW1wKTsKCX0KCQoJZnVuY3Rpb24gZ2V0VG9rZW4oJG9wKXsKCQlnbG9iYWwgJGV4cF9wdHI7CgkJZ2xvYmFsICR0b2tlbiwgJHRva2VuX3R5cGU7CgoJCSR0b2sgPSAiIjsKCQkkdG9rZW5fdHlwZSA9IFVOREVGVE9LOwoJCSR0b2tlbiA9ICIiOwoJCWlmKCRvcCA9PSAiIil7CgkJCSR0b2tlbl90eXBlID0gVU5ERUZUT0s7CgkJCSR0b2tlbiA9ICIiOwoJCQlyZXR1cm47CgkJfQoJCWlmKCRleHBfcHRyID09IHN0cmxlbigkb3ApKXsKCQkJJHRva2VuX3R5cGUgPSBFTkRQQVJTRTsKCQkJJHRva2VuID0gIiI7CgkJCXJldHVybjsKCQl9CgkJJHRvayA9IHN1YnN0cigkb3AsICRleHBfcHRyLCAxKTsKCQlpZihpc29wZXJhdG9yKCR0b2spKXsKCQkJJHRva2VuX3R5cGUgPSBPUEVSQVRPUlRPSzsKCQkJJHRva2VuID0gJHRvazsKCQkJJGV4cF9wdHIrKzsKCQl9ZWxzZWlmKGlzZGlnaXQoJHRvaykpewoJCQkkdG9rZW5fdHlwZSA9IE5VTUJFUlRPSzsKCQkJd2hpbGUoaXNkaWdpdCgkdG9rKSl7CgkJCQkkdG9rZW4gPSAkdG9rZW4uJHRvazsKCQkJCSRleHBfcHRyKys7CgkJCQkkdG9rID0gc3Vic3RyKCRvcCwgJGV4cF9wdHIsIDEpOwoJCQl9CgkJfWVsc2V7CgkJCXJldHVybjsKCQl9Cgl9CgkKCWZ1bmN0aW9uIGNvbnZlcnRSZXZlcnNlUG9saXNoTm90YXRpb24oJiRzdHJpbmdFeHByZXNzaW9uKXsJCQoJCWdsb2JhbCAkdG9rZW4sICR0b2tlbl90eXBlLCAkZXhwX3B0cjsKCQkKCQkkdG9rZW5fdHlwZSA9IFVOREVGVE9LOwoJCSR0b2tlbiA9ICIiOwoJCSRleHBfcHRyID0gMDsKCQkKCQkkc3RhY2sgPSBuZXcgU3BsU3RhY2soKTsKCQkkY29udmVyc2lvblJlc3VsdHMgPSBhcnJheSgpOwoJCSRzdHJpbmdFeHByZXNzaW9uID0gcHJlZ19yZXBsYWNlKCIvXHMrLyIsICIiLCAkc3RyaW5nRXhwcmVzc2lvbik7CgkJLy8g0JjQt9GK0ZHQsdGB0YLQstC+INC00LvRjyDQvtCx0YXQvtC00LAg0YPQvdCw0YDQvdC+0LPQviDQvNC40L3Rg9GB0LAgLdCwINC30LDQvNC10L3Rj9C10YLRgdGPINC90LAgMC3QsAoJCS8vIC0o0LAr0LIpINC90LAgKDAtMSkqKNCwK9CyKQoJCSRzdHJpbmdFeHByZXNzaW9uID0gcHJlZ19yZXBsYWNlKCIvKF4tW1xkXC5dezEsfSkvdSIsICIoMCQxKSIsICRzdHJpbmdFeHByZXNzaW9uKTsKCQkkc3RyaW5nRXhwcmVzc2lvbiA9IHByZWdfcmVwbGFjZSgiLyhbXC9cKlwtXCtcXlwoXSkoXC1bXGRcLl17MSx9KS91IiwgIiQxKDAkMikiLCAkc3RyaW5nRXhwcmVzc2lvbik7CgkJJHN0cmluZ0V4cHJlc3Npb24gPSBwcmVnX3JlcGxhY2UoIi8oW1wvXCpcLVwrXF5dKShcLSlcKC91IiwgIiQxKDBcJHsyfTEpKigiLCAkc3RyaW5nRXhwcmVzc2lvbik7CgkJCgkJaWYocHJlZ19tYXRjaF9hbGwoIi8oXCgpL3UiLCAkc3RyaW5nRXhwcmVzc2lvbiwgJG1hdGNoKSAhPSBwcmVnX21hdGNoX2FsbCgiLyhcKSkvdSIsICRzdHJpbmdFeHByZXNzaW9uLCAkbWF0Y2gpKXsKCQkJZXhpdCgi0J3QtdGB0L7QstC/0LDQtNC10L3QuNC1INGB0LrQvtCx0L7QuiIpOwoJCX1lbHNlaWYocHJlZ19tYXRjaF9hbGwoIi9bXCtcLVwqXC9cXl17Mix9L3UiLCAkc3RyaW5nRXhwcmVzc2lvbiwgJG1hdGNoKSAmJiAhcHJlZ19tYXRjaF9hbGwoIi9bXCtcKlwvXF5dLS91IiwgJHN0cmluZ0V4cHJlc3Npb24sICRtYXRjaCkpewoJCQlleGl0KCLQndC10YHQutC+0LvRjNC60L4g0L7Qv9C10YDQsNGC0L7RgNC+0LIg0L/QvtC00YDRj9C0Iik7CgkJfWVsc2VpZihwcmVnX21hdGNoX2FsbCgiL1teXCtcLVwqXC9cXlwoXClcZFwuXS91IiwgJHN0cmluZ0V4cHJlc3Npb24sICRtYXRjaCkpewoJCQlleGl0KCLQndC10LjQt9Cy0LXRgdGC0L3Ri9C1INGB0LjQvNCy0L7Qu9GLIik7CgkJfWVsc2VpZihwcmVnX21hdGNoX2FsbCgiL1xkXCh8XClcZHxcKVwoL3UiLCAkc3RyaW5nRXhwcmVzc2lvbiwgJG1hdGNoKSl7CgkJCWV4aXQoItCf0YDQvtC/0YPRidC10L0g0L7Qv9C10YDQsNGC0L7RgCIpOwoJCX0KCQkKCQl3aGlsZSgkdG9rZW5fdHlwZSAhPSBFTkRQQVJTRSl7CgkJCWdldFRva2VuKCRzdHJpbmdFeHByZXNzaW9uKTsKCQkJaWYoJHRva2VuX3R5cGUgPT0gT1BFUkFUT1JUT0sgJiYgJHRva2VuID09ICIpIil7CgkJCQl3aGlsZSgoJG9wID0gJHN0YWNrLT5wb3AoKSkgIT0gIigiKXsKCQkJCQlhcnJheV9wdXNoKCRjb252ZXJzaW9uUmVzdWx0cywgJG9wKTsKCQkJCX0KCQkJfQoJCQlpZigkdG9rZW5fdHlwZSA9PSBOVU1CRVJUT0spIHsKCQkJCWFycmF5X3B1c2goJGNvbnZlcnNpb25SZXN1bHRzLCAkdG9rZW4pOwoJCQl9CgkJCWlmKCR0b2tlbl90eXBlID09IE9QRVJBVE9SVE9LICYmICR0b2tlbiA9PSAiKCIpewoJCQkJJHN0YWNrLT5wdXNoKCR0b2tlbik7CgkJCX0KCQkJaWYoJHRva2VuX3R5cGUgPT0gT1BFUkFUT1JUT0sgJiYgKCR0b2tlbiA9PSAiKyIgfHwgJHRva2VuID09ICItIiB8fCAkdG9rZW4gPT0gIioiIHx8ICR0b2tlbiA9PSAiLyIgfHwgJHRva2VuID09ICJeIikpewoJCQkJaWYoJHN0YWNrLT5jb3VudCgpID09IDApewoJCQkJCSRzdGFjay0+cHVzaCgkdG9rZW4pOwoJCQkJfSBlbHNlIHsKCQkJCQlpZihyZXR1cm5QcGlvcGl0ZXQoJHRva2VuKSA+IHJldHVyblBwaW9waXRldCgkc3RhY2stPnRvcCgpKSl7CgkJCQkJCSRzdGFjay0+cHVzaCgkdG9rZW4pOwoJCQkJCX0gZWxzZSB7CgkJCQkJCXdoaWxlKCRzdGFjay0+Y291bnQoKSAhPTAgJiYgcmV0dXJuUHBpb3BpdGV0KCRzdGFjay0+dG9wKCkpID49IHJldHVyblBwaW9waXRldCgkdG9rZW4pKXsKCQkJCQkJCWFycmF5X3B1c2goJGNvbnZlcnNpb25SZXN1bHRzLCAkc3RhY2stPnBvcCgpKTsKCQkJCQkJfQoJCQkJCQkkc3RhY2stPnB1c2goJHRva2VuKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQkJCgkJfQoJCXdoaWxlKCRzdGFjay0+Y291bnQoKSAhPTApewoJCQlhcnJheV9wdXNoKCRjb252ZXJzaW9uUmVzdWx0cywgJHN0YWNrLT5wb3AoKSk7CgkJfQoJCXJldHVybiAkY29udmVyc2lvblJlc3VsdHM7Cgl9CgkKCWZ1bmN0aW9uIGNvbXB1dGUoJiRzdHJpbmdFeHByZXNzaW9uKXsKCQkkY29udmVyc2lvblJlc3VsdHMgPSBjb252ZXJ0UmV2ZXJzZVBvbGlzaE5vdGF0aW9uKCRzdHJpbmdFeHByZXNzaW9uKTsKCQkkc3RhY2sgPSBuZXcgU3BsU3RhY2soKTsKCQkKCQl3aGlsZShjb3VudCgkY29udmVyc2lvblJlc3VsdHMpICE9MCl7CgkJCSRvcCA9IGFycmF5X3NoaWZ0KCRjb252ZXJzaW9uUmVzdWx0cyk7CgkJCWlmKHJldHVyblBwaW9waXRldCgkb3ApPj0wKXsKCQkJCXN3aXRjaCgkb3ApewoJCQkJCWNhc2UgIisiOgoJCQkJCQkkb3AxID0gJHN0YWNrLT5wb3AoKTsKCQkJCQkJJG9wMiA9ICRzdGFjay0+cG9wKCk7CgkJCQkJCSRzdGFjay0+cHVzaCgoZG91YmxlKSRvcDIgKyAoZG91YmxlKSRvcDEpOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICItIjoKCQkJCQkJJG9wMSA9ICRzdGFjay0+cG9wKCk7CgkJCQkJCSRvcDIgPSAkc3RhY2stPnBvcCgpOwoJCQkJCQkkc3RhY2stPnB1c2goKGRvdWJsZSkkb3AyIC0gKGRvdWJsZSkkb3AxKTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAiKiI6CgkJCQkJCSRvcDEgPSAkc3RhY2stPnBvcCgpOwoJCQkJCQkkb3AyID0gJHN0YWNrLT5wb3AoKTsKCQkJCQkJJHN0YWNrLT5wdXNoKChkb3VibGUpJG9wMiAqIChkb3VibGUpJG9wMSk7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgIi8iOgoJCQkJCQkkb3AxID0gJHN0YWNrLT5wb3AoKTsKCQkJCQkJJG9wMiA9ICRzdGFjay0+cG9wKCk7CgkJCQkJCWlmKCRvcDIgPT0gMCl7CgkJCQkJCQlleGl0KCLQlNC10LvQuNC8INC90LAg0L3QvtC70YwiKTsKCQkJCQkJfQoJCQkJCQkkc3RhY2stPnB1c2goKGRvdWJsZSkkb3AyIC8gKGRvdWJsZSkkb3AxKTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAiXiI6CgkJCQkJCSRvcDEgPSAkc3RhY2stPnBvcCgpOwoJCQkJCQkkb3AyID0gJHN0YWNrLT5wb3AoKTsKCQkJCQkJJHN0YWNrLT5wdXNoKHBvdygoZG91YmxlKSRvcDIsIChkb3VibGUpJG9wMSkpOwoJCQkJCQlicmVhazsKCQkJCX0KCQkJfWVsc2V7CgkJCQkkc3RhY2stPnB1c2goJG9wKTsKCQkJfQoJCX0KCQlyZXR1cm4gJHN0YWNrLT5wb3AoKTsKCX0KCgkkc3RyID0gIjYrNS84KzE1KjkvOCo5LzgqKDU1KzYqNSkiOwoJJHJleiA9IGNvbXB1dGUoJHN0cik7CgllY2hvICRzdHIuIiA9ICIuJHJlei4iXG4iOwoJCgkkc3RyID0gIjYgKyA1XjIqOCArIDYgLyA4OSo4IC0gOSszIjsKCSRyZXogPSBjb21wdXRlKCRzdHIpOwoJZWNobyAkc3RyLiIgPSAiLiRyZXouIlxuIjsKCQoJJHN0ciA9ICI2LjYgKyA1LjJeNS41NTU1KzYvOCo5LjleNTUuNjYiOwoJJHJleiA9IGNvbXB1dGUoJHN0cik7CgllY2hvICRzdHIuIiA9ICIuJHJlei4iXG4iOwoJCgkkc3RyID0gIjYuNiAqICgyKyg2Kyg5LzgpKjYvKDUrOSkpKSI7CgkkcmV6ID0gY29tcHV0ZSgkc3RyKTsKCWVjaG8gJHN0ci4iID0gIi4kcmV6LiJcbiI7CgkKCSRzdHIgPSAiNSAqICgtMyArIDgpIjsKCSRyZXogPSBjb21wdXRlKCRzdHIpOwoJZWNobyAkc3RyLiIgPSAiLiRyZXouIlxuIjsKCQoJJHN0ciA9ICItNSstNiotKC01Ky05KS8tOCs2KjgqKC05LS02KS8tOF4tNiI7CgllY2hvICRzdHI7CgkkcmV6ID0gY29tcHV0ZSgkc3RyKTsKCWVjaG8gIiA9ICIuJHJlei4iXG4iOwoKPz4=