COMBIEs 1 Pass Formelparser und Interpreter

Operatoren

Für jeden Operator ist im Operatoren-Array eine Funktion anzugeben, welche dann vom Parser aufgerufen wird.

Rangfolge der Operatoren

Punkt vor Strich:
Die Rangfolge wird im Operatoren-Array festgelegt. In diesem Formel Parser gilt: Niedriger Rang gleich hohe Priorität. In der Formel kann die Auswertungsreihenfolge durch Klammerungen beeinflußt werden. 2^3^4 wird ausgewertet wie (2^3)^4. Dieses: 2^(3^4) erzwingt eine andere Reihenfolge.

Bindung der Operatoren

Es gibt 3 Arten von Operatoren

Die Bindung sagt, wo der jeweilige Operator seinen Parameter her bekommt. Zum Beispiel das Plus Zeichen benötigt 2 Parameter. Einen Rechten und einen Linken. Die Fakultät benötigt einen Linken. Also so: 5!. Die Absolut Funktion ist Rechts bindend. abs -5.

Funktionen

Hinter jedem Operator steht eine PHP Funktion. Das kann sowohl eine eingebaute, als auch eine selbstgeschriebene sein. Es gibt mehrere Möglichkeiten diese Funktion im Operatoren-Array zu deklarieren. Benutzt wird der im PHP eingebaute Callback Mechanismus.

<?php
// die klassische Variante
$operatoren['sin'] = array('rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS,
                          
'funktion'=>'sin');
?>
<?php
// mit statischen Klassen Methoden
$operatoren['sin'] = array('rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS,
                          
'funktion'=>array('Klasse','sin'));
?>
<?php
// Methoden einer instanzierten Klasse
$operatoren['sin'] = array('rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS,
                          
'funktion'=>array($instance,'sin'));
?>
<?php
// die PHP >= 5.3 Namespace Variante des Aufrufs einer statischen Methode
$operatoren['sin'] = array('rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS,
                          
'funktion'=>'NamensRaum::Klasse::sin');
?>
<?php
// die PHP >= 5.3 Namespace Variante des relativen statischen Aufrufs einer Methode
$operatoren['sin'] = array('rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS,
                          
'funktion'=>array('NamensRaum::Klasse','parent::sin'));
?>

Über Callbacks steht im PHP Handbuch einiges.

Hier ein paar Beispiel Funktionen

Die Operatoren im Beispielcode

<?php


// Operatoren
$rang 0// hoher Rang -->> niedrige priorität
$operatoren      = array();
$operatoren['e'] = array('rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS_UND_LINKS,
                          
'funktion'=>'f_e10');
$rang++;
$operatoren['sin'] = array('rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS,
                          
'funktion'=>'sin');
$operatoren['degrad'] = array('rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS,
                          
'funktion'=>'deg2rad');
$operatoren['raddeg'] = array('rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS,
                          
'funktion'=>'rad2deg');
$operatoren['cos'] = array('rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS,
                          
'funktion'=>'cos');
$operatoren['abs'] = array('rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS,
                          
'funktion'=>'abs');
$operatoren['!'] = array( 'rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_LINKS,
                          
'funktion'=>'fakultaet');
$operatoren['^'] = array( 'rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS_UND_LINKS,
                          
'funktion'=>'pow');
$operatoren['²'] = array( 'rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_LINKS,
                          
'funktion'=>'f_pow2');
$operatoren['³'] = array( 'rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_LINKS,
                          
'funktion'=>'f_pow3');
$rang++;
$operatoren['/'] = array( 'rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS_UND_LINKS,
                          
'funktion'=>'f_div');
$operatoren['*'] = array( 'rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS_UND_LINKS,
                          
'funktion'=>'f_mul');
$operatoren['%'] = array( 'rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS_UND_LINKS,
                          
'funktion'=>'f_mod');
$rang++;
$operatoren['+'] = array( 'rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS_UND_LINKS,
                          
'funktion'=>'f_add');
$operatoren['-'] = array( 'rang'=>$rang,
                          
'bindung'=>Combie_FormelParser_Operator::BINDUNG_RECHTS_UND_LINKS,
                          
'funktion'=>'f_sub');