Fazele compilatorului cu exemplu, proces și pași

⚡ Rezumat inteligent

Fazele compilatorului descriu modul în care un compilator transformă codul sursă în cod mașină prin șase etape: analiza lexicală, analiza sintactică, analiza semantică, generarea de cod intermediar, optimizarea codului și generarea de cod, susținute de gestionarea tabelului de simboluri și tratarea erorilor pe tot parcursul procesului.

  • 🔤 Analiza lexicala: Prima fază scanează codul sursă și grupează caracterele în token-uri, completând tabela de simboluri.
  • 🌳 Analiza sintaxei: Jetoanele sunt verificate în funcție de regulile gramaticale și aranjate într-un arbore de analiză.
  • ✅ Analiza semantică: Compilatorul verifică compatibilitatea tipurilor și semnificația folosind arborele sintactic și tabelul de simboluri.
  • 🔁 Intermediar Code: O reprezentare independentă de mașină, cum ar fi un cod cu trei adrese, este generată pentru o traducere ușoară.
  • ⚡ Optimizare: Codul redundant și inaccesibil este eliminat pentru a face programul mai rapid și mai mic.
  • 🖥️ Code Generaţie: Faza finală convertește codul optimizat în cod mașină țintă, alocând registre și memorie.

Care sunt fazele de proiectare a compilatorului?

compilator operează în diverse faze fiecare fază transformă programul sursă de la o reprezentare la alta. Fiecare fază preia intrări din etapa anterioară și își alimentează ieșirea în faza următoare a compilatorului.
Există 6 faze într-un compilator. Fiecare din această fază ajută la conversia limbajului de nivel înalt în codul mașinii. Fazele unui compilator sunt:

  1. Analiza lexicală
  2. Analiza sintaxei
  3. Analiza semantică
  4. Generator de cod intermediar
  5. Code Instrumentul de optimizare a
  6. Code generator
Fazele compilatorului
Fazele compilatorului

Toate aceste faze convertesc codul sursă prin împărțirea în token-uri, crearea arborilor de analiză și optimizarea codului sursă în diferite faze.

Faza 1: Analiza lexicală

Analiza lexicală este prima fază când compilatorul scanează codul sursă. Acest proces poate fi de la stânga la dreapta, caracter cu caracter, și grupează aceste personaje în jetoane.
Aici, fluxul de caractere din programul sursă este grupat în secvențe semnificative prin identificarea jetoanelor. Acesta face introducerea biletelor corespunzătoare în tabelul cu simboluri și trece acel jeton în faza următoare.
Funcțiile principale ale acestei faze sunt:

  • Identificați unitățile lexicale dintr-un cod sursă
  • Clasificați unitățile lexicale în clase precum constante, cuvinte rezervate și introduceți-le în tabele diferite. Va ignora comentariile din programul sursă
  • Identificați simbolul care nu face parte din limbaj

Exemplu:
x = y + 10

indicativele

X identificator
= Operator de misiune
Y identificator
+ Operator de adaos
10 Număr

Faza 2: Analiza sintaxei

Analiza sintaxei se referă la descoperirea structurii în cod. Acesta determină dacă un text urmează sau nu formatul așteptat. Scopul principal al acestei faze este de a vă asigura că codul sursă a fost scris de programator este corect sau nu.
Analiza de sintaxă se bazează pe regulile bazate pe limbajul de programare specific prin construirea arborelui de analiză cu ajutorul token-urilor. De asemenea, determină structura limbii sursă și gramatica sau sintaxa limbii.
Iată o listă a sarcinilor efectuate în această fază:

  • Obțineți jetoane de la analizatorul lexical
  • Verifică dacă expresia este corectă din punct de vedere sintactic sau nu
  • Raportați toate erorile de sintaxă
  • Construiți o structură ierarhică care este cunoscută sub numele de arbore de analiză

Exemplu

Orice identificator/număr este o expresie
Dacă x este un identificator și y+10 este o expresie, atunci x= y+10 este o declarație.
Luați în considerare arborele de analiză pentru următorul exemplu

(a+b)*c

Exemplu de analiză de sintaxă

În Parse Tree

  • Nod interior: înregistrare cu un operator depus și două dosare pentru copii
  • Frunză: înregistrări cu 2/mai multe câmpuri; unul pentru token și alte informații despre token
  • Asigurați-vă că componentele programului se potrivesc în mod semnificativ
  • Adună informații de tip și verifică compatibilitatea tipurilor
  • Operanzii de verificare sunt permisi de limba sursă

Faza 3: Analiza semantică

Analiza semantică verifică consistența semantică a codului. Utilizează arborele de sintaxă al fazei anterioare împreună cu tabelul de simboluri pentru a verifica dacă codul sursă dat este consistent din punct de vedere semantic. De asemenea, verifică dacă codul transmite un sens adecvat.
Semantic Analyzer va verifica dacă există nepotriviri de tip, operanzi incompatibili, o funcție numită cu argumente necorespunzătoare, o variabilă nedeclarată etc.
Funcțiile fazei de analiză semantică sunt:

  • Vă ajută să stocați informațiile de tip colectate și să le salvați în tabelul de simboluri sau arborele de sintaxă
  • Vă permite să efectuați verificarea tipului
  • În cazul nepotrivirii tipului, unde nu există reguli exacte de corectare a tipului care să satisfacă operația dorită, este afișată o eroare semantică
  • Colectează informații despre tip și verifică compatibilitatea tipului
  • Verifică dacă limba sursă permite operanzii sau nu

Exemplu

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

În codul de mai sus, analizorul semantic va introduce numărul întreg 30 la 30.0 înainte de multiplicare.

Faza 4: Intermediară Code Generație

Odată ce faza de analiză semantică s-a încheiat, compilatorul generează cod intermediar pentru mașina țintă. Acesta reprezintă un program pentru anumite abs.tracmașină t.
Codul intermediar este între limbajul de nivel înalt și cel de mașină. Acest cod intermediar trebuie generat în așa fel încât să fie ușor de tradus în codul mașină țintă.
Funcții pe nivel intermediar Code generaţie:

  • Ar trebui să fie generat din reprezentarea semantică a programului sursă
  • Deține valorile calculate în timpul procesului de traducere
  • Vă ajută să traduceți codul intermediar în limba țintă
  • Vă permite să păstrați ordinea de prioritate a limbii sursă
  • Acesta conține numărul corect de operanzi ai instrucțiunii

Exemplu

De exemplu,

total = count + rate * 5

Codul intermediar cu ajutorul metodei codului de adresă este:

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

Faza 5: Code Optimizare

Următoarea fază este optimizarea codului sau codul intermediar. Această fază elimină linia de cod inutilă și aranjează secvența de instrucțiuni pentru a accelera execuția programului fără a pierde resurse. Scopul principal al acestei faze este de a îmbunătăți codul intermediar pentru a genera un cod care rulează mai repede și ocupă mai puțin spațiu.
Funcțiile principale ale acestei faze sunt:

  • Vă ajută să stabiliți un compromis între viteza de execuție și cea de compilare
  • Îmbunătățește timpul de rulare al programului țintă
  • Generează cod simplificat încă în reprezentare intermediară
  • Eliminarea codului inaccesibil și eliminarea variabilelor neutilizate
  • Eliminarea instrucțiunilor care nu sunt modificate din buclă

Exemplu:
Luați în considerare următorul cod

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

Poate deveni

b =c * 10.0
f = e+b

Faza 6: Code Generație

Code Generarea este ultima și finala fază a unui compilator. Aceasta primește date de intrare din fazele de optimizare a codului și produce codul paginii sau codul obiect ca rezultat. Obiectivul acestei faze este de a aloca spațiu de stocare și de a genera cod mașină relocabil.
De asemenea, alocă locații de memorie pentru variabilă. Instrucțiunile din codul intermediar sunt convertite în instrucțiuni de mașină. Această fază acoperă codul de optimizare sau intermediar în limba țintă.
Limba țintă este codul mașinii. Prin urmare, toate locațiile și registrele de memorie sunt, de asemenea, selectate și alocate în această fază. Codul generat de această fază este executat pentru a prelua intrări și a genera ieșirile așteptate.

Exemplu

a = b + 60.0
Ar putea fi tradus în registre.

MOVF a, R1
MULF #60.0, R2
ADDF R1, R2

Managementul tabelului de simboluri

Un tabel de simboluri conține o înregistrare pentru fiecare identificator cu câmpuri pentru atributele identificatorului. Această componentă face mai ușor pentru compilator să caute înregistrarea de identificare și să o recupereze rapid. Tabelul de simboluri vă ajută și pentru gestionarea domeniului. Tabelul de simboluri și gestionarea erorilor interacționează cu toate fazele și tabelul de simboluri se actualizează în mod corespunzător.

Rutina de gestionare a erorilor

În procesul de proiectare al compilatorului, pot apărea erori în toate fazele de mai jos:

  • Analizor lexical: jetoane scrise greșit
  • Analizor de sintaxă: lipsește paranteza
  • Generator de cod intermediar: operanzi nepotriviți pentru un operator
  • Code Optimizator: Când instrucțiunea nu este accesibilă
  • Code Generator: Când memoria este plină sau nu sunt alocate registre adecvate
  • Tabelele cu simboluri: Eroare a mai multor identificatori declarati

Cele mai frecvente erori sunt secvența de caractere nevalidă în scanare, secvențele de simbol invalide în tip, eroarea domeniului și analizarea în analiza semantică.
Eroarea poate fi întâlnită în oricare dintre fazele de mai sus. După găsirea erorilor, faza trebuie să se ocupe de erori pentru a continua cu procesul de compilare. Aceste erori trebuie raportate operatorului de eroare care se ocupă de eroare pentru a efectua procesul de compilare. În general, erorile sunt raportate sub formă de mesaj.

Întrebări frecvente

Faza de analiză (front end) descompune codul sursă prin analiză lexicală, sintactică și semantică. Faza de sinteză (back end) construiește programul țintă prin generare intermediară de cod, optimizare și generare de cod.

Un compilator traduce întregul program sursă în cod mașină înainte de a-l rula. Un interpretor traduce și execută codul linie cu linie, ceea ce este mai ușor de depanat, dar de obicei mai lent în timpul execuției.

Codul cu trei adrese este o reprezentare intermediară în care fiecare instrucțiune are cel mult trei operanzi, cum ar fi t1 = a + b. Este simplu de optimizat și ușor de tradus în cod mașină țintă.

Inteligența artificială și învățarea automată ajută compilatoarele moderne să ia decizii de optimizare mai inteligente, cum ar fi alegerea transformărilor de buclă, inlinearea și alocarea registrelor. Acestea prevăd ce optimizări îmbunătățesc performanța pentru un anumit program și o anumită țintă.

Da. IA poate explica fiecare fază cu exemple, tracmodul în care o instrucțiune exemplu trece de la token-uri la cod mașină și răspunde la întrebări ulterioare. Acest lucru facilitează învățarea designului compilatorului pentru studenți.

Rezumați această postare cu: