|
In Java è naturalmente possibile realizzare a mano dei parser. La loro
codifica diretta tuttavia è molto noiosa, complessa, ripetitiva e soggetta
a numerosi errori. Fortunatamente si possono usare formalismi potenti per
descrivere in maniera semplice ed intuitiva i linguaggi formali: i più usati
sono le grammatiche. Utilizzando una grammatica, si può derivare da essa in
maniera automatica il codice del parser utilizzando dei generatori di codice.
Questi generatori vengono talvolta chiamati, in maniera un po' esagerata,
compiler-compiler (compilatori di compilatori). Con essi si riduce notevolmente
il lavoro poiché il codice viene generato automaticamente a partire da una
grammatica estesa con opportuno codice di supporto; in gergo si dice che la
grammatica viene annotata. Vedremo quindi come utilizzare in pratica un
compiler-compiler con un esempio pratico: descrivereremo la realizzazione
di un semplice valutatore di espressione. Partendo dal codice fornito insieme
all'articolo avrete una ottima base per avventurarvi nello sviluppo del vostro
linguaggio di programmazione.
Il primo passo per programmare un parser è quindi la scelta del generatore
di codice. In rete sono disponibili due generatori di parser in Java: il JavaCC
e il JavaCup, entrambi utilizzabili gratuitamente anche se con licenze diverse.
Il JavaCC è molto potente, e anche molto usato, ma sebbene l'uso sia gratuito,
non ne viene rilasciato il codice sorgente. Non ritengo un gran problema
il fatto che il JavaCC non sia OpenSource se non avessi rilevato nell'uso
dei messaggi di errore interno, messaggi che mi hanno insospettito non poco.
A quanto sembra il JavaCC non è stato aggiornato da tempo e genera errori
usando per esempio un interpreta Java 1.1.
Per questo motivo non mi sono sentito di utilizzarlo. Di un prodotto commerciale
posso eventualmente richiedere l'assistenza (in un progetto industriale),
ma di un prodotto gratuito (quindi non commerciale) se il sorgente non è
disponibile, c'è il pericolo che venga (nella peggiore delle ipotesi) abbandonato.
Un altro motivo per cui non ho apprezzato il JavaCC è che è abbastanza diverso
da Yacc, di conseguenza si deve imparare una metodologia un po' differente
da quella a cui un esperto di Yacc è abituato. In realtà niente di grave,
solo una sensazione di maggior complessità che andava contro i principi di
massima semplicità che prediligo. Poiché esiste il JavaCup, una implementazione
di un sistema molto simile a Yacc, per di più distribuito gratuitamente con
licenza GPL, compreso il sorgente, ho optato per quest'ultimo. Sia l'esempio
che il JavaCup stesso con il sorgente sono acclusi all'articolo. Devo dire
che mi ha meno problemi e lo ho trovato più semplice e immediatamente comprensibile
del JavaCC, anche perché ho una certa esperienza con Yacc.
Con questo non sto condannando il JavaCC, anche perché è usato dalla maggioranza
dei progetti di linguaggi in Java che conosco, osservo solo che si può usare
proficuamente anche il JavaCup, che è valido e abbastanza facile da usare.
Per questo articolo (e per i miei usi lavorativi) ho solo scelto uno strumento
piuttosto che un altro.
|