Espressioni matematiche in PHP: la teoria

12 giugno 2008

A molti di voi probabilmente verrà da chiedersi quale sia la necessità di scrivere codice PHP che, data un’espressione matematica, sia in grado di valutarne il risultato in un determinato contesto. Abbiamo già la funzione eval che può fare al caso nostro per esempio, ed è molto probabilmente più potente di gran parte del codice che potremmo scrivere per raggiungere l’obiettivo posto.

Ma, per quanto utile possa essere la funzione sopra citata, quello di cui mi appresto a scrivere in questa breve serie di articoli riguarda un po’ di teoria che sta dietro alla scrittura di strumenti capaci di analizzare e valutare espressioni. L’obiettivo è quello di ottenere una libreria su cui si abbia un controllo assoluto che il codice eseguito non sia dannoso per il sistema. Purtroppo eval, a meno che non si provveda alla pulizia dell’input con minuziosità, rischia di essere abusata dai malintenzionati nel caso in cui ci sia una piccola falla e si possa immettere del codice potenzialmente dannoso.

In questo articolo vedremo come gettare le basi per gli strumenti che servono per trasformare un’espressione in una struttura dati facilmente analizzabile e come valutare il risultato di un’espressione partendo da questa struttura dati e da un contesto fornito (come ad esempio variabili o funzioni native).

Breve introduzione sull’esecuzione di espressioni

Iniziamo con un po’ di teoria prima di passare alla pratica. Valutare espressioni è un’operazione tendenzialmente molto semplice, che però – se affrontata come ci apprestiamo a fare in questo articolo – tocca diversi interessanti punti che vengono poi ripresi quando si parla di scrittura di compilatori, linguaggi di programmazione, interpreti e correlati. La valutazione di un’espressione avviene attraverso tre passaggi principali: l’analisi lessicale, il parsing ed infine l’esecuzione.

Analisi lessicale

L’analisi lessicale è un processo che permette di trasformare una stringa in input potenzialmente generica in una serie di simboli con un significato specifico. L’analisi lessicale avviene tramite uno scanner (o Lexer o Tokenizer) che si occupa di riconoscere all’intero della stringa gruppi di caratteri che – indipendentemente dalla loro posizione – possono avere un significato nell’espressione.

Prendiamo per esempio la libreria che andremo a scrivere: accetta espressioni composte da numeri interi o float, operazioni aritmetiche base, chiamate a funzioni, variabili e raggruppamento tra parentesi. Lo scanner nel nostro caso deve trasformare l’espressione in input in una lista di gruppi di carattere che saranno identificati espressamente come numero, operatore, parentesi o identificatore. Su questi gruppi di caratteri, chiamati Token, si andrà poi a basare la successiva fase di parsing.

Per chiarire meglio, nel caso dessimo al nostro Scanner questa espressione in input:

+ - sin    ( a + 10 ( *   ) sqrt( 16.4

otterremo una lista di Token rappresentabile graficamente in questo modo (il primo valore nella parentesi rappresenta il tipo di token):

(operator, + )
(operator, - )
(identifier, sin )
(left-parenthesis)
(identifier, + )
(operator, + )
(number, 10 )
(operator, + )
(left-parenthesis)
(operator, * )
(right-parenthesis)
(identifier, sqrt )
(number, 16.4 )

Lo scanner scarta gli spazi, che non hanno significato in un’espressione, e restituisce una lista di Token che riesce a riconoscere. Notate come lo scanner ignori completamente se la stringa in input ha una struttura valida o meno. Questo è compito della fase successiva.

Se vuoi aggiornamenti su Espressioni matematiche in PHP: la teoria inserisci la tua e-mail nel box qui sotto:
 
X
Se vuoi aggiornamenti su Espressioni matematiche in PHP: la teoria

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy