Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- class Translator
- {
- private $current_index;
- private $inputCode;
- private $n;
- private $n_max;
- private $vars=array();
- private $let;
- private $int;
- private $debug;
- function construct($text="",$debug=false)
- {
- $this->debug=$debug;
- if($this->debug)
- echo "<br> construct()";
- $this->n=0;
- $this->n_max=2;
- $this->k=0;
- $this->current_index=0;
- $this->inputCode=$text;
- }
- private function getEight($x)
- {
- if($x<0)
- {
- $x=abs($x);
- return -decoct($x);
- }
- else
- {
- $x=abs($x);
- return decoct($x);
- }
- }
- private function getDecimal($x)
- {
- if($x<0)
- return -octdec($x);
- else
- return octdec($x);
- }
- private function add($x1, $x2)
- {
- $x1=$this->getDecimal($x1);
- $x2=$this->getDecimal($x2);
- $y=$x1+$x2;
- $y=$this->getEight($y);
- return ($y);
- }
- private function sub($x1, $x2)
- {
- $y=0;
- $x1=$this->getDecimal($x1);
- $x2=$this->getDecimal($x2);
- $y.=$x1-$x2;
- $y=$this->getEight($y);
- return ($y);
- }
- private function mult($x1, $x2)
- {
- $y=0;
- $x1=$this->getDecimal($x1);
- $x2=$this->getDecimal($x2);
- $y=$x1*$x2;
- $y=$this->getEight($y);
- return ($y);
- }
- private function div($x1, $x2)
- {
- $y=0;
- $x1=$this->getDecimal($x1);
- $x2=$this->getDecimal($x2);
- $y=round($x1/$x2);
- $y=$this->getEight($y);
- return ($y);
- }
- private function power($x1, $x2)
- {
- $y=0;
- $x1=$this->getDecimal($x1);
- $x2=$this->getDecimal($x2);
- $y=pow($x1, $x2);
- $y=$this->getEight($y);
- return ($y);
- }
- private function number($x)
- {
- if (mb_ereg("[0-7]", $x))
- return true;
- else
- return false;
- }
- private function letter($let)
- {
- if (mb_ereg("[а-яА-Я]", $let))
- return true;
- else
- return false;
- }
- public function printVars()
- {
- $html="<ul>";
- foreach ($this->vars as $key=>$value)
- {
- $html.="<li>{$key}={$value}</li>";
- }
- $html.="</ul>";
- return $html;
- }
- public function setText($text)
- {
- if($this->debug)
- echo"<br>setText()";
- $this->inputCode=$text;
- }
- public function run()
- {
- if($this->debug)
- echo "<br>run()";
- try
- {
- mb_internal_encoding("UTF-8");
- mb_regex_encoding("UTF-8");
- $interenc=mb_internal_encoding();
- $this->inputCode=mb_convert_encoding($this->inputCode, $interenc, "UTF-8");
- $this->inputCode=mb_ereg_replace("<span.*?>|<\/span>","",$this->inputCode);
- $this->inputCode=mb_ereg_replace("<p>","@",$this->inputCode);
- $this->inputCode=mb_ereg_replace("</p>","#",$this->inputCode);
- $this->inputCode=mb_ereg_replace(" ","",$this->inputCode);
- $this->language();
- }
- catch(Exception $e)
- {
- echo '<div id="errors"><b>Ошибка:</b>', $e - getMessage(), "\n", "</div>";
- $this->skipSpaces(true);
- if (mb_ereg_replace("\r|\n", "", mb_subst($this->inputCode, $this->current_index, 1)) == "")
- {
- $this->current_index += 2;
- $text = mb_ereg_replace("\r\n", "", mb_substr($this->inputCode, 0, $this->current_index)) .
- "<span style='background-color:red;'>"
- . mb_ereg_replace("\r\n", "", mb_substr($this->inputCode, $this->current_index, 1))
- . "</span>"
- . mb_ereg_replace("\r\n", "", mb_substr($this->inputCode, $this->current_index + 1, mb_strwidth($this->inputCode) - $this->current_index));
- }
- else
- {
- $text=mb_ereg_replace("\r\n","",mb_substr($this->inputCode, 0,$this->current_index,1).
- "<span style='background-color:red;'>"
- . mb_ereg_replace("\r\n", "", mb_substr($this->inputCode, $this->current_index, 1))
- . "</span>"
- .mb_ereg_replace("\r\n","",mb_substr($this->inputCode,$this->current_index+1,mb_strwidth($this->inputCode)-$this->current_index)));
- }
- $text = mb_ereg_replace("@", "<p>", $text);
- $text = mb_ereg_replace("#", "</p>", $text);
- //$text=mb_ereg_replace("\ "," ",$text);
- $text = mb_ereg_replace("\r\n", "", $text);
- echo "<script>
- setText(\"{$text}\");
- </script>";
- exit();
- }
- $text=mb_ereg_replace("@","<p>",$this->inputCode);
- $text=mb_ereg_replace("#","</p>",$text);
- //$text=mb_ereg_replace("\ "," ",$text);
- $text=mb_ereg_replace("\r\n","",$text);
- echo"<script>
- setText(\"{$text}\");
- </script>";
- }
- private function skipSpaces($skipRN=false)
- {
- while(true)
- {
- $ch=$this->getChar($this->current_index);
- if($ch=="&")
- {
- if(mb_substr($this->inputCode, $this->current_index, mb_strwidth(" "))==" ")
- {
- $this->current_index+=mb_strwidth(" ");
- }
- else
- break;
- }
- else
- if ($ch==" "||$ch=="@"||$ch=="#")
- {
- $this->current_index++;
- continue;
- }
- else
- if($skipRN)
- {
- if($ch=="\r"||$ch=="\n")
- {
- $this->current_index++;
- continue;
- }
- else
- {
- break;
- }
- }
- else
- {
- break;
- }
- };
- }
- private function getChar($i)
- {
- return mb_substr($this->inputCode,$i,1);
- }
- private function language()
- {
- if($this->debug)
- echo "<br>language()";
- $this->skipSpaces(true);
- if(mb_substr($this->inputCode, $this->current_index, mb_strwidth("Программа"))!="Программа")
- {
- throw new Exception("Ожидалось слово \"Программа\"");
- }
- $this->current_index += mb_strwidth("Программа");;
- $this->skipSpaces();
- $this->zvenia();
- if($this->k!=0)
- return;
- $this->skipSpaces();
- if(mb_substr($this->inputCode, $this->current_index, mb_strwidth("Конец"))!="Конец")
- {
- throw new Exception("Ожидалось слово \"Конец\"");
- }
- $this->current_index =+ mb_strwidth("Конец");
- $this->skipSpaces(true);
- if($this->current_index<mb_strwidth($this->inputCode))
- throw new Exception("Лишний код после программы");
- }
- private function zvenia()
- {
- if($this->debug)
- echo "<br>zvenia";
- /*
- * for(;;) zveno()";"
- */
- do
- {
- $this->skipSpaces();
- if($this->k!=0)
- return;
- if($this->getChar($this->current_index)==";")
- {
- $this->current_index++;
- continue;
- }
- if($this->current_index>mb_strwidth($this->inputCode))
- break;
- $this->skipSpaces();
- }
- while((mb_substr($this->inputCode, $this->current_index, mb_strwidth("Конец"))!="Конец"));
- }
- private function missInt($index)
- {
- if($this->debug)
- echo"<br>missInt()";
- do
- {
- $ch=$this->getChar($index);
- $index++;
- }
- while(($this->number($ch)));
- return $this->getChar($index);
- }
- private function zveno()
- {
- if ($this->debug)
- echo "<br>zveno()";
- $this->skipSpaces(true);
- if (mb_substr($this->inputCode, $this->current_index, mb_strwidth("Ввод")) != "Ввод")
- {
- throw new Exception("Ожидалось слово \"Ввод\"");
- }
- $this->current_index += mb_strwidth("Ввод");
- do
- {
- $this->word();
- if($this->current_index>mb_strwidth($this->inputCode))
- break;
- if($this->k!=0)
- return;
- $this->skipSpaces(false);
- if(($this->getChar($this->current_index)=="\r")and($this->getChar($this->current_index+1)=="\n"))
- {
- $this->current_index +=2;
- }
- /*
- else
- {
- if($this->getChar($this->current_index)==",")
- {
- $this->current_index++;
- }
- }
- */
- elseif(!(($this->missInt($this->current_index)!=":")and($this->getChar($this->current_index)!=";")and(mb_substr($this->inputCode, $this->current_index, mb_strwidth("Конец"))!="Конец")))
- {
- ;
- }
- else
- {
- throw new Exception("Ожидались знак операции, перевод строки или \";\"");
- }
- $this->skipSpaces();
- }
- while(($this->missInt($this->current_index)!=":")and($this->getChar($this->current_index)!=";")and($this->getChar($this->current_index)!=",")and(mb_substr($this->inputCode, $this->curent_index, mb_strwidth("Конец"))!="Конец"));
- }
- public function word()
- {
- if($this->debug)
- echo"<br>word()";
- $this->n=0;
- $this->skipSpaces(true);
- $this->int();
- $this->skipSpaces(true);
- if($this->getChar($this->current_index)!=":")
- {
- throw new Exception("Ожидалось \":\"");
- }
- $this->current_index++;
- $var_name=$this->perem();
- $this->skipSpaces();
- if($this->getChar($this->current_index)!="=")
- {
- throw new Exception("Ожидалось \"=\"");
- }
- $this->current_index++;
- $val=$this->rightPart();
- $this->vars[$var_name]=$val;
- if($this->debug)
- echo"<hr>perem={$perem}<hr>";
- if($this->k!=0)
- return;
- }
- public function rightPart()
- {
- if($this->debug)
- echo"<br>rightPart()";
- $rp=0;
- $this->skipSpaces();
- if($this->getChar($this->current_index)=="-")
- {
- $this->current_index++;
- $rp=-$this->block1();
- if($this->k!=0)
- return;
- }
- else
- {
- $rp=$this->block1();
- if($this->k!=0)
- return;
- }
- do
- {
- $this->skipSpaces();
- if($this->getChar($this->current_index)=="+")
- {
- $this->current_index++;
- $rp=$this->sub($rp, $this->block1());
- if($this->k!=0)
- return;
- }
- }
- while(($this->getChar($this->current_index)=="+")||($this->getChar($this->current_index)=="-"));
- return $rp;
- }
- //multiplicative
- private function block1()
- {
- if($this->debug)
- echo"<br>block1()";
- $rp=0;
- $block1=$this->block2();
- if($this->k!=0)
- return;
- do
- {
- $this->skipSpaces();
- if($this->getChar($this->current_index)=="*")
- {
- $this->current_index++;
- $block1=$this->mult($block1,$this->block2());
- if($this->k!=0)
- return;
- }
- elseif($this->getChar($this->current_index)=="/")
- {
- $this->current_index++;
- $block2=$this->block2();
- if($block2==0)
- {
- $this->current_index-=2;
- throw new Exception("Деление на 0 не разрешено");
- }
- $block1-$this->div($block1, $block2);
- if($this->k!=0)
- return;
- }
- }
- while(($this->getChar($this->current_index)=="*")||($this->getChar($this->current_index)=="/"));
- return $block1;
- }
- private function block2()
- {
- if ($this->debug)
- echo"<br>block2()";
- $block2=0;
- $block2=$this->block3();
- if($this->k!=0)
- return;
- do
- {
- $this->current_indx++;
- $block3=$this->block3();
- $block2=$this->power($block2,$block3);
- if($this->k!=0)
- return;
- }
- while(($this->getChar($this->current_index)=="^"));
- return $block2;
- }
- private function block3()
- {
- if($this->debug)
- echo"<br>block3()";
- $block3=0;
- $this->skipSpaces();
- if($this->getChar($this->current_index)=="(")
- {
- $this->current_index++;
- $block3 = $this->rightPart();
- if ($this->getChar($this->current_index) == ")") {
- $this->current_index++;
- } else {
- $k = 1;
- throw new Excepton("Нет закрывающей круглой скобки");
- }
- }
- elseif ($this->getChar($this->current_index)=="[")
- {
- $this->current_index++;
- $this->n++;
- if($this->n>$this->n_max)
- {
- $k=1;
- throw new Exception("Глубина вложенности квадратных скобок не должна превышать 2");
- }
- $block3-$this->rightPart();
- if($this->getChar($this->current_index)=="]")
- {
- $this->current_index++;
- }
- else
- {
- $k=1;
- throw new Exception("Нет закрывающей квадратной скобки");
- }
- }
- elseif ($this->letter($this->getChar($this->current_index)))
- {
- $block3=$this->getVar();
- }
- elseif($this->number($this->getChar($this->current_index)))
- {
- $block3=$this->int();
- }
- else
- {
- throw new Exception("Ожидались \"(\", \"[\", переменная или целое");
- }
- return $block3;
- }
- private function getVar()
- {
- if($this->debug)
- echo"<br>getVar()";
- $name=$this->readVar();
- if(isset($this->vars[$name]))
- return $this->vars[$name];
- else
- {
- $this->current_index -= mb_strwidth($name);
- throw new Exception("Неизвестная переменная");
- }
- }
- private function readVar()
- {
- if($this->debug)
- echo"<br>readVar()";
- $var="";
- $this->skipSpaces();
- if(!$this->letter($this->getChar($this->current_index)))
- {
- throw new Exception("Ожидалась буква");
- }
- $var.=$this->getChar($this->current_index);
- $this->current_index++;
- for($i=0;$i<3;$i++)
- {
- $this->skipSpaces();
- $ch=$this->getChar($this->current_index);
- $var.=$this->getChar($this->current_index);
- $this->current_index++;
- if(!($this->number($ch)))
- {
- throw new Exception("Ожидалась цифра");
- }
- }
- return $var;
- }
- private function perem()
- {
- if($this->debug)
- echo"<br>perem()";
- $name=$this->readVar();
- return$name;
- }
- private function int()
- {
- $x="";
- if($this->debug)
- echo"<br>int()";
- $this->skipSpaces();
- if($this->number($this->getChar($this->current_index)))
- {
- do
- {
- $this->skipSpaces();
- if($this->number($this->getChar($this->current_index)))
- {
- $x .= $this->getChar($this->current_index);
- $this->current_index++;
- }
- else
- {
- break;
- }
- }
- while(true);
- }
- else
- {
- throw new Exception("Ожидалось целое");
- }
- return (int)$x;
- }
- }
- ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement