PHP  »  Articoli  »  Programmazione Php 

Espressioni matematiche in PHP: la pratica

di: Gabriele Farina     31 Luglio 2008

Dopo aver introdotto brevemente la teoria che sta dietro all'analisi e all'esecuzione di espressioni in modo dinamico, possiamo passare alla parte pratica. Ho implementato un semplicissimo valutatore di espressioni, in grado di gestire le seguenti operazioni:

  • addizione
  • sottrazione
  • moltiplicazione
  • divisione
  • raggruppamento di espressioni tramite parentesi
  • chiamata di funzioni
  • supporto per le variabili
  • numeri negativi

Il sistema implementato è volutamente semplice in modo da suddividere nel modo più chiaro possibile i concetti discussi nell'articolo precedente (Scanner, Parser, AST). I sorgenti possono essere scaricati da qui.

Nel file zip allegato a questo articolo è contenuto in file di esempio. Questo esegue una semplice espressione stampandone il risultato e la notazione postfissa. Il codice dell'esempio è il seguente:

<?php 
require_once "it/html/expr/Scanner.php";
require_once "it/html/expr/Parser.php";
require_once "it/html/expr/error/ ExpressionError.php"; 
$expression = "sin( x / ( 4 / 2 * 2 - 2 + 2 * x / x ) ) * 100";
$scanner = new Scanner( $expression );
$parser = new Parser( $scanner ); 
$compiled = $parser->parse(); 
$context = array(
      "x"  => 100,
      "sin" =>  "sin",
      "cos" => "cos"
); 
echo 'Postfix:', $compiled;
echo 'Result:', $compiled->execute( $context ); 
?>

Come possiamo notare, tralasciando le inclusioni, il sistema risulta di semplice utilizzo; il parser accetta come parametro uno scanner, che si occupa di suddividere l'espressione in token riconoscibili dal sistema, ed il metodo parse restituisce un oggetto (CompiledExpression) che espone un metodo execute che valuta l'espressione. Il metodo execute accetta come parametro un array che definisce il contesto di esecuzione. Come potete notare difatti l'espressione che vogliamo valutare contiene la variabile x ed una chiamata alla funzione sin. I valori di questi due identificatori non sono conosciuti dal sistema, e quindi devono essere specificati manualmente. Cambiando il valore di x per esempio otterremo risultati differenti. sin e cos sono invece funzioni, mappate alle corrispettive funzioni PHP. Internamente il sistema utilizza call_user_func_array per chiamare la funzione corrispondente.

La struttura del file zip include tutto il codice necessario all'interno della directory it/html/expr e sottocartelle:

  • Ident: classe utilizzata per registrare un identificatore e mappare la variabile ad un valore specificato dal contesto del metodo execute discusso sopra;
  • Parser: Il parser di espressioni che legge i Token generati dallo scanner alla ricerca di sequenze valide trasformabili in nodi x l'albero sintattico (AST);
  • Scanner: lo scanner che si occupa di assegnare ad ogni carattere o sequenza di caratteri un Token, che rappresenta l'unità minima di input comprensibile dal Parser;
  • SymbolTable: una tabella utilizzata per salvare i simboli incontrati durante il parsing, per far si che poi siano agilmente recuperabili durante la valutazione dell'espressione;
  • Token: il Token è l'unità minima di input compresa dal parser; i Token possono essere composti da uno o più caratteri, e sono generati dallo Scanner;
  • TokenType: classe di utilità usata per definire le costanti che differenziano i vari tipi di Token;
  • CompiledExpression: classe utilizzata per rappresentare un'espressione compilata in AST. L'albero dei nodi AST è salvato all'interno, ed è valutato quando si chiama il metodo execute;
  • error/ExpressionError: eccezione lanciata quando il parser incontra un errore;
  • ast/*: ogni classe contenuta in questa directory rappresenta un nodo dell'AST. Ogni nodo implementa l'interfaccia IExpression, in modo che ogni nodo abbia la sua rappresentazione sotto forma di stringa e sia in grado di eseguirsi;

Analizziamo ora le classi principali, cercando di chiarire i concetti implementativi nel modo migliore possibile. Per brevità non includerò tutto il codice ma solo le parti interessanti, mettendo tre puntini nel caso di codice omesso.

Guide PHP

Guida Yii Framework

Come creare applicazioni Web in modo semplice e veloce con il...

Guida Zend Framework

Diventate professionisti dello sviluppo Web. Zend Framework è lo...

Guida Applicazioni Facebook con PHP

Come realizzare un'applicazione per Facebook. Dalle basi della...

Altre guide

Newsletter @PHP

Ogni lunedì, direttamente nella tua e-mail: script, articoli, guide e tutorial su PHP, MySQL e Apache.

Iscriviti alla newsletter

Altre newsletter

Corsi in aula

Corso PHP per Webmaster

11 Giugno 2012 a Milano
Disponibilità: 7 Posti

Corso Google AdWords Base

25 Giugno 2012 a Milano
Disponibilità: 7 Posti

Corso Google AdWords Base

05 Giugno 2012 a Roma
Disponibilità: 7 Posti