Progettazione del compilatore - Fasi del compilatore
Il processo di compilazione è una sequenza di varie fasi. Ogni fase prende l'input dalla sua fase precedente, ha la propria rappresentazione del programma sorgente e alimenta il proprio output alla fase successiva del compilatore. Cerchiamo di capire le fasi di un compilatore.
Analisi lessicale
La prima fase dello scanner funziona come uno scanner di testo. Questa fase analizza il codice sorgente come un flusso di caratteri e lo converte in lessemi significativi. L'analizzatore lessicale rappresenta questi lessemi sotto forma di token come:
<token-name, attribute-value>
Analisi della sintassi
La fase successiva è chiamata analisi della sintassi o parsing. Prende come input il token prodotto dall'analisi lessicale e genera un albero di analisi (o albero di sintassi). In questa fase, la disposizione dei token viene verificata rispetto alla grammatica del codice sorgente, cioè il parser controlla se l'espressione fatta dai token è sintatticamente corretta.
Analisi semantica
L'analisi semantica controlla se l'albero di analisi costruito segue le regole del linguaggio. Ad esempio, l'assegnazione dei valori avviene tra tipi di dati compatibili e l'aggiunta di una stringa a un numero intero. Inoltre, l'analizzatore semantico tiene traccia degli identificatori, dei loro tipi ed espressioni; se gli identificatori vengono dichiarati prima dell'uso o meno, ecc. L'analizzatore semantico produce un albero della sintassi annotato come output.
Generazione di codice intermedio
Dopo l'analisi semantica il compilatore genera un codice intermedio del codice sorgente per la macchina di destinazione. Rappresenta un programma per qualche macchina astratta. Si trova tra il linguaggio di alto livello e il linguaggio macchina. Questo codice intermedio dovrebbe essere generato in modo tale da renderlo più facile da tradurre nel codice macchina di destinazione.
Ottimizzazione del codice
La fase successiva esegue l'ottimizzazione del codice del codice intermedio. L'ottimizzazione può essere considerata come qualcosa che rimuove le righe di codice non necessarie e organizza la sequenza di istruzioni in modo da velocizzare l'esecuzione del programma senza sprecare risorse (CPU, memoria).
Generazione di codice
In questa fase, il generatore di codice prende la rappresentazione ottimizzata del codice intermedio e la mappa sul linguaggio macchina di destinazione. Il generatore di codice traduce il codice intermedio in una sequenza di codice macchina (generalmente) ricollocabile. La sequenza di istruzioni del codice macchina esegue l'attività come farebbe il codice intermedio.
Tabella dei simboli
È una struttura dati mantenuta durante tutte le fasi di un compilatore. Tutti i nomi dell'identificatore insieme ai loro tipi vengono memorizzati qui. La tabella dei simboli rende più facile per il compilatore cercare rapidamente il record dell'identificatore e recuperarlo. La tabella dei simboli viene utilizzata anche per la gestione dell'ambito.