Documente Academic
Documente Profesional
Documente Cultură
10
11
Universul
calculatorului
Universul
problemei
Simulare
Elaborare
program
Compilare
Universul limbajului
de programare
Figura 1.
12
13
Compilator
Interpretor
asamblor
Microprocesor
Cod masina
Figura 2.
Limbajul sau codul main reprezint un limbaj binar cu care lucreaz efectiv
procesorul. De obicei, fiecare procesor are propriul su cod main, definit fizic
de constructorul procesorului. Codul main aparine primei generaii de
limbaje de programare.
Limbajele de asamblare sau macroasamblare se situeaz deasupra codului
main i sunt formate prin coresponden direct ntre succesiuni binare i
termeni (eventual prescurtai) din vorbire. Limbajele de asamblare fac parte din
generaia 2-a de limbaje de programare.
Programele scrise n cod main sau limbaje de asamblare pot fi considerate
optimale pentru calculator, deoarece acesta poate s execute n mod direct,
fr o alt conversie un asemenea cod. Dezavantajele principale ale acestora
rezid n dificultatea acestor limbaje. Productivitatea activitii de programare
este foarte sczut. Limbajele din primele dou generaii sunt specifice pe
procesor, adic gradul lor de portabilitate este foarte sczut. Prin portabilitate
se nelege caracteristica unui program de a putea fi rulat pe diverse
calculatoare (sau tipuri de calculatoare) fr modificri, sau cu modificri
minimale.
Limbajele de nivel superior aparin generaiilor 3-a, 4-a i 5-a de limbaje de
programare. Aceste limbaje se apropie tot mai mult de nelegerea uman, de
reprezentri specifice n termenii problemei de rezolvat.
Limbajele de generaia 3 conin limbaje pentru prelucrarea datelor neorganizate
n baze de date. Ele sunt limbaje de uz general, respectiv de programare
automat. Aceste limbaje permit programatorului s exprime rezolvarea
problemei ntr-un limbaj mai apropiat de limbajul natural. Includem n aceast
categorie limbaje precum Fortran, C/C++, Pascal etc.
14
15
Traducerea n dou faze presupune traducerea codului din cod surs ntr-un
cod intermediar care apoi este rulat pe o main virtual. Limbajele care
funcioneaz pe acest principiu se numesc limbaje pseudo-compilative.
Exemple de limbaje pseudo-compilative sunt Java i limbajele din familia .NET.
16
17
prin care o clas este caz particular (specializat) al unei superclase. Astfel, prin
compoziie i motenire se asigur reutilizarea codului.
Principalul avantaj al programrii obiectuale fa de paradigmele anterioare
este realizarea polimorfismului. Prin polimorfism se nelege proprietatea unui
nume de a fi utilizat cu nelesuri diferite. Cea mai important form de
polimorfism este polimorfismul de tip, prin care tipul referinei se adapteaz la
tipul obiectului.
Smalltalk este limbajul care a introdus paradigma obiectual. Acest limbaj a
fost dezvoltat n limbajele Smalltalk80 i Smalltalk86. C++ reprezint extensia
obiectual a limbajului structurat C. De asemenea Java implementeaz
caracteristicile paradigmei obiectuale.
18
19
An
1957-si
Autori
Predecesor
J. Backus
(IBM)
Algol60
1960-s
Comitet
Cobol
1960-s
DOD
Scop
Calcule numerice
Fortran
Calcule numerice
Prelucrri de date
economice
20
APL
1960-si
K. Iverson
(Harvard)
Prelucrri de tablouri
Lisp
1962
J. McCarthy
(MIT)
Prelucrri de liste
Snobol
1966-si
R. Griswold
(Bell)
Prelucrri de iruri de
caractere
PL/1
1964-s
IBM
Fortran,
Algol60, Cobol
Uz general
Simula67
1967
O.J. Dahl
Algol60
Simulare
Algol68
1968-s
Comitet
Algol60
Uz general
Pascal
1971
N. Wirth (ETH
Zurich)
Algol60
Uz general, scop
educaional
Prolog
1972
Univ. Marsilia
1974
D. Ritchie
(Bell)
Algol60, BCPL
Programare de sistem
Concurrent
Pascal
1975
P.B. Hansen
(CalTech)
Pascal
Programare concurent
Euclid
1977
Comitet
Pascal
Programare de sistem
verificabil
Modula
1977
N. Wirth
Pascal
Programare de sistem n
timp real
Ada
1979
J. Ichbiah (CIIBull)
Pascal,
Simula67
Smalltalk
1980
Xerox PARC
Simula67
Programare orientat
obiect
C++
1984
B. Stroustrup
Programare orientat
obiect
Oberon
1987
N. Wirth
Pascal,
Modula
Programare orientat
obiect
Modula-3
1988
DEC, Olivetti
Modula
Java
1995
Sun
Tabelul 1.
Programare logic
n 1944 maina numit Mark I realizat de IBM a fost primul calculator capabil
s execute o secven lung de operaii aritmetice i logice. n 1946 ENIAC
(Electronic Numerical Integrator And Calculator) devine predecesorul primei
generaii de calculatoare.
21
Algol60
1960
Cobol
Lisp
CPL
PL/1
BCPL
Simula67
Algol68
Pascal
1970
Prolog
C
Modula-2
Ada
C cu clase
1980
Smalltalk
Objective
C
ANSI C
C++
Modula-3
1990
Ada9X
Figura 3.
22
Instructiuni
iesiri
Date
Figura 4.
23
24
25
26
4.
5.
6.
Capitolul 2.
Fundamentele limbajelor de programare
n acest capitol vom introduce aspectele formale ale limbajelor de programare.
Astfel, vom defini limbajele abstracte, ca i fundament pentru dezvoltarea
tehnicilor de parsare i a compilatoarelor. Seciunea 2-a a capitolului va
prezenta paii i operaiile pe care le suport un cod surs pentru a fi
transformat n cod main, prin operaia de compilare.
2.1.1. Gramatici
Fie o mulime
A*
A*
A*
A*
A.
A . Simbolurile se
A*.
A*
din
atunci irul
z = xy ,
y,
va fi de
cu simbolurile din
A*
din
nzestrat cu operaia
A*.
este o submulime
a lui
28
i mulimea
P ( A*)
a prilor mulimii
A * , pe aceast
L1 L2
a.
intersecie:
b.
reuniune:
c.
complementare:
d.
produs:
e.
stea:
f.
L1 L2
L = {x A* | x L}
L* = {} L L2 ... Ln ...
~ ~
~
reflectare: L = {x | x L} unde x este imaginea reflectat a lui x
x A * , dac se
x L sau x L .
poate
alfabetul sistemului
F A*
S =< A, F ,, R >
29
R . O regul de deducie
n
de aritate n + 1 este o relaie din mulimea F F , care asociaz o
formul unic x cu un n-tuplu y =< y1 , y 2 ,..., y n > . Spunem c x se
mulimea finit a regulilor de deducie (inferen)
deduce din
Fie
y1 , y 2 ,..., y n
formulele
i scriem
y1 , y 2 ,..., y n ,
corecte
E0 .
yRx .
numite
premise.
Fie
Ei = Ei 1 U{x | y E ,
n
i 1 astfel incat
n 1
E0 =
yRx} .
Ei
se
Ei .
x.
alfabetul
disjuncte
de simboluri terminale.
b.
c.
d.
Acest
simbol se numete simbol de nceput.
Regulile de deducii au la baz producii: O producie este o pereche
( , )
de formule, notat cu
unde
P Q P Q
se poate nlocui
cu
i se obine tot o
G =< N , , P, S >
se numete gramatic.
din
deriveaz imediat n
din
i o
30
producie
= 1 2
astfel nct
= 1 2 .
O asemenea
prin k derivri.
L(G ) = {x}
cu proprietatea c
deriv general pe
x.
4.
31
32
2.1.2.2. EBNF
De multe ori, specificarea BNF este greoaie din punct de vedere al lizibilitii,
mai ales atunci cnd un simbol neterminal se poate repeta, de un numr finit
sau infinit de ori, ntr-o construcie. De exemplu, putem considera definirea unui
string ca fiind un ir de una sau mai multe cifre:
<string>::=<digit>|<digit><string>
n BNF
sau
<number>=[<sign>]<unsigned>
n EBNF
33
<sentence>::=<expression>=
<expression>::=<number>[<operator><expression>]
<number>::=[<sign>]<unsigned>
<operator>::=*|+|-|/
<sign>::=+|<unsigned>::=<string>[.<string>]|.<string>
<string>::=<digit>{<digit>}
<digit>::=0|1|2|3|4|5|6|7|8|9
<expression>
<digit>
0
1
2
3
4
5
6
7
8
9
<string>
Figura 5.
<digit>
Diagrame de sintax.
sau nu?
34
Asemenea automate sunt definite prin grafuri. Nodurile grafului reprezint stri
ale automatului, iar arcele reprezint tranziii ntre stri. Arcele sunt marcate cu
condiii, cu semnificaia c, dac automatul se afl ntr-o anumit stare, i se
ndeplinete condiia de pe un arc care iese din starea respectiv, atunci
automatul va trece n starea de la cellalt capt al arcului selectat.
Automatele pot fi:
deterministe, dac dintr-o stare se poate realiza cel mult o singur micare
nedeterministe, dac dintr-o stare exist mai multe micri posibile.
Automatele nedeterministe corespund gramaticilor cu producii cu
alternative.
Un ir x este acceptat de un automat U dac, pornind de la configuraia
iniial, prin micrile automatului se parcurge ntregul ir de intrare i
automatul ajunge ntr-o configuraie final.
Pentru exemplificare, vom considera automatul finit din figura 6.
b
a
a
q0
q1
Figura 6.
Astfel, automatul din figura 6 are 2 stri: q0 i q1. q0 reprezint starea iniial,
q1 reprezint starea final. Dac, pe banda de intrare se ntlnete irul a i
automatul este n starea q0, atunci automatul trece n starea q1. Dac pe
banda de intrare se ntlnete irul b i automatul este n starea q0, atunci
automatul rmne n aceeai stare etc. Tabelul 2 prezint matricea de definire
corespunztoare acestui automat.
a
b
Tabelul 2.
q0
q1
q0
q1
q1
q0
(q1,aba)
(q1,ba)
(q0,a)
(q1, )
Deci, pornindu-se din starea iniial q0, se parcurge irul de intrare i n final, la
epuizarea acestuia, se ajunge n starea final q1, cu irul vid
35
care reprezint
a
a
2
a
Figura 7.
Tabelul 3.
{0,1}
{2}
{2,3}
{2}
{3}
Q.
astfel:
Q1
pe aceeai
36
Procedure AFN2AFD
Q1 {q0 }
while (mai exist stri nemarcate n
Q1
nemarcat din
Q1
End for
q ' { p | p = ( M , )}
if
q ' Q1
Q1 Q1 {q '}
end if
La mulimea de tranziii a automatului determinist adaug
tranziia q
end for
end while
end procedure
q'
Figura 8.
Transformarea unui automat finit nedeterminist ntr-un
automat determinist echivalent din punct de vedere al limbajului
acceptat
n algoritmul din figura 8 s-au realizat urmtoarele notaii:
-
q0
q0
este nchiderea
(q, a )
q0
37
este nodul 0. nchiderea tranzitiv a acestui nod conine
nodul 0 mpreun cu toate nodurile n care se poate ajunge din acest nod
considernd doar tranziii vide. Deci
q0
q0
M = {0,1,2} .
Considerm
q'
. Extindem mulimea
q ' = [0,1,2] .
n automatul
q0
n nodul
q ' . Continum algoritmul prin considerarea celui de-al doilea simbol de intrare,
b. Considernd toate nodurile care urmeaz din noduri ale lui
dezvolta mulimea
M = {3} .
q0
prin b, vom
este mulimea
vid. Deci, vom aduga starea mulime vid n automatul determinist i vom
lega aceast stare de starea iniial prin tranziia pe simbolul de intrare b.
Continum algoritmul prin marcarea unei noi stri,
[0,1,2] ,
i reluarea
38
a
[2]
a
a
b
[2,3]
[0,1,2]
[0,2]
[3]
b
a,b
[0]
Figura 9.
2.2. Compilatoare
n procesul de comunicare om-calculator intervine un program intermediar,
translatorul, care asigur traducerea programelor scrise de utilizator din cod
surs ntr-un alt limbaj mai apropiat de calculator. Dac limbajul int este codul
main, translatorul se numete compilator. Astfel, execuia unui program
surs se realizeaz, n cadrul limbajelor compilative, n 2 faze:
compilare, care traduce codul surs n program obiect
execuie, care ruleaz codul obiect pe calculator, folosind datele iniiale ale
programului i produce rezultate
Compilatorul unui limbaj de asamblare se numete asamblor.
n practic, pe lng compilatoarele obinuite, exist i alte tipuri de
compilatoare.
Astfel, preprocesoarele sunt translatoare care traduc dintr-un limbaj de nivel
nalt n alt limbaj de nivel nalt. Preprocesorul limbajului C++ reprezint un bun
exemplu.
2.2. Compilatoare
39
Sir de atomi
lexicali
Analiza
lexicala
Arbore
sintactic
Analiza
sintactica
Tratarea
erorilor
Figura 10.
Cod
intermediar
Analiza
semantica
Cod intermediar
optimizat
Optimizare
de cod
Program
obiect
Generare de
cod
Gestiunea
tabelelor
40
4.
5.
41
<expression>::=<number>{<operator><expression>}
<sentence>::=<number>{<operator><sentence>}=
<number>::={<sin>}<unsigned>