Advertisement
Guest User

Untitled

a guest
Mar 24th, 2019
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 17.32 KB | None | 0 0
  1. <?php
  2. class Translator
  3. {
  4.     private $current_index;
  5.     private $inputCode;
  6.     private $n;
  7.     private $n_max;
  8.     private $vars=array();
  9.     private $let;
  10.     private $int;
  11.     private $debug;
  12.     function construct($text="",$debug=false)
  13.     {
  14.         $this->debug=$debug;
  15.         if($this->debug)
  16.             echo "<br> construct()";
  17.         $this->n=0;
  18.         $this->n_max=2;
  19.         $this->k=0;
  20.         $this->current_index=0;
  21.         $this->inputCode=$text;
  22.     }
  23.  
  24.     private function getEight($x)
  25.     {
  26.         if($x<0)
  27.         {
  28.             $x=abs($x);
  29.             return -decoct($x);
  30.         }
  31.         else
  32.         {
  33.             $x=abs($x);
  34.             return decoct($x);
  35.         }
  36.     }
  37.  
  38.     private function getDecimal($x)
  39.     {
  40.         if($x<0)
  41.             return -octdec($x);
  42.         else
  43.             return octdec($x);
  44.     }
  45.  
  46.     private function add($x1, $x2)
  47.     {
  48.         $x1=$this->getDecimal($x1);
  49.         $x2=$this->getDecimal($x2);
  50.         $y=$x1+$x2;
  51.         $y=$this->getEight($y);
  52.         return ($y);
  53.     }
  54.  
  55.     private function sub($x1, $x2)
  56.     {
  57.         $y=0;
  58.         $x1=$this->getDecimal($x1);
  59.         $x2=$this->getDecimal($x2);
  60.         $y.=$x1-$x2;
  61.         $y=$this->getEight($y);
  62.         return ($y);
  63.     }
  64.  
  65.     private function mult($x1, $x2)
  66.     {
  67.         $y=0;
  68.         $x1=$this->getDecimal($x1);
  69.         $x2=$this->getDecimal($x2);
  70.         $y=$x1*$x2;
  71.         $y=$this->getEight($y);
  72.         return ($y);
  73.     }
  74.  
  75.     private function div($x1, $x2)
  76.     {
  77.         $y=0;
  78.         $x1=$this->getDecimal($x1);
  79.         $x2=$this->getDecimal($x2);
  80.         $y=round($x1/$x2);
  81.         $y=$this->getEight($y);
  82.         return ($y);
  83.     }
  84.  
  85.     private function power($x1, $x2)
  86.     {
  87.         $y=0;
  88.         $x1=$this->getDecimal($x1);
  89.         $x2=$this->getDecimal($x2);
  90.         $y=pow($x1, $x2);
  91.         $y=$this->getEight($y);
  92.         return ($y);
  93.     }
  94.  
  95.     private function number($x)
  96.     {
  97.         if (mb_ereg("[0-7]", $x))
  98.             return true;
  99.         else
  100.             return false;
  101.     }
  102.  
  103.     private function letter($let)
  104.     {
  105.         if (mb_ereg("[а-яА-Я]", $let))
  106.             return true;
  107.         else
  108.             return false;
  109.     }
  110.  
  111.     public function printVars()
  112.     {
  113.         $html="<ul>";
  114.         foreach ($this->vars as $key=>$value)
  115.         {
  116.             $html.="<li>{$key}={$value}</li>";
  117.         }
  118.         $html.="</ul>";
  119.         return $html;
  120.     }
  121.  
  122.     public function setText($text)
  123.     {
  124.         if($this->debug)
  125.             echo"<br>setText()";
  126.         $this->inputCode=$text;
  127.     }
  128.  
  129.     public function run()
  130.     {
  131.         if($this->debug)
  132.             echo "<br>run()";
  133.         try
  134.         {
  135.             mb_internal_encoding("UTF-8");
  136.             mb_regex_encoding("UTF-8");
  137.             $interenc=mb_internal_encoding();
  138.             $this->inputCode=mb_convert_encoding($this->inputCode, $interenc, "UTF-8");
  139.             $this->inputCode=mb_ereg_replace("<span.*?>|<\/span>","",$this->inputCode);
  140.             $this->inputCode=mb_ereg_replace("<p>","@",$this->inputCode);
  141.             $this->inputCode=mb_ereg_replace("</p>","#",$this->inputCode);
  142.             $this->inputCode=mb_ereg_replace("&nbsp;","",$this->inputCode);
  143.             $this->language();
  144.         }
  145.         catch(Exception $e)
  146.         {
  147.             echo '<div id="errors"><b>Ошибка:</b>', $e - getMessage(), "\n", "</div>";
  148.             $this->skipSpaces(true);
  149.             if (mb_ereg_replace("\r|\n", "", mb_subst($this->inputCode, $this->current_index, 1)) == "")
  150.             {
  151.                 $this->current_index += 2;
  152.                 $text = mb_ereg_replace("\r\n", "", mb_substr($this->inputCode, 0, $this->current_index)) .
  153.                     "<span style='background-color:red;'>"
  154.                     . mb_ereg_replace("\r\n", "", mb_substr($this->inputCode, $this->current_index, 1))
  155.                     . "</span>"
  156.                     . mb_ereg_replace("\r\n", "", mb_substr($this->inputCode, $this->current_index + 1, mb_strwidth($this->inputCode) - $this->current_index));
  157.             }
  158.             else
  159.             {
  160.                 $text=mb_ereg_replace("\r\n","",mb_substr($this->inputCode, 0,$this->current_index,1).
  161.                     "<span style='background-color:red;'>"
  162.                     . mb_ereg_replace("\r\n", "", mb_substr($this->inputCode, $this->current_index, 1))
  163.                     . "</span>"
  164.                     .mb_ereg_replace("\r\n","",mb_substr($this->inputCode,$this->current_index+1,mb_strwidth($this->inputCode)-$this->current_index)));
  165.             }
  166.  
  167.             $text = mb_ereg_replace("@", "<p>", $text);
  168.             $text = mb_ereg_replace("#", "</p>", $text);
  169.             //$text=mb_ereg_replace("\&nbsp"," ",$text);
  170.             $text = mb_ereg_replace("\r\n", "", $text);
  171.             echo "<script>
  172.                    setText(\"{$text}\");
  173.                    </script>";
  174.             exit();
  175.         }
  176.  
  177.             $text=mb_ereg_replace("@","<p>",$this->inputCode);
  178.             $text=mb_ereg_replace("#","</p>",$text);
  179.             //$text=mb_ereg_replace("\&nbsp"," ",$text);
  180.             $text=mb_ereg_replace("\r\n","",$text);
  181.             echo"<script>
  182.                setText(\"{$text}\");
  183.                </script>";
  184.     }
  185.  
  186.     private function skipSpaces($skipRN=false)
  187.     {
  188.         while(true)
  189.         {
  190.             $ch=$this->getChar($this->current_index);
  191.             if($ch=="&")
  192.             {
  193.                 if(mb_substr($this->inputCode, $this->current_index, mb_strwidth("&nbsp;"))=="&nbsp;")
  194.                 {
  195.                     $this->current_index+=mb_strwidth("&nbsp;");
  196.                 }
  197.                 else
  198.                     break;
  199.             }
  200.             else
  201.                 if ($ch==" "||$ch=="@"||$ch=="#")
  202.                 {
  203.                     $this->current_index++;
  204.                     continue;
  205.                 }
  206.                 else
  207.                     if($skipRN)
  208.                     {
  209.                         if($ch=="\r"||$ch=="\n")
  210.                         {
  211.                             $this->current_index++;
  212.                             continue;
  213.                         }
  214.                         else
  215.                         {
  216.                             break;
  217.                         }
  218.                     }
  219.                     else
  220.                     {
  221.                         break;
  222.                     }
  223.         };
  224.     }
  225.  
  226.     private function getChar($i)
  227.     {
  228.         return mb_substr($this->inputCode,$i,1);
  229.     }
  230.  
  231.     private function language()
  232.     {
  233.         if($this->debug)
  234.             echo "<br>language()";
  235.  
  236.         $this->skipSpaces(true);
  237.         if(mb_substr($this->inputCode, $this->current_index, mb_strwidth("Программа"))!="Программа")
  238.         {
  239.             throw new Exception("Ожидалось слово \"Программа\"");
  240.         }
  241.         $this->current_index += mb_strwidth("Программа");;
  242.         $this->skipSpaces();
  243.         $this->zvenia();
  244.         if($this->k!=0)
  245.             return;
  246.         $this->skipSpaces();
  247.         if(mb_substr($this->inputCode, $this->current_index, mb_strwidth("Конец"))!="Конец")
  248.         {
  249.             throw new Exception("Ожидалось слово \"Конец\"");
  250.         }
  251.         $this->current_index =+ mb_strwidth("Конец");
  252.         $this->skipSpaces(true);
  253.         if($this->current_index<mb_strwidth($this->inputCode))
  254.             throw new Exception("Лишний код после программы");
  255.     }
  256.  
  257.     private function zvenia()
  258.     {
  259.         if($this->debug)
  260.             echo "<br>zvenia";
  261.         /*
  262.          * for(;;) zveno()";"
  263.         */
  264.         do
  265.         {
  266.             $this->skipSpaces();
  267.             if($this->k!=0)
  268.                 return;
  269.             if($this->getChar($this->current_index)==";")
  270.             {
  271.                 $this->current_index++;
  272.                 continue;
  273.             }
  274.  
  275.             if($this->current_index>mb_strwidth($this->inputCode))
  276.                 break;
  277.             $this->skipSpaces();
  278.         }
  279.         while((mb_substr($this->inputCode, $this->current_index, mb_strwidth("Конец"))!="Конец"));
  280.     }
  281.  
  282.     private function missInt($index)
  283.     {
  284.         if($this->debug)
  285.             echo"<br>missInt()";
  286.         do
  287.         {
  288.             $ch=$this->getChar($index);
  289.             $index++;
  290.         }
  291.         while(($this->number($ch)));
  292.         return $this->getChar($index);
  293.     }
  294.  
  295.     private function zveno()
  296.     {
  297.         if ($this->debug)
  298.             echo "<br>zveno()";
  299.         $this->skipSpaces(true);
  300.         if (mb_substr($this->inputCode, $this->current_index, mb_strwidth("Ввод")) != "Ввод")
  301.         {
  302.             throw new Exception("Ожидалось слово \"Ввод\"");
  303.         }
  304.         $this->current_index += mb_strwidth("Ввод");
  305.         do
  306.         {
  307.             $this->word();
  308.             if($this->current_index>mb_strwidth($this->inputCode))
  309.                 break;
  310.             if($this->k!=0)
  311.                 return;
  312.             $this->skipSpaces(false);
  313.             if(($this->getChar($this->current_index)=="\r")and($this->getChar($this->current_index+1)=="\n"))
  314.             {
  315.                 $this->current_index +=2;
  316.             }
  317.             /*
  318.             else
  319.             {
  320.                 if($this->getChar($this->current_index)==",")
  321.                 {
  322.                     $this->current_index++;
  323.                 }
  324.             }
  325.             */
  326.             elseif(!(($this->missInt($this->current_index)!=":")and($this->getChar($this->current_index)!=";")and(mb_substr($this->inputCode, $this->current_index, mb_strwidth("Конец"))!="Конец")))
  327.             {
  328.                 ;
  329.             }
  330.             else
  331.             {
  332.                 throw new Exception("Ожидались знак операции, перевод строки или \";\"");
  333.             }
  334.             $this->skipSpaces();
  335.         }
  336.         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("Конец"))!="Конец"));
  337.     }
  338.  
  339.     public function word()
  340.     {
  341.         if($this->debug)
  342.             echo"<br>word()";
  343.         $this->n=0;
  344.         $this->skipSpaces(true);
  345.         $this->int();
  346.         $this->skipSpaces(true);
  347.         if($this->getChar($this->current_index)!=":")
  348.         {
  349.             throw new Exception("Ожидалось \":\"");
  350.         }
  351.         $this->current_index++;
  352.         $var_name=$this->perem();
  353.         $this->skipSpaces();
  354.         if($this->getChar($this->current_index)!="=")
  355.         {
  356.             throw new Exception("Ожидалось \"=\"");
  357.         }
  358.         $this->current_index++;
  359.         $val=$this->rightPart();
  360.         $this->vars[$var_name]=$val;
  361.         if($this->debug)
  362.             echo"<hr>perem={$perem}<hr>";
  363.         if($this->k!=0)
  364.             return;
  365.     }
  366.  
  367.     public function rightPart()
  368.     {
  369.         if($this->debug)
  370.             echo"<br>rightPart()";
  371.         $rp=0;
  372.         $this->skipSpaces();
  373.         if($this->getChar($this->current_index)=="-")
  374.         {
  375.             $this->current_index++;
  376.             $rp=-$this->block1();
  377.             if($this->k!=0)
  378.                 return;
  379.         }
  380.         else
  381.         {
  382.             $rp=$this->block1();
  383.             if($this->k!=0)
  384.                 return;
  385.         }
  386.  
  387.         do
  388.         {
  389.             $this->skipSpaces();
  390.             if($this->getChar($this->current_index)=="+")
  391.             {
  392.                 $this->current_index++;
  393.                 $rp=$this->sub($rp, $this->block1());
  394.                 if($this->k!=0)
  395.                     return;
  396.             }
  397.         }
  398.         while(($this->getChar($this->current_index)=="+")||($this->getChar($this->current_index)=="-"));
  399.         return $rp;
  400.     }
  401.  
  402.     //multiplicative
  403.     private function block1()
  404.     {
  405.         if($this->debug)
  406.             echo"<br>block1()";
  407.         $rp=0;
  408.         $block1=$this->block2();
  409.         if($this->k!=0)
  410.             return;
  411.         do
  412.         {
  413.             $this->skipSpaces();
  414.             if($this->getChar($this->current_index)=="*")
  415.             {
  416.                 $this->current_index++;
  417.                 $block1=$this->mult($block1,$this->block2());
  418.                 if($this->k!=0)
  419.                     return;
  420.             }
  421.             elseif($this->getChar($this->current_index)=="/")
  422.             {
  423.                 $this->current_index++;
  424.                 $block2=$this->block2();
  425.                 if($block2==0)
  426.                 {
  427.                     $this->current_index-=2;
  428.                     throw new Exception("Деление на 0 не разрешено");
  429.                 }
  430.                 $block1-$this->div($block1, $block2);
  431.                 if($this->k!=0)
  432.                     return;
  433.             }
  434.         }
  435.         while(($this->getChar($this->current_index)=="*")||($this->getChar($this->current_index)=="/"));
  436.         return $block1;
  437.     }
  438.  
  439.     private function block2()
  440.     {
  441.         if ($this->debug)
  442.             echo"<br>block2()";
  443.         $block2=0;
  444.         $block2=$this->block3();
  445.         if($this->k!=0)
  446.             return;
  447.         do
  448.         {
  449.             $this->current_indx++;
  450.             $block3=$this->block3();
  451.             $block2=$this->power($block2,$block3);
  452.             if($this->k!=0)
  453.                 return;
  454.         }
  455.         while(($this->getChar($this->current_index)=="^"));
  456.         return $block2;
  457.     }
  458.  
  459.     private function block3()
  460.     {
  461.         if($this->debug)
  462.             echo"<br>block3()";
  463.         $block3=0;
  464.         $this->skipSpaces();
  465.         if($this->getChar($this->current_index)=="(")
  466.         {
  467.             $this->current_index++;
  468.             $block3 = $this->rightPart();
  469.             if ($this->getChar($this->current_index) == ")") {
  470.                 $this->current_index++;
  471.             } else {
  472.                 $k = 1;
  473.                 throw new Excepton("Нет закрывающей круглой скобки");
  474.             }
  475.         }
  476.         elseif ($this->getChar($this->current_index)=="[")
  477.         {
  478.             $this->current_index++;
  479.             $this->n++;
  480.             if($this->n>$this->n_max)
  481.             {
  482.                 $k=1;
  483.                 throw new Exception("Глубина вложенности квадратных скобок не должна превышать 2");
  484.             }
  485.             $block3-$this->rightPart();
  486.             if($this->getChar($this->current_index)=="]")
  487.             {
  488.                 $this->current_index++;
  489.             }
  490.             else
  491.             {
  492.                 $k=1;
  493.                 throw new Exception("Нет закрывающей квадратной скобки");
  494.             }
  495.         }
  496.         elseif ($this->letter($this->getChar($this->current_index)))
  497.         {
  498.             $block3=$this->getVar();
  499.         }
  500.         elseif($this->number($this->getChar($this->current_index)))
  501.         {
  502.             $block3=$this->int();
  503.         }
  504.         else
  505.         {
  506.             throw new Exception("Ожидались \"(\", \"[\", переменная или целое");
  507.         }
  508.         return $block3;
  509.     }
  510.  
  511.     private function getVar()
  512.     {
  513.         if($this->debug)
  514.             echo"<br>getVar()";
  515.         $name=$this->readVar();
  516.         if(isset($this->vars[$name]))
  517.             return $this->vars[$name];
  518.         else
  519.         {
  520.             $this->current_index -= mb_strwidth($name);
  521.             throw new Exception("Неизвестная переменная");
  522.         }
  523.     }
  524.  
  525.     private function readVar()
  526.     {
  527.         if($this->debug)
  528.             echo"<br>readVar()";
  529.         $var="";
  530.         $this->skipSpaces();
  531.         if(!$this->letter($this->getChar($this->current_index)))
  532.         {
  533.             throw new Exception("Ожидалась буква");
  534.         }
  535.         $var.=$this->getChar($this->current_index);
  536.         $this->current_index++;
  537.         for($i=0;$i<3;$i++)
  538.         {
  539.             $this->skipSpaces();
  540.             $ch=$this->getChar($this->current_index);
  541.             $var.=$this->getChar($this->current_index);
  542.             $this->current_index++;
  543.             if(!($this->number($ch)))
  544.             {
  545.                 throw new Exception("Ожидалась цифра");
  546.             }
  547.         }
  548.         return $var;
  549.     }
  550.  
  551.     private function perem()
  552.     {
  553.         if($this->debug)
  554.             echo"<br>perem()";
  555.         $name=$this->readVar();
  556.         return$name;
  557.     }
  558.  
  559.     private function int()
  560.     {
  561.         $x="";
  562.         if($this->debug)
  563.             echo"<br>int()";
  564.         $this->skipSpaces();
  565.         if($this->number($this->getChar($this->current_index)))
  566.         {
  567.             do
  568.             {
  569.                 $this->skipSpaces();
  570.                 if($this->number($this->getChar($this->current_index)))
  571.                 {
  572.                     $x .= $this->getChar($this->current_index);
  573.                     $this->current_index++;
  574.                 }
  575.                 else
  576.                 {
  577.                     break;
  578.                 }
  579.             }
  580.             while(true);
  581.         }
  582.         else
  583.         {
  584.             throw new Exception("Ожидалось целое");
  585.         }
  586.         return (int)$x;
  587.     }
  588. }
  589. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement