3. Ce vom face la LFT în acest an
Cum se implementeaza un limbaj de
programare
Analiza lexicală, sintactică, semantică
Generare de cod intermediar
Sistemul de runtime
Optimizări
Garbage collection, Just In Time compilers
4. Tehnologii
Limbaje de programare
Pentru unele lucrări practice la alegere
Parsare
generatoare de analizoare lexicale+semantice
6. Bibliografie
The Purple Dragon Book
Compilers - Principles, Techniques and Tools
Aho, Lam, Sethi & Ullman
Exista un numar mare de cursuri online bazate pe Dragon Book
(de ex. coursera.org )
8. Structura cursului
Cursul cuprinde aspecte teoretice si practice
Aveți nevoie de limbaje de programare!
Teme programare = practică
9. De ce un curs de compilatoare
Scopul cursului: cum se implementeaza un limbaj
de programare
De ce e nevoie de multe limbaje…
Fiecare domeniu de aplicatie are cerintele proprii (aplicatii
de sistem, baze de date, calcul stiintific, aplicatii web)
Dinamica limbajelor de programare
Este relativ usor de scris un limbaj nou.
Este greu de modificat un limbaj popular.
Apar noi domenii de aplicatii.
Limbaje legate de platforma (Java, .NET , Android)
10. De ce un curs de compilatoare
Sunt peste tot
Toolchains; IDE-uri; analiza statică; execuție simbolică;
scripting; domain specific languages; baze de date;
tehnoredactare; servere HTTP; framework-uri web;
browsere; drivere video
Combina cunostinte de hardware, software,
inginerie, matematica
Multe probleme grele/complexe, implica multa
teorie dar si practica
Compilatoarele “ghideaza” procesoarele viitoare
11. Cum sunt implementate limbajele?
Două strategii principale
Interpretoarele rulează programele “așa cum sunt”
Preprocesare puțină sau de loc
Compilatoarele – preprocesare extinsă
12. Istoria limbajelor high-level
1954: IBM dezvoltă 704
Succesorul lui 701
Problema
Costurile software depășesc costurile hardware
Toată programarea se efectuează în limbaj de
asamblare
20. Fazele compilarii
▪ Preprocesorul macro substituţie, eliminarea
comentariilor, etc.
▪ Analiză + generare de cod = componenta principală a
traducerii
❑ Se verifica corectitudinea formala a textului programului
❑ Se traduce acest text într-o alta forma
▪ Optimizari = îmbunătăţirea calitatii traducerii
(performanţelor programului tradus)
▪ Fazele nu sunt neapărat clar separate ci sunt realizate
printr-un ansamblu de funcţii care cooperează
25
21. Analiza lexicală
▪ Automate finite, expresii regulate
▪ Imparte programul in unitati lexicale (atomi
lexicali, tokeni)
❑ Cuvinte cheie
❑ Numere
❑ Nume
▪ Prima decizie stabilirea atomilor lexicali ai
limbajului
26
22. Analiza lexicala
▪ Un atom lexical are
❑ Clasa (cod numeric) folosit in analiza sintactica
❑ Atribute specifice clasei analiza semantica,
generare de cod
▪ De obicei, analizorul lexical are o interfata
simpla
❑ lexer.getNextToken()
27
28. Analizor sintactic al unui program
if x == y then z = 1; else z = 2;
x == y z 1 z 2
atribuire atribuire
operator de relaționare
condiție logică instrucțiune-then instrucțiune-else
instrucțiune-if-then-else
30. Analiza semantică
▪ O mare parte e integrata de obicei in analiza
sintactica
▪ Verificarea corectitudinii semantice a
propozitiilor
❑ In compilatoare verificarea consistentei
programului, verificari de tip
▪ Adnoteaza arborele de derivare cu informatii
semantice (de tip)
❑ Pregateste generarea de cod
35
31. Analiza semnatică
Înțelegerea “sensului” unei propoziții
Sensul este foarte greu pentru compilatoare
Compilatoarele efectuează analize limitate pentru
a găsi incoerențe
32. Analiza semantică – limba română
Exemplu
Andrei a spus că Marian a lăsat tema lui acasă.
◼ La cine se referă “lui”? la Andrei sau la Marian?
Și mai complicat
Andrei a spus că Andrei a lăsat tema lui acasă?
◼ Câți Andrei sunt?
◼ Care și-a lăsat tema acasă?
33. Analiza semantică în programare
Limbajele de
programare definesc
reguli clare pentru a
evita ambiguitatea
Codul C++ afișează 4;
este utilizată
instrucțiunea din
interior
{
int Andrei = 3;
{
int Andrei = 4;
cout<<Andrei;
}
}
34. Analiza semantică
Compilatoarele efectuează multe verificări
semantice pe lângă cele legate de variabile
Exemplu
Andrei a spus că a lăsat tema ei acasă.
Nepotrivire de tip între Andrei și ei
35. Detectarea erorilor
▪ Analiza lexicală - şir care nu corespunde unui
atom lexical
❑ 0x1234ABFG
▪ Analiza sintactica erori legate de structura
instrucţiunilor
❑ int real alfa; alfa;/* corect lexical, nu sintactic
▪ Analiză semantică erori semantice
❑ A=b+c; /*incorect daca b e de tip ‘struct’ */
▪ Recuperarea din eroare - cum continuam analiza
cand am intalnit o eroare
40
36. Generarea de cod intermediar
▪ Uneori, direct in timpul parsarii
❑ Sau prin parcurgerea arborelui de derivare
sintactic
▪ “cod obiect pentru o masina virtuală”
❑ Permite multe optimizari comune pentru diferite
frontend-uri limbaje si backend-uri procesoare
❑ Unele optimizari se pot face si direct pe arbore
41
37. Optimizare
Modificarea automată a programelor astfel încât
acestea să
Ruleze mai rapid
Utilizeze mai puțină memorie
În general, să păstreze anumite resurse
38. Generator de cod
Produce cod în limbaj de asamblare (în general)
Translatare într-un alt limbaj
Asemănător cu traducerea limbajelor
39. Limbaj intermediar
Multe compilatoare efectuează translatări între
forme intermediare succesive
Toate, cu excepția primului și ultimului sunt
considerate limbaje intermediare
De obicei este 1 LI
40. Limbaj intermediar
Proiectarea limbajului are un impact mare asupra
compilatorului
Determină ce este ușor sau greu de compilat
41. Compilatoare în ziua de azi
Structura generală a aproape fiecărui compilator
aderă la schema din curs
Proporțiile s-au modificat de când a fost inventat
FORTRAN
La început: analiza lexicală, sintactică era partea cea
mai complexă, cea mai scumpă
Astăzi: optimizarea domină toate celelalte faze
42. Analizor lexical (Scanner) - Exemplu
a[index] = 4 + 2
conține 12 caractere nealbe și 8 atomi
a identificator
[ paranteză dreaptă
Index identificator
] paranteză dreaptă
= atribuire
4 număr
+ adunare
2 număr
43. Analizor sintactic (Parser)
Analiza sintactică
verifică dacă programul sursă de la intrare este corect
din punct de vedere sintactic
◼ gruparea atomilor în structuri sintactice - arbore sintactic
46. Analizor sintactic (Parser) - Exemplu
Arbore sintactic - a[index] = 4 + 2
Analizoarele sintactice tind sa genereze un arbore
sintactic care este o condensare a arborelui de
derivare
48. Optimizatorul de cod sursă
Modifică arborele sintactic, ori porţiuni din codul intermediar,
astfel încât programul rezultat să îndeplinească unele cerinţe de
performanţă
În cazul nostru compilatorul poate efectua adunarea 4 + 2 și se
obține valoarea 6 - împachetarea constantelor - constant
folding
Se optimizeaza o forma liniara a arborelui
Se poate folosi o variabila temporara t pentru a stoca rezultatul
adunarii
t=4+2 a[index]=t
Optimizatorul imbunatateste acest cod in doi pasi
Efectuând adunarea t = 6 a[index]=t
Înlocuind valoarea lui t: a[index]=6
50. Generatorul de cod - Exemplu
MOV R0, index ;; value of index R0
MUL R0, 2 ;; double value in R0
MOV R1, &a ;; address of a R1
ADD R1, R0 ;; add R0 to R1
MOV *R1, 6 ;; constant 6 address in R1
*R1 – adresare indirecta la registrii - ultima instructiune
stocheaza valoarea 6 la adresa continuta in R1
51. Optimizatorul de cod obiect
MOV R0, index ;; value of index R0
SHL R0 ;; double value in R0
MOV &a[R0], 6 ;; constant 6 address a + R0
52. Limbaje si gramatici
▪ Ce este o gramatica?
▪ Dar un limbaj?
▪ Tipuri de gramatici
▪ Ierarhia Chomsky a gramaticilor
❑ Regulate
❑ Independente de context
❑ Dependente de context
❑ Generice
▪ Unde se incadreaza un limbaj de programare?
57