Documente Academic
Documente Profesional
Documente Cultură
INTRODUCERE
1.1 Obiectul i utilitatea disciplinei
Tehnicile de compilare sunt tehnici de programare specializate utilizate, n primul rnd, la scrierea programelor de translatare dar, n acelai timp, aplicabile la realizarea unei game de programe similare translatoarelor. Se tie c translatorul este un program care verific programele scrise de utilizator ntr-un anumit limbaj de programare i le traduce n programe echivalente exprimate ntr-un limbaj accesibil calculatorului (de exemplu cod main). Exponentul cel mai cunoscut al familiei programelor de translatare este compilatorul, ceea ce justific i denumirea disciplinei. Istoria scrierii compilatoarelor a debutat n 1957, cnd a fost realizat primul compilator pentru limbajul de programare Fortran. Performana deosebit pentru vremea aceea, aparine unei echipe de cercettori americani, de la firma I.B.M, condus de John Backus. Implementarea compilatorului a durat circa 18 luni ceea ce poate s par mult astzi cnd compilatoare pentru limbaje de programare comparabile cu Fortran sau chiar mai complexe (Pascal, C, Ada, Java) se pot scrie ntr-un timp mult mai scurt. Principalii factori care au contribuit la aceast evoluie sunt: - Definirea tiinific a noilor limbaje de programare prin includerea unor concepte de baz comune i respectarea riguroas a anumitor principii care uureaz verificarea i translatarea programelor. - Elaborarea, ntre timp, a unei teorii a compilrii bine fundamentat matematic prin Algebra superioar, Logica Matematic i n special prin Teoria limbajelor formale. - Evoluia continu a Ingineriei programrii care a disciplinat i eficientizat activitatea de programare n general i, n special, realizarea programelor de mari dimensiuni. - Apariia i perfecionarea unor unelte software specializate pentru proiectarea i scrierea compilatoarelor. Utiliznd astfel de unelte, se pot genera n mod automat pri ale unui compilator ceea ce reduce durata lui de implementare la sptmni sau chiar la zile. Astzi nu este posibil s se scrie programe de translatare competitive fr cunoaterea teoriei compilrii i ignornd aplicarea tehnicilor, algoritmilor i metodelor specifice. Mai mult, cel care se ocup de implementarea unui limbaj de programare
trebuie s aib solide cunotine att din domeniul general al tiinei calculatoarelor (arhitectur, cod main, echipamente periferice) ct i o privire corect i complet asupra ntregului domeniu al limbajelor de programare. Din acest motiv, disciplina Tehnici de compilare este logic legat de disciplina Conceptele fundamentale ale limbajelor de programare n care s-au introdus deja o serie de cunotine, concepte i noiuni care vor fi utilizate i dezvoltate n continuare: limbaje de programare caracteristici, clasificri, implementarea unui limbaj de programare, sintaxa i semantica unui limbaj simbolisme pentru reprezentarea lor, gramatica unui limbaj, arbore sintactic, probleme legate de implementarea diferitelor concepte i mecanisme specifice limbajelor de programare etc. Coninutul disciplinei Tehnici de compilare este util i pentru realizarea altor tipuri de programe dect cele din familia compilatoarelor: Sisteme de operare, Sisteme de gestiune a bazelor de date, Editoare de texte, toat gama de Programe utilitare sau chiar simple aplicaii care presupun, ca interfa cu utilizatorul, un limbaj de comunicare (comand). Cu ct acest limbaj este mai complicat, cu att este mai util s stpnim astfel de tehnici i metode. Aceste cunotine sunt importante chiar din faza definirii i proiectrii limbajului. Aplicate corect, ele pot conduce la simplificarea limbajului de comunicare i, implicit, la eficientizarea procesului de traducere. Se poate concluziona c teoria compilrii ofer tehnici i metode avansate de programare utile ntr-o gam larg de aplicaii n care comunic dou sisteme, cazul cel mai frecvent fiind acela n care cele dou sisteme sunt omul i respectiv calculatorul.
Fig. 1.1. Compilatorul n mod frecvent limbajul destinaie este limbaj main sau un limbaj apropiat de acesta. Ca o parte important a procesului de traducere, compilatorul semnaleaz utilizatorului prezena erorilor n programul surs.
Existena, n prezent, a mii de limbaje surs, varietatea limbajelor destinaie, diferenele, mai mici sau mai mari, de structur i funcionare, au condus la o aparent copleitoare diversificare a compilatoarelor. n ciuda acestei complexiti i varieti aparente, sarcinile de baz pe care trebuie s le ndeplineasc orice compilator sunt n esen aceleai. nelegnd aceste sarcini se pot construi compilatoare pentru o mare varietate de limbaje surs i calculatoare destinaie folosind aceleai tehnici de baz.
Cunotinele despre organizarea i scrierea compilatoarelor au crescut enorm de la nceputul apariiei primelor compilatoare, n deceniul 6. De atunci s-au descoperit tehnici sistematice pentru tratarea multora dintre sarcinile importante care apar n compilatoare. S-au dezvoltat de asemenea, limbaje de implementare bune, ambiane de programare i unelte software. n aceste condiii, un compilator substanial poate fi implementat chiar i ca proiect ntr-un curs de un semestru de proiectare a compilatoarelor.
Modelul analiz-sintez al compilrii Funciile de principiu ale unui compilator sunt: Analiza programului surs; Sinteza programului destinaie (obiect); Corespunztor acestor funcii, compilatoarele se compun din dou pri.. Partea de analiz desface programul surs n componenetele sale de baz i creaz o reprezentare intermediar a programului surs. Partea de sintez construiete programul destinaie din aceast reprezentare intermediar.
avanseaz n procesul de compilare. Aceste informaii se utilizeaz pentru a efectua verificrile semantice (de exemplu verificrile de tip) precum i pentru generarea corect a codului obiect.
Program surs
Analizor lexical
Analizor sintactic
Tratarea erorilor
Optimizor de cod
Generator de cod
Program destinaie
Fig. 1.2. Fazele unui compilator Detectarea i semnalarea erorilor Fiecare faz de compilare poate descoperi erori. Reacia compilatorelor la erori poate fi diferit: a) Oprirea compilrii la prima eroare, semnalarea i corectarea ei n programul surs, urmat de reluarea compilrii de la nceput. b) Tratarea erorilor detectate astfel nct compilarea s poat continua, permind s se detecteze i alte erori care vor fi corectate n mod global, la sfrit. Acest mod de tratare se numete revenirea din eroare. n ceea ce privete gestionarea tratrii erorilor, ea poate fi global, pe ntregul compilator, cum sugereaz fig. 1.2 sau poate fi distribuit fiecrei faze.
Cea mai mare parte dintre erorile de compilare sunt detectate n fazele de analiz sintactic i semantic.
Structura ierarhic a unui program este, n multe cazuri, exprimat prin reguli recursive. De exemplu, sunt binecunoscute regulile recursive de definire a expresiilor. Similar, ntr-o mare categorie de limbaje, i instruciunile sunt definite prin reguli recursive. mprirea n analiz lexical i sintactic este oarecum arbitrar. De obicei se alege o mprire care simplific sarcina total a analizei. Astfel, numerele, sirurile de caractere, cuvintele (identificatorii) semnele de punctuaie sunt considerate simboluri lexicale n timp ce expresiile, instruciunile, declaraiile sunt construcii sintactice. 3. Analiza semantic sau contextual Efectueaz verificrile care in de sensul (nelesul) componentelor programului i culege informaii de tip pentru faza urmtoare: generarea de cod. Ea utilizeaz structura ierarhic determinat de faza de analiz sintactic pentru a identifica operatorii i operanzii expresiilor i instruciunilor. O component important a analizei semantice este verificarea tipurilor. Aceast component verific dac fiecare operator are operanzi permii de specificarea limbajului surs. De exemplu, definiiile multor limbaje de programare consider c este eroare atunci cnd un numr real este utilizat pentru a indexa un tablou. O alt parte distinct o reprezint analiza de domeniu adic verificarea utilizrii fiecrui identificator strict numai n domeniul su de vizibilitate.
10
b) Pentru a pstra valorile calculate n fiecare instruciune, compilatorul trebuie s genereze variabile temporare (variabile create de compilator fr coresponden direct n textul surs);
5. Optimizarea codului Scopul acestei faze este acela de a mbuntii codul intermediar, astfel nct s rezulte cod main mai rapid. n acest sens se acioneaz pentru eliminarea redundanelor, a calculelor i variabilelor inutile. Exist mari diferene ntre optimizarea de cod care se face n diferite compilatoare. n aa numitele compilatoare cu optimizare, n care acestei faze i se acord o importan deosebit, fraciunea din timpul de compilare cheltuit pentru optimizare este foarte mare. Exist ns i optimizri simple care mbuntesc considerabil eficiena programului obiect fr a ncetini prea mult compilarea. 6. Generarea de cod Generarea codului destinaie (obiect) este faza final a compilatorului. Codul obiect generat poate s fie, de exemplu, cod main relocabil sau un cod virtual. Pe lng transformarea instruciunilor intermediare n secvene de instruciuni main (virtuale) mai trebuie rezolvate urmtoarele probleme: - selecionarea i alocarea de celule de memorie pentru variabilele din program; - alegerea i implementarea celor mai eficiente tehnici de acces la fiecare variabil n parte (inclusiv la componentele variabilei) utiliznd toate posibilitile de adresare ale calculatorului: indexare, indirectare etc.; - alocarea registrelor pentru calcule i pentru reinerea temporar a rezultatelor intermediare.
n fig. 1.4 se prezint, pe faze, ntregul proces de traducere al instruciunii a:=b+c*10 i principalele structuri de date asociate compilrii. Observaie: Se consider c a, b i c sunt variabile reale.
11
a:=b+c*10
TS 1 a b c
-------------
id
Analizor semantic
id
num
10
Optimizor de cod
temp1:=id3*10.0 id1:=id2+temp1
Generator de cod
(id3) -> R2 #10.0 * (R2) -> R2 (id2) -> R1 (R2) + (R1) -> R1 (R1) -> id1
12
13
programelor compilate, datorit volumului mare de date care trebuie reinute, incluznd i forma intern a programului. Pentru unele faze, gruparea ntr-o trecere unic este destul de simpl (de exemplu analiza lexical i sintactic). n schimb generarea de cod este mai greu de efectuat pn cnd nu s-a generat n ntregime reprezentarea intermediar (ex. variabilele utilizate nainte de a fi declarate n PL/I, Algol 68 i salturile nainte n codul obiect corespunztoare implementrii unor instruciuni condiionale sau ciclice).
14
3. Maini de traducere dirijate de sintax. Acestea produc colecii de rutine care parcurg arborele sintactic, genernd cod intermediar. 4. Generatoare de cod automate. O astfel de unealt primete o colecie de reguli care definesc traducerea fiecrei operaii din limbajul intermediar n limbajul main pentru calculatorul destinaie. Regulile trebuie s includ suficiente detalii pentru a putea trata diferitele metode de acces posibile pentru date; de exemplu variabilele pot fi n registre, ntr-o locaie fix (static) n memorie sau li se poate aloca o poziie ntr-o stiv. Tehnica de baz este potrivirea tiparelor: instruciunile din codul intermediar sunt nlocuite cu tipare care reprezint secvene de instruciuni main. 5. Maini pentru fluxul datelor. Sunt utilizate la optimizarea de cod pentru culegerea de informaii despre modul de transmitere a valorilor ntre diferitele pri ale programului. Maina primete la intrare detalii despre relaia dintre instruciunile de cod intermediar i informaia culeas.
15