Fasi del compilatore con esempio

Sommario:

Anonim

Quali sono le fasi della progettazione del compilatore?

Il compilatore opera in varie fasi ogni fase trasforma il programma sorgente da una rappresentazione all'altra. Ogni fase prende input dalla sua fase precedente e alimenta il suo output alla fase successiva del compilatore.

Ci sono 6 fasi in un compilatore. Ciascuna di questa fase aiuta a convertire la lingua di alto livello in codice macchina. Le fasi di un compilatore sono:

  1. Analisi lessicale
  2. Analisi della sintassi
  3. Analisi semantica
  4. Generatore di codice intermedio
  5. Ottimizzatore del codice
  6. Generatore di codici
Fasi del compilatore

Tutte queste fasi convertono il codice sorgente dividendolo in token, creando alberi di analisi e ottimizzando il codice sorgente in diverse fasi.

In questo tutorial imparerai:

  • Quali sono le fasi della progettazione del compilatore?
  • Fase 1: analisi lessicale
  • Fase 2: analisi della sintassi
  • Fase 3: analisi semantica
  • Fase 4: generazione di codice intermedio
  • Fase 5: ottimizzazione del codice
  • Fase 6: generazione del codice
  • Gestione della tabella dei simboli
  • Routine di gestione degli errori:

Fase 1: analisi lessicale

L'analisi lessicale è la prima fase in cui il compilatore esegue la scansione del codice sorgente. Questo processo può essere lasciato a destra, carattere per carattere, e raggruppare questi personaggi in gettoni.

Qui, il flusso di caratteri dal programma sorgente è raggruppato in sequenze significative identificando i gettoni. Effettua l'entrata dei biglietti corrispondenti nella tabella dei simboli e passa quel gettone alla fase successiva.

Le funzioni principali di questa fase sono:

  • Identifica le unità lessicali in un codice sorgente
  • Classificare le unità lessicali in classi come costanti, parole riservate e inserirle in tabelle diverse. Ignorerà i commenti nel programma sorgente
  • Identifica il token che non fa parte della lingua

Esempio :

x = y + 10

Gettoni

X identificatore
= Operatore di assegnazione
Y identificatore
+ Operatore di addizione
10 Numero

Fase 2: analisi della sintassi

L'analisi della sintassi riguarda la scoperta della struttura nel codice. Determina se un testo segue o meno il formato previsto. Lo scopo principale di questa fase è assicurarsi che il codice sorgente scritto dal programmatore sia corretto o meno.

L'analisi della sintassi si basa sulle regole basate sul linguaggio di programmazione specifico costruendo l'albero di analisi con l'ausilio di token. Determina anche la struttura della lingua di origine e la grammatica o la sintassi della lingua.

Ecco un elenco delle attività eseguite in questa fase:

  • Ottieni gettoni dall'analizzatore lessicale
  • Controlla se l'espressione è sintatticamente corretta o meno
  • Segnala tutti gli errori di sintassi
  • Costruisci una struttura gerarchica nota come albero di analisi

Esempio

Qualsiasi identificatore / numero è un'espressione

Se x è un identificatore e y + 10 è un'espressione, allora x = y + 10 è un'istruzione.

Considera l'albero di analisi per il seguente esempio

(a+b)*c

In Parse Tree

  • Nodo interno: record con un operatore archiviato e due file per bambini
  • Foglia: record con 2 / più campi; uno per il token e altre informazioni sul token
  • Assicurati che i componenti del programma combacino in modo significativo
  • Raccoglie informazioni sul tipo e verifica la compatibilità del tipo
  • Gli operandi di controllo sono consentiti dalla lingua di origine

Fase 3: analisi semantica

L'analisi semantica verifica la coerenza semantica del codice. Utilizza l'albero della sintassi della fase precedente insieme alla tabella dei simboli per verificare che il codice sorgente specificato sia semanticamente coerente. Controlla anche se il codice trasmette un significato appropriato.

Semantic Analyzer verificherà eventuali mancate corrispondenze di tipo, operandi incompatibili, una funzione chiamata con argomenti impropri, una variabile non dichiarata, ecc.

Le funzioni della fase di analisi semantica sono:

  • Aiuta a memorizzare le informazioni sul tipo raccolte e salvarle nella tabella dei simboli o nella struttura della sintassi
  • Consente di eseguire il controllo del tipo
  • In caso di mancata corrispondenza del tipo, dove non ci sono regole di correzione del tipo esatte che soddisfano l'operazione desiderata viene mostrato un errore semantico
  • Raccoglie informazioni sul tipo e verifica la compatibilità del tipo
  • Controlla se la lingua di origine consente o meno gli operandi

Esempio

float x = 20.2;float y = x*30;

Nel codice sopra, l'analizzatore semantico tipizzerà l'intero 30 in float 30.0 prima della moltiplicazione

Fase 4: generazione di codice intermedio

Terminata la fase di analisi semantica, il compilatore genera il codice intermedio per la macchina di destinazione. Rappresenta un programma per qualche macchina astratta.

Il codice intermedio è tra il linguaggio di alto livello e il linguaggio a livello di macchina. Questo codice intermedio deve essere generato in modo tale da facilitarne la traduzione nel codice macchina di destinazione.

Funzioni sulla generazione del codice intermedio:

  • Dovrebbe essere generato dalla rappresentazione semantica del programma sorgente
  • Contiene i valori calcolati durante il processo di traduzione
  • Ti aiuta a tradurre il codice intermedio nella lingua di destinazione
  • Consente di mantenere l'ordine di precedenza della lingua di origine
  • Contiene il numero corretto di operandi dell'istruzione

Esempio

Per esempio,

total = count + rate * 5

Il codice intermedio con l'aiuto del metodo del codice indirizzo è:

t1 := int_to_float(5)t2 := rate * t1t3 := count + t2total := t3

Fase 5: ottimizzazione del codice

La fase successiva è l'ottimizzazione del codice o il codice intermedio. Questa fase rimuove la riga di codice non necessaria e organizza la sequenza di istruzioni per velocizzare l'esecuzione del programma senza sprecare risorse. L'obiettivo principale di questa fase è migliorare il codice intermedio per generare un codice che gira più velocemente e occupa meno spazio.

Le funzioni principali di questa fase sono:

  • Ti aiuta a stabilire un compromesso tra l'esecuzione e la velocità di compilazione
  • Migliora il tempo di esecuzione del programma di destinazione
  • Genera codice semplificato ancora nella rappresentazione intermedia
  • Rimozione di codice irraggiungibile ed eliminazione delle variabili inutilizzate
  • Rimozione di istruzioni che non vengono alterate dal ciclo

Esempio:

Considera il codice seguente

a = intofloat(10)b = c * ad = e + bf = d

Può diventare

b =c * 10.0f = e+b

Fase 6: generazione del codice

La generazione del codice è l'ultima e ultima fase di un compilatore. Ottiene input dalle fasi di ottimizzazione del codice e come risultato produce il codice della pagina o il codice oggetto. L'obiettivo di questa fase è allocare memoria e generare codice macchina rilocabile.

Alloca anche le posizioni di memoria per la variabile. Le istruzioni nel codice intermedio vengono convertite in istruzioni macchina. Questa fase converte il codice ottimizzato o intermedio nella lingua di destinazione.

La lingua di destinazione è il codice macchina. Pertanto, anche tutte le posizioni di memoria e i registri vengono selezionati e assegnati durante questa fase. Il codice generato da questa fase viene eseguito per prendere input e generare output attesi.

Esempio:

a = b + 60,0

Potrebbe essere eventualmente tradotto in registri.

MOVF a, R1MULF #60.0, R2ADDF R1, R2

Gestione della tabella dei simboli

Una tabella dei simboli contiene un record per ogni identificatore con campi per gli attributi dell'identificatore. Questo componente semplifica la ricerca nel record dell'identificatore e il recupero rapido da parte del compilatore. La tabella dei simboli aiuta anche nella gestione dell'ambito. La tabella dei simboli e il gestore degli errori interagiscono di conseguenza con tutte le fasi e l'aggiornamento della tabella dei simboli.

Routine di gestione degli errori:

Nel processo di progettazione del compilatore può verificarsi un errore in tutte le fasi indicate di seguito:

  • Analizzatore lessicale: gettoni scritti in modo errato
  • Analizzatore di sintassi: parentesi mancante
  • Generatore di codice intermedio: operandi non corrispondenti per un operatore
  • Ottimizzatore del codice: quando l'istruzione non è raggiungibile
  • Generatore di codice: dichiarazioni irraggiungibili
  • Tabelle dei simboli: errore di più identificatori dichiarati

Gli errori più comuni sono la sequenza di caratteri non valida nella scansione, le sequenze di token non valide nel tipo, l'errore di ambito e l'analisi nell'analisi semantica.

L'errore può essere riscontrato in una delle fasi precedenti. Dopo aver trovato gli errori, la fase deve affrontare gli errori per continuare con il processo di compilazione. Questi errori devono essere segnalati al gestore degli errori che gestisce l'errore per eseguire il processo di compilazione. Generalmente, gli errori vengono riportati sotto forma di messaggio.

Sommario

  • Il compilatore opera in varie fasi ogni fase trasforma il programma sorgente da una rappresentazione all'altra
  • Sei fasi della progettazione del compilatore sono 1) Analisi lessicale 2) Analisi della sintassi 3) Analisi semantica 4) Generatore di codice intermedio 5) Ottimizzatore di codice 6) Generatore di codice
  • L'analisi lessicale è la prima fase in cui il compilatore esegue la scansione del codice sorgente
  • L'analisi della sintassi riguarda la scoperta della struttura nel testo
  • L'analisi semantica verifica la coerenza semantica del codice
  • Una volta terminata la fase di analisi semantica, il compilatore genera il codice intermedio per la macchina di destinazione
  • La fase di ottimizzazione del codice rimuove la riga di codice non necessaria e organizza la sequenza di istruzioni
  • La fase di generazione del codice riceve input dalla fase di ottimizzazione del codice e produce di conseguenza il codice della pagina o il codice oggetto
  • Una tabella dei simboli contiene un record per ogni identificatore con campi per gli attributi dell'identificatore
  • La routine di gestione degli errori gestisce errori e rapporti durante molte fasi