UN compilatore è un programma che si traduce in lettura umana codice sorgente nel codice macchina eseguibile dal computer. Per farlo correttamente, il codice leggibile dall'uomo deve essere conforme a sintassi regole di qualunque linguaggio di programmazione sia scritto. Il compilatore è solo un programma e non può correggere il codice per te. Se si commette un errore, è necessario correggere la sintassi o non verrà compilata.
Cosa succede quando compili il codice?
La complessità di un compilatore dipende dalla sintassi del linguaggio e dalla quantità di astrazione quel linguaggio di programmazione fornisce. Un compilatore C è molto più semplice di un compilatore per C ++ o C #.
Analisi lessicale
Durante la compilazione, il compilatore legge prima un flusso di caratteri da un file di codice sorgente e genera un flusso di token lessicali. Ad esempio, il codice C ++:
int C = (A * B) +10;
potrebbe essere analizzato come questi token:
- digitare "int"
- variabile "C"
- è uguale a
- leftbracket
- variabile "A"
- volte
- variabile "B"
- RIGHTBRACKET
- più
- letterale "10"
Analisi sintattica
L'output lessicale va alla parte dell'analizzatore sintattico del compilatore, che utilizza le regole grammaticali per decidere se l'input è valido o meno. Salvo che variabili A e B erano stati precedentemente dichiarati ed erano nell'ambito, il compilatore poteva dire:
- 'A': identificatore non dichiarato.
Se sono stati dichiarati ma non inizializzati. il compilatore emette un avviso:
- variabile locale 'A' utilizzata senza essere inizializzata.
Non si dovrebbero mai ignorare gli avvisi del compilatore. Possono rompere il tuo codice in modi strani e inaspettati. Correggi sempre gli avvisi del compilatore.
Un passaggio o due?
Alcuni linguaggi di programmazione sono scritti in modo che un compilatore possa leggere il codice sorgente una sola volta e generare il codice macchina. Pascal è una di queste lingue. Molti compilatori richiedono almeno due passaggi. A volte, è a causa delle dichiarazioni anticipate di funzioni o classi.
In C ++, una classe può essere dichiarata ma non definita fino a dopo. Il compilatore non è in grado di calcolare la quantità di memoria necessaria alla classe fino a quando non compila il corpo della classe. Deve rileggere il codice sorgente prima di generare il codice macchina corretto.
Generazione del codice macchina
Supponendo che il compilatore completi correttamente le analisi lessicali e sintattiche, lo stadio finale sta generando il codice macchina. Questo è un processo complicato, specialmente con le CPU moderne.
La velocità del compilato eseguibile il codice dovrebbe essere il più veloce possibile e può variare enormemente in base alla qualità del codice generato e alla quantità di ottimizzazione richiesta.
La maggior parte dei compilatori consente di specificare la quantità di ottimizzazione, generalmente nota per compilazioni di debug rapide e ottimizzazione completa per il codice rilasciato.
La generazione di codice è impegnativa
Lo scrittore del compilatore deve affrontare sfide quando si scrive un generatore di codice. Molti processori accelerano l'elaborazione utilizzando
- Pipeline di istruzioni
- Interno cache.
Se tutte le istruzioni all'interno di un codice ciclo continuo può essere tenuto nel processore cache, quindi quel ciclo viene eseguito molto più velocemente rispetto a quando la CPU deve recuperare le istruzioni dalla RAM principale. La cache della CPU è un blocco di memoria integrato nel chip della CPU a cui si accede molto più velocemente dei dati nella RAM principale.
Cache e code
La maggior parte delle CPU ha una coda di prelievo in cui la CPU legge le istruzioni nella cache prima di eseguirle. Se si verifica un ramo condizionale, la CPU deve ricaricare la coda. Il codice dovrebbe essere generato per minimizzare questo.
Molte CPU hanno parti separate per:
- Aritmetica intera (numeri interi)
- Aritmetica in virgola mobile (numeri frazionari)
Queste operazioni possono spesso essere eseguite in parallelo per aumentare la velocità.
I compilatori in genere generano codice macchina in file oggetto che lo sono connesso insieme da un programma linker.