Nel presente articolo cercheremo di approfondire che cosa sono gli analizzatori lessicali e quali attività essi svolgono. Vedremo di cosa è costituito un ipotetico output di dati diretto ad un parser e proveremo a realizzare un semplice analizzatore lessicale mediante il generatore di codice Flex.
Prerequisiti
Si presume che il lettore abbia dimistichezza con il generatore di parser Bison, che conosca approfonditamente la programmazione in linguaggio C ed abbia una conoscenza generale circa la struttura dei compilatori.
Iniziamo con un esempio
Gli analizzatori lessicali svolgono compiti che possiamo così sintetizzare:
- suddividere un testo in token (frammenti di testo);
- codificare i token ed inviarli al parser;
- analizzare il testo secondo delle metodologie specifiche.
Dei punti elencati i primi sono di facile comprensione e nel prosieguo dell’articolo ne daremo evidenza. L’ultimo punto invece richiede un approfondimento. L'analizzatore lessicale è sempre il primo stadio di un compilatore, proviamo ad immaginarne il flusso: il testo viene analizzato carattere per carattere, ogni volta che viene trovata una sequenza valida (presente nella lista dei token validi) questi continua ad analizzare fino a quando non viene trovata una parola chiave(o sequenza valida) e concludere "token trovato". In tale condizione, sembrerebbe logico, si può immaginare che l'analizzatore possa trasmettere il token al parser e passare ad analizzare i caratteri successivi. Non si può affermare a priori che questo sia il comportamento corretto. Dipende dai criteri di analisi stabilti. Nell'esempio che segue vedremo come in certi casi l'analizzatore non può terminare l'attività nelle condizioni proposte ma debba proseguire nella ricerca. Si consideri il seguente codice scritto in linguaggio C(my_test.c):
1 int main ( void )
2 {
3 int i=10,h=0;
4 i = i+++h;
5 printf( "il calcolo vale %d\n", i);
6 return 0 ;
7 }
Osserviamo fin da subito che tale codice non è compilabile a meno di non inserire prima della funzione main() l’include del file stdio.h. Dimentichiamoci per un attimo di questo dettaglio che esula dal contesto(non è nei nostri interessi compilare il file my_test.c). Osserviamo la riga 3. Tale dichiarazione, per quanto insolita, è corretta(nello standard C99). Abbiamo un operatore somma ‘+’ ed uno di incremento ‘++’ in sequenza, ma in quale ordine vanno interpretati tali operatori? Abbiamo due possibilità:
- i= (i++) + h;
- i = i + (++h);





