Autor Zpráva
Stano
Profil *
Zdravím, neriešil niekto z Vás lexikálny analyzátor na matematické operácie? Ide mi o to že mám dáky string s násobenim delením sčítavaním dake zátvorky [a=(c+b)/f+10*a)]. Php mi to samozrejme bez problémov spočíta, kým tam nemám polia (matice) no a presne s nimi potrebujem počítať. Takže potrebujem kód, ktorý to prejde a začne od najvnútornejších zátvoriek počítať.

Nápady ako by som to riešil mám, len pochybujem, že by som to na prvý krát vyriešil optimálne a keďže to bude pomerne dôležitá časť kódu tak ju chcem mat trocha optimalizovanú. Na internete som nič také nenašiel tak sa skúsim spýtať ešte aj tu. A ak nič tak to začnem písať niečo svoje.

V podstate mi stačia aj dobré rady. Zatial dik Stano
TomášK
Profil
To mi zní povědomě :-) Na MFF je předmět principy překladačů, kde se dělá překlad (skoro) pascalového kódu do instrukcí pro virtuální stroj, viz http://data.ksi.ms.mff.cuni.cz/svn/NSWI098pub/html/index.html. Šlo by to ořezat o překlad do instrukcí a jazykové konstrukce typu cykly apod., pak by z toho vypadlo to, co potřebujete. Lze použít tytéž nástroje - Flex a Bison. Ale možná je to celé příilš velký kanón na to, co potřebujete. Hodit by se mohl taky článek na wiki: http://en.wikipedia.org/wiki/Recursive_descent_parser
Stano
Profil *
keďže som nič nenašiel tak som daco spravil. Ak sa niekomu chce tak sa môže pozrieť či sa to nedá viac optimalizovať.

ak by to niekto hľadal tak nech sa páči.

$string = "(10*5*(5-8)+(5*5-6))";

$lenght = strlen($string);
    
    $uroven = 0;
    $uroven_max = 0;
    $zatvorka = 0;
    $j = 0;
    
    $begin = 0;
    $end = 0;
    
    for($i=0;$i<$lenght;$i++){
      if($string[$i] == "("){
        $string_structure[$j++] = array('position' => $i, 'uroven' => $uroven++, 'zatvorka' => $zatvorka++);
        $begin++;
        
        }
      elseif($string[$i] == ")"){
        $uroven--;
        if($uroven_max < $uroven){$uroven_max = $uroven;}
        $end++;
        }
      }
    if($begin < $end){die("Chýba začiatok zátvorky");}
    elseif($begin > $end){die("Chýba koniec zátvorky");}  
    
    
    $z = 0;
    for($i=$uroven_max;$i>=0;$i--){
      for($j=0;$j<count($string_structure);$j++){
        if($string_structure[$j]["uroven"] == $i){
          $string_structure_order[$z++] = $string_structure[$j];
          }
        }
      }
    for($i=0;$i<count($string_structure_order);$i++){
      $position =  $string_structure_order[$i]["position"];
  
      for($j=$position;$j<$lenght;$j++){
        
        $odcitaj++;
        $string_partial[$i] .= $string[$j];
        
        if($string[$j] == "("){$next++;}
        if($string[$j] == ")"){$next--;}
        if($next == 0){
          for($k=0;$k<count($string_partial)-1;$k++){
            //$l = $k+1;
            $string_partial[$i] = str_replace($string_partial[$k],"vysledok[$k]",$string_partial[$i]);
            //$string_partial[$i] = "(min(10,5) * 5)";
            }
          
          $s_array = make_math_array($string_partial[$i]);
          //show($s_array);
          //$s_array = wp_math_functions_replace($s_array);
          //$s_array = wp_math_implemented_functions($s_array);
                 
          for($f=0;$f<count($s_array);$f++){
            //echo $s_array[$f]." <**>";
            if($s_array[$f] == "*"){
              echo $vzorec = "\$medzi_vysledok = wp_math_multiply(".$s_array[$f-1].",".$s_array[$f+1].");";
              eval($vzorec);
              $s_array[$f-1] = "\$medzi_vysledok";
              $s_array[$f+1] = "\$medzi_vysledok";
              //echo $medzi_vysledok[$n++];
              $n++;
              }
            elseif($s_array[$f] == "/"){
              $vzorec = "\$medzi_vysledok = wp_math_divide(".$s_array[$f-1].",".$s_array[$f+1].");";
              eval($vzorec);
              $s_array[$f-1] = "\$medzi_vysledok";
              $s_array[$f+1] = "\$medzi_vysledok";
              $n++;
              }
            }   
          for($f=0;$f<count($s_array);$f++){
            if($s_array[$f] == "+"){
              $vzorec = "\$medzi_vysledok = wp_math_add(".$s_array[$f-1].",".$s_array[$f+1].");";
              eval($vzorec);
              $s_array[$f-1] = "\$medzi_vysledok";
              $s_array[$f+1] = "\$medzi_vysledok";
              $n++;
              
              }
            elseif($s_array[$f] == "-"){
              $vzorec = "\$medzi_vysledok = wp_math_subtract(".$s_array[$f-1].",".$s_array[$f+1].");";
              eval($vzorec);
              $s_array[$f-1] = "\$medzi_vysledok";
              $s_array[$f+1] = "\$medzi_vysledok";
              $n++;
              }
            else{}
            }
  
        $vysledok[$i] = $medzi_vysledok;
        break;}
        } 
      
      }
      
echo $string."=".$medzi_vysledok;
      
function wp_math_add($a,$b){
  $c = $a + $b;
  return $c;
  } 

function wp_math_subtract($a,$b){
  $c = $a - $b;
  return $c;
  } 

function wp_math_divide($a,$b){
  $c = $a / $b;
  return $c;
  } 
  
function wp_math_multiply($a,$b){
  $c = $a * $b;
  return $c;
  }       

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: