Vous êtes sur la page 1sur 14

TEHNICI DE COMPILARE

Cap.I

n acest capitol vom vedea ce este un compilator i vom descrie pe scurt fazele i componentele unui compilator. Spus simplu, un compilator este un program care citete un alt program scris ntr-un anumit limbaj, numit limbaj surs i l traduce ntr-un program echivalent n alt limbaj, numit limbaj destinaie (vezi Fig. 1.1.). O parte important a procesului de traducere o constituie i atenionarea utilizatorului asupra erorilor din programul surs.

&1.1. Introducere
Principiile i tehnicile folosite n scrierea unui compilator sunt att de cuprinztoare nct multe dintre acestea pot fi folosite cu succes n multe alte cazuri. Scrierea unui compilator necesit cunotine de programare, arhitectura calculatoarelor, limbaje formale i algoritmic. Tehnicile utilizate n construcia compilatoarelor pot folosi i n alte domenii cum ar fi: editoare de texte, sisteme de regsire a informaiilor i recunoaterea formelor. De asemenea, limbajele independente de context i definiiile orientate pe sintax pot fi folosite pentru a construi minilimbaje ca acelea de tiprire sau de desenare a figurilor. Tehnicile de optimizare a codului au fost folosite n verificarea programelor i n producerea de programe structurate din unele nestructurate.

Program surs

Compilator

Program obiect

Mesaje de eroare

Figura 1.1
Pag.1

TEHNICI DE COMPILARE

Cap.I

Un compilator este un program care are ca intrare un program surs, scris ntr-un limbaj evoluat, iar ca ieire furnizeaz un program obiect. n timpul traducerii, compilatorul afieaz mesajele de eroare, putnd chiar s corecteze anumite erori. Exist mii de limbaje de programare, de la cele tradiionale (FORTRAN, PASCAL) pn la limbaje specializate aprute n diferite domenii ale aplicaiilor calculatoarelor. Cu ct programul surs este scris ntr-un limbaj mai evoluat (mai apropiat de limbajul natural), cu att structura compilatorului este mai complicat. Limbajul obiect poate avea mai multe accepiuni: alt limbaj de programare sau un limbaj main pentru orice calculator ntre un microprocesor i un supercomputer. Dei compilatoarele pot fi ntr-un singur pas, multi-pass, load-and-go (evit trecerea prin faze necesare numai programelor complexe form direct executabil) i altele, tehnicile de baz folosite sunt aceleai. Compilatoarele single-pass efectueaz o singur trecere asupra programului surs, pe cnd cele multi-pass proceseaz de mai multe ori sursa Primele compilatoare au nceput s apar prin anul 1950, experimentarea i implementarea lor fiind fcut independent de grupuri diferite. Primele ncercri de compilare au nceput cu traducerea expresiilor aritmetice n cod main. n aceast perioad, compilatoarele erau considerate programe deosebit de dificile. De exemplu, compilatorul FORTRAN (Backus .a., 1957) a necesitat 18 ani de munc n echip pentru implementare. De atunci s-au descoperit tehnici pentru rezolvarea principalelor probleme care apar n compilare, tehnici care au fcut posibil scrierea unui compilator n cadrul unui proiect studenesc. Compilatorul se compune din dou pri principale: analiza i sinteza. Partea de analiz realizeaz descompunerea programului surs n pri constituente i crearea reprezentrii intermediare. Partea de sintez construiete programul obiect dorit din reprezentarea intermediar. n timpul analizei, operaiile implicate de programul surs sunt determinate i nregistrate ntr-un arbore. De cele mai multe ori se folosete un arbore sintactic n care fiecare nod reprezint o operaie, iar descendenii nodului sunt operanzi (argumentele operaiei).

Pag.2

TEHNICI DE COMPILARE

Cap.I

Exemplul 1.1 Arborele sintactic pentru instruciunea de atribuire: valoare := valoareinit + cant * 40 este urmtorul:
: =

valoar e

valoareinit

*
40 cant

Figura 1.2 Multe instrumente care manipuleaz programe surs execut nti anumite tipuri de analiz. Exemple de astfel de instrumente sunt: 1. Editoare structurale. Un editor structural are ca intrare un ir de comenzi din care construiete un program surs. Un editor structural nu execut numai crearea textului i funcii de modificare precum un editor de texte ordinar, ci el de asemenea analizeaz textul punndu-l ntr-o structur ierarhic. Deci ieirea unui astfel de editor este similar cu faza de analiz a unui compilator. 2. Pretty printer. Un astfel de tipritor analizeaz un program i l tiprete ntr-o form n care structura programului devine foarte vizibil. De exemplu, comentariile apar scrise cu alte fonturi, iar instruciunile incluse una n cealalt sunt scrise astfel nct s sugereze ierarhia. 3. Analizor static. Un astfel de program citete un program surs, l analizeaz i pune n eviden defectele fr s-l execute. De exemplu, un analizor static depisteaz acele pri ale programului surs care nu vor fi niciodat executate sau acele variabile care sunt folosite nainte de a fi definite. n plus, el poate depista anumite erori logice cum ar fi folosirea unei variabile reale drept pointer. 4. Interpretor. Interpretorul nu produce un program obiect, ci execut operaiile implicate n programul surs. Pentru o instruciune de atribuire, de exemplu, un interpretor poate
Pag.3

TEHNICI DE COMPILARE

Cap.I

construi un arbore ca cel din Figura 1.1 i apoi s execute operaiile din noduri, parcurgnd arborele. n rdcin va descoperi c este greu s execute o atribuire n care membrul drept este o expresie i atunci va chema o rutin care va calcula valoarea expresiei. Aceast rutin descoper c are de fcut o adunare n care membrul drept este o expresie. Atunci se autoapeleaz (se apeleaz recursiv) pentru calculul expresiei din membrul drept (o nmulire) i apoi adun valoarea la variabila iniial. Interpretoarele sunt frecvent utilizate pentru a executa limbaje de comand pentru c fiecare operator executat ntr-un limbaj de comand este, n mod normal, o apelare a unei rutine complexe ca un editor sau un compilator. Similar, anumite limbaje de nivel foarte nalt APL sunt interpretate pentru c exist multe lucruri despre date, ca dimensiunea irurilor sau tablourilor, care nu pot fi deduse n timpul compilrii. n mod normal, privim un compilator ca un program care traduce un program scris intr-un limbaj surs (ca FORTRAN-ul) ntr-un limbaj de asamblare sau n cod main pentru un anume calculator. Totui, exist i alte domenii unde tehnicile de compilare pot fi folosite. Partea de analiz din urmtoarele exemple este similar cu partea de analiz a unui compilator: 1. Formatarea textelor. Un formator de text are ca intrare un ir de caractere ntre care majoritatea sunt text sau de tiprire, dar anumite caractere formeaz comenzi pentru a indica paragrafe, figuri sau structuri matematice ca indici inferiori sau superiori. 2. Silicon compiler. Un silicon computer are un limbaj surs care este similar cu un limbaj de programare dar variabilele limbajului nu reprezint locaii n memorie ci semnale logice (0 sau 1) sau grupe de semnale n circuite de comunicaie. Ieirea este descrierea unui circuit ntr-un limbaj specific. 3. Interpretor logic. Un astfel de interpretor traduce un predicat, coninnd operatori relaionali i booleeni, n comenzi de cutare ntr-o baz de date a unor nregistrri satisfcnd predicatul. Observaia 1.1 n afar de compilator mai sunt necesare i alte programe pentru a obine un program obiect. Un program surs poate fi mprit n module care sunt memorate n cmpuri separate. Sarcina adunrii programului surs revine unui

Pag.4

TEHNICI DE COMPILARE

Cap.I

preprocesor. Preprocesorul poate, de asemenea, s desfac macrourile n instruciuni ale programului surs.

&1.2. Fazele unui compilator


Un compilator opereaz n mai multe faze, fiecare din faze transformnd programul dintr-o reprezentare n alta. O descompunere tipic a unui compilator este prezent n Figura 1.3,

Program surs Analizor lexical (scanner)

Analiza

Analizor sintactic (parser)

Analizor semantic
Managerul tabelei de simboluri Recuperarea erorilor

Generatorul codului intermediar

Sinteza

Optimizarea codului

Generatorul de cod

Program obiect unele dintre faze fiind grupate mpreun.


Pag.5

TEHNICI DE COMPILARE

Cap.I

Figura 1.3 Cteodat, att managerul tabelei de simboluri ct i recuperarea erorilor sunt considerate faze ale compilrii. &1.2.1. Managerul tabelei de simboluri Una din funciile eseniale ale unui compilator este de a nregistra identificatorii folosii i de a aduna informaii despre diferitele atribute ale fiecrui identificator. Aceste atribute pot furniza informaii despre memoria alocat pentru un identificator, despre scopul su, i n cazul unui nume de procedur- anumite informaii ca: numrul parametrilor, tipul i metoda de transmitere a acestora (de exemplu prin referin) i tipul returnat. O tabel de simboluri este o structur de date coninnd o nregistrare pentru fiecare identificator, cu cmpuri pentru atributele identificatorului. O astfel de structur de date trebuie astfel organizat nct s permit stocarea i regsirea rapid a informaiei. Cnd un identificator este depistat n faza de analiz lexical, el este imediat introdus n tabela de simboluri. Totui atributele identificatorului nu pot fi imediat deduse din faza de analiz lexical. Exemplul 1.2 ntr-o declaraie Pascal de forma: Var valoare, valoareinit, cant : Real; tipul real nu este cunoscut cnd identificatorii valoare, valoareinit i cant sunt depistai de analizorul lexical. Celelalte faze introduc n tabela de simboluri informaii despre identificatori i apoi utilizeaz aceste informaii n diferite feluri. De exemplu, n timpul analizei semantice i la generarea codului intermediar este necesar s tim ce tip de identificatori sunt pentru a putea verifica dac programul surs i utilizeaz corect. Generatorul de cod cere i utilizeaz informaii detaliate despre memoria alocat unui identificator. &1.2.2.Detectarea i raportarea erorilor n fiecare faz pot fi descoperite erori. Totui, dup depistarea unei erori o faz trebuie s continue pentru a depista alte erori din programul surs, deci trebuie s repare eroarea, ntr-o anumit form care s permit aceast continuare. n faza de analiz lexical i n cea de analiz sintactic se depisteaz cea mai mare parte a erorilor detectabile de un
Pag.6

TEHNICI DE COMPILARE

Cap.I

compilator. Faza de analiz lexical poate detecta erorile n cazul n care caracterele rmase din intrare nu formeaz o unitate lexical a limbajului. Erorile de sintax sunt acelea n care un ir de uniti lexicale violeaz structura sintactic a limbajului surs (regulile limbajului). n faza de analiz semantic a compilatorului, analizorul ncearc s detecteze acele construcii corecte din punct de vedere sintactic- care nu au sens din punct de vedere operaional, de exemplu dac ncercm s adunm doi identificatori i unul este nume de tablou iar altul nume de procedur. Manevrarea erorilor va fi discutat la fiecare faz n parte. &1.2.3.Faza de analiz Pe parcursul compilrii, forma programului surs se schimb. Vom ilustra acest lucru considernd traducerea instruciunii: valoare := valoareinit + cant * 40 ( 1.a)

(a) Faza de analiz lexical citete caracterele programului surs i le grupeaz n uniti lexicale sau token-i, unde fiecare unitate lexical reprezint o secven logic de caractere ca, de exemplu, un identificator, un cuvnt cheie (if, while, begin), un caracter sau un multicaracter (:=, <= etc.). Secvena de caractere formnd un token se numete lexem pentru token. Token-ilor li se adaug valoarea lexical. De exemplu, cnd identificatorul cant este gsit, analizorul lexical genereaz un token, id, dar adaug i lexema cant n tabela de simboluri dac ea nu exist deja. Astfel, n urma analizei lexicale a instruciunii ( 1.a) se va obine: id1 := id2 + id3 * 40 ( 1.b) Observaia 3.5.1 Se poate utiliza un token pentru := dar ngreuneaz expunerea; de asemenea, token-ul numr pentru constanta 40. De asemenea, n tabela de simboluri se introduce valoare n momentul depistrii unitii lexicale id1, valoareinit n momentul depistrii unitii lexicale id2, respectiv cant n momentul depistrii unitii lexicale id3.

Pag.7

:= id1+ id id2*1

: = +
Cap.I

TEHNICI DE COMPILARE

id3num (40) id

* id3 40 Figura1.4

(b) n faza de analiz sintactic se ncearc construirea arborelui de derivaie, o structur ierarhic a irului de token-i. O structur tipic de date pentru arbore este prezentat n Figura 1.4. n figur, un nod interior este o nregistrare cu un cmp pentru operator i dou cmpuri coninnd pointeri pentru nregistrarea descendenilor stng i drept. O frunz este o nregistrare cu dou sau mai multe cmpuri, unul pentru a identifica token-ul i unul pentru a nregistra informaii despre acel token. Pentru exemplul considerat, Figura 1.6 arat succesiunea fazelor n procesul analizei. n mod obinuit, arborele sintactic pentru instruciunea de atribuire se construiete conform regulilor gramaticale ale limbajului, care folosesc regulile definirii unei expresii aritmetice: 1. Orice identificator este o expresie. 2. Orice numr este o expresie. 3. Dac expresie1 i expresie2 sunt expresii, atunci tot expresii sunt i: expresie1 + expresie2 expresie1 * expresie2 (expresie1) unde regulile 1 i 2 sunt nerecursive iar regula 3 este recursiv. Similar, pentru instruciune multe limbaje folosesc regulile de definire: 1. Dac identificator1 este un identificator i expresie2 este o expresie, atunci identificator1 := expresie2 este o instruciune (de atribuire). 2. Dac expresie1 este o expresie i instruciune2 este o instruciune, atunci while (expresie1) do instruciune2 i
Pag.8

TEHNICI DE COMPILARE

Cap.I

if (expresie1) then instruciune2 sunt instruciuni. Atunci arborele sintactic pentru instruciunea de atribuire considerat arat ca n Figura 1.5 . Instruciune de atribuire
identificator

:= expresie
identificator

expresie + expresie expresie *


numr

valoare

expresie
identificator

valoareinit

cant

40 Figura 1.5

Faza de analiz lexical rezolv capetele nnegrite din figur, pentru care aceste definiii nu sunt recursive (se folosesc gramatici regulate i automate cu numr finit de stri). n faza de analiz sintactic, definiiile recursive sunt modelate cu ajutorul gramaticilor independente de context. n mod uzual nu se folosete un arbore sintactic aa de complicat ci unul de analiz ca cel din Figura 1.4 . (c) n faza de analiz semantic, analizorul caut erorile semantice i adun informaii pentru generarea de cod. O parte important din analiza semantic este verificarea tipurilor. Analizorul semantic verific dac fiecare operand cu care opereaz un operator este de tipul cerut n limbajul de programare surs. Totui specificarea limbajului permite i anumite corecii, de exemplu cnd o operaie aritmetic este aplicat unui ntreg i unui real. n acest caz, compilatorul trebuie s converteasc ntregul ntr-un real. Pentru exemplul considerat de noi ( 1.a), 40 este un ntreg i cant este real, deci analizorul semantic va converti 40 n real prin apelarea subrutinei IntToReal i deci adaug un nod n plus la arborele sintactic.

Pag.9

TEHNICI DE COMPILARE

Cap.I

&1.2.4.Faza de sintez (a) Faza de generare a codului intermediar: dup analiza sintactic i semantic, anumite compilatoare genereaz o reprezentare intermediar explicit a programului surs, ca un program pentru o main abstract. Aceast reprezentare trebuie s aib dou caliti: s fie uor de realizat i uor de tradus n program obiect. O reprezentare intermediar poate avea o mulime de forme, una din acestea fiind codul cu trei adrese, n care exist cel mult trei operanzi. n aceast form, compilatorul poate decide n ce ordine s execute operaiile (operatorul * este anterior operatorului +). (b) n faza de optimizare de cod, compilatorul tinde s mbunteasc codul intermediar n sensul micorrii timpului de execuie. Astfel, n exemplul nostru ( 1.a), compilatorul poate deduce c are de fcut o singur conversie pentru constanta 40 n real, deci nu are rost s o memoreze i nici s adauge IntToReal ci s foloseasc direct 40.0 . De asemenea, cmp3 este folorit numai o dat pentru a memora i transmite valoarea sa lui id1. Atunci, devine sigur nlocuirea lui cmp3 prin id1. (c) Faza final a compilatorului este faza de generare de cod obiect, care const ntr-un cod main relocatabil sau ntr-un cod de asamblare. Sunt selectate locaii de memorie pentru fiecare din variabilele folosite n program. Apoi instruciunile intermediare sunt traduse fiecare n cte o secven de instruciuni n limbaj de asamblare. Un aspect deosebit de important este atribuirea variabilelor regitrilor de memorie. Pentru exemplul nostru ( 1.a), codul de asamblare ar fi:
MOVF MULF MOVF ADDF MOVF id3,R2 #40.0,R2 id2,R1 R2,R1 R1,id1

ntr-o instruciune n cod de asamblare, primul i al doilea operand reprezint sursa, respectiv destinaia. Litera F ataat instruciunii respective specific faptul c instruciunile se execut cu numere n virgul flotant. Semnul # specific faptul c 40.0 trebuie tratat ca o constant.
Pag.10

TEHNICI DE COMPILARE

Cap.I

O imagine complet asupra compilrii exemplului considerat (1.a) este dat n figura urmtoare (Figura 1.6).

Pag.11

TEHNICI DE COMPILARE valoare := valoareinit + cant * 40

Cap.I

analizor lexical
id1 := id2 + id3 * 40

analizor sintactic
:= id1 id2 id3 + * num(40)

analizor semantic
:= id1 id2 id3 + * IntToReal(40)

generatorul codului
temp1 := IntToReal(40) temp2 := id3 * temp1 temp3 := id2 + temp2 id1 := temp3

optimizarea codului
temp1 := id3 * 40.0 id1 := id2 + temp1

generarea codului
MOVF id3, R2 MULF #40.0, R2 MOVF id2, R1 ADDF R2, R1 MOVF R1, id1

Fig. 1.6. Transformarea unei instruciuni de atribuire aritmetic


Pag.12

TEHNICI DE COMPILARE

Cap.I

&1.3.Instrumente compilatoarelor

folosite

construcia

Pentru c fazele aprute n construcia compilatoarelor sunt, n esen, aceleai, au aprut o serie de instrumente soft folosibile. Aceste instrumente sunt des referite ca: compilatoare de compilator, generatoare de compilator sau sisteme de scriere a translatoarelor. 1. Generatoare de analizor lexical (scanner generators) Aceste programe genereaz automat un analizor lexical, pe baza unei specificaii alctuite din expresii regulate i aciuni asociate acestor expresii regulate. Primul generator de acest tip a fost LEX, realizat n 1975 de M.E.Lesle, sub sistemul de operare Unix. Pentru MS-DOS exist varianta PCLEX; Un alt generator de scanner este FLEX al proiectului GNU, unul din cele mai eficiente generatoare de analizor lexical; Mai exist i REX la proiectului COCKTAIL, cu un limbaj de specificaie propriu diferit de LEX i care permite o mai mare libertate de micare. 2. Generatoare de analizor sintactice (parser generators) Un astfel de generator este un program a crui intrare este o gramatic indpendent de context iar ieirea este un analizor sintactic. Un astfel de generator este YACC (Yet Another Compiler Compiler) creat n 1970 de S.C.Johnson. Pentru MS-DOS exist varianta PCYACC. Alte astfel de generatoare sunt: BISON al proiectului GNU-FSF n sistemul de operare LINUX (versiune UNIX); BYACC (Berkeley YACC) n sistemul de operare MS-DOS (versiunea 6.0); LALR al proiectului COCKTAIL, dezvoltat de Universitatea Karlsruhe-Germania. 3. Mecanisme de traducere orientate pe sintax (syntaxdirected translation engines) Acestea sunt rutine de parcurgere a arborelui de analiz i a codului intern. n acest domeniu sunt programe ale proiectului COCKTAIL, cum ar fi: AST: generator pentru arborele de sintax abstract;

Pag.13

TEHNICI DE COMPILARE

Cap.I

AG: generator al unui evaluator al atributelor semantice ale componentelor arborelui sintactic obinut prin AST; ESTRA: generator pentru transformarea arborelui sintactic atributat.
Exerciii

1. Considerai cteva compilatoare la care avei acces. Comparai structura lor i timpii de execuie pentru acelai program. 2. Descriei, pe scurt, fazele compilrii pentru o instruciune de atribuire de forma: A1 := A1 + B * 2 * (C A / 5)

&1.1. INTRODUCERE...........................................................................................................1 &1.2. FAZELE UNUI COMPILATOR.................................................................................5 &1.2.1. MANAGERUL TABELEI DE SIMBOLURI................................................................................6 &1.2.2.DETECTAREA I RAPORTAREA ERORILOR.............................................................................6 &1.2.3.FAZA DE ANALIZ..........................................................................................................7 &1.2.4.FAZA DE SINTEZ.........................................................................................................10 &1.3.INSTRUMENTE FOLOSITE N CONSTRUCIA COMPILATOARELOR.....13 Exerciii...........................................................................................................................14

Pag.14

Vous aimerez peut-être aussi