Indietro

ⓘ Compilatore




Compilatore
                                     

ⓘ Compilatore

Un compilatore è un programma informatico che traduce una serie di istruzioni scritte in un determinato linguaggio di programmazione in istruzioni di un altro linguaggio. Il processo di traduzione si chiama compilazione mentre lattività inversa - ovvero passare dal codice oggetto al codice sorgente - è chiamata decompilazione ed è effettuata per mezzo di un decompilatore.

Se tutti i compilatori aderissero esattamente alla specifica del linguaggio, lo stesso programma potrebbe essere compilato senza modifiche da ciascun compilatore, producendo risultati semanticamente uguali, ovvero programmi che producono lo stesso risultato se sottoposti agli stessi dati di ingresso. Nella realtà, molti compilatori implementano il linguaggio in modo incompleto o aggiungono estensioni proprietarie, creando quindi dei dialetti del linguaggio principale. Per i linguaggi che adottano uno standard nella decorazione dei simboli, il codice oggetto generato da compilatori differenti può essere collegato assieme in un unico eseguibile.

                                     

1. Storia

A partire dal 1950 vennero sviluppati diversi compilatori sperimentali vedi ad esempio, i primi lavori di Grace Hopper sul linguaggio A-0, ma nel 1957 il team Fortran presso lIBM, guidato da John Backus, fu il primo a realizzare un compilatore completo mentre, nel 1960, il COBOL fu uno dei primi linguaggi a essere compilato su più architetture.

Lidea della compilazione prese velocemente piede e molti dei principi di design dei compilatori vennero sviluppati negli anni sessanta. Un compilatore è esso stesso un programma scritto in un qualche linguaggio e, i primi di essi vennero scritti in Assembly. Il primo compilatore auto-compilato, capace cioè di compilare il suo stesso codice, fu creato per il linguaggio Lisp da Hart e Levin presso il MIT nel 1962. Luso di linguaggi ad alto livello per scrivere i compilatori ebbe una accelerazione nei primi anni settanta quando i linguaggi Pascal e C furono usati per scrivere compilatori per loro stessi: ossia, a esempio, furono scritti compilatori per il C scritti a loro volta in C.

                                     

2. Descrizione

Quando un linguaggio di programmazione viene definito per la prima volta, sorge il problema di come realizzare il relativo compilatore. In questo caso esistono due approcci possibili:

  • oppure - se esiste già un interprete per il nuovo linguaggio - è possibile sfruttarlo per scrivere una prima versione del compilatore, che verrà usata dandogli in input il codice sorgente di sé stesso per ottenere un primo compilatore funzionante in linguaggio macchina, che quindi renderà inutile luso dellinterprete. Il compilatore così ottenuto potrà essere usato per scrivere a sua volta compilatori migliori, e così via.
  • scrivere il compilatore in un linguaggio diverso;
                                     

2.1. Descrizione Funzionamento

Il compilatore prende in ingresso un programma, il codice sorgente, su cui esegue una serie di operazioni in modo da ottenere, in assenza di errori, il codice oggetto. In generale i compilatori sono in grado di riconoscere alcune classi di errori presenti nel programma, e in alcuni casi di suggerire in che modo correggerli.

I compilatori attuali dividono loperazione di compilazione in due stadi principali il front end e il back end. Nello stadio di front end il compilatore traduce il sorgente in un linguaggio intermedio di solito interno al compilatore; nello stadio di back end avviene la generazione del codice oggetto.

                                     

2.2. Descrizione Stadio di front end

Questo stadio si suddivide in più fasi:

  • Analisi lessicale Attraverso un analizzatore lessicale, spesso chiamato scanner o lexer, il compilatore divide il codice sorgente in tanti pezzetti chiamati token. I token sono gli elementi minimi non ulteriormente divisibili di un linguaggio, ad esempio parole chiave for, while, nomi di variabili pippo, operatori +, -, ".
  • Analisi sintattica Lanalisi sintattica prende in ingresso la sequenza di token generata nella fase precedente ed esegue il controllo sintattico. Il controllo sintattico è effettuato attraverso una grammatica. Il risultato di questa fase è un albero di sintassi.
  • Generazione del codice intermedio: Dallalbero di sintassi viene generato il codice intermedio.
  • Analisi semantica Lanalisi semantica si occupa di controllare il significato delle istruzioni presenti nel codice in ingresso. Controlli tipici di questa fase sono il type checking, ovvero il controllo di tipo, controllare che gli identificatori siano stati dichiarati prima di essere usati e così via. Come supporto a questa fase viene creata una tabella dei simboli symbol table che contiene informazioni su tutti gli elementi simbolici incontrati quali nome, scope, tipo se presente etc. Il risultato di questa fase è lalbero sintattico astratto AST.


                                     

2.3. Descrizione Stadio di back end

Anche lo stadio di back end si divide in più fasi:

  • Ottimizzazione del codice intermedio.
  • Generazione del codice target: in questa fase viene generato il codice nella forma del linguaggio target. Spesso il linguaggio target è un linguaggio macchina.