Documente Academic
Documente Profesional
Documente Cultură
Analiza lexicala
Analiza lexicala transforma programul sursa, vazut ca un sir de caractere, intr-un
sir de simboluri numite atomi lexicali (tokeus). In momentul in care o secventa de
caractere a fost identificata ca o aparitie a unui simbol de baza, analizorul lexical va
crea un atom lexical care sa o descrie.
De exemplu, daca consideram ca reprezentari posibile pentru operatorul relational
“mai mic” pe “<”, “LESS” si “LT”, toate trei vor conduce la crearea aceluiasi atom
lexical.
Un atom lexical poate fi privit ca un reprezentant al unei clase de siruri de caractere
cu reguli de formare precise.
In majoritatea limbajelor de programare, drept clase vom gasi:
- clasa identif.
- clasa constante intregi
- clasa constante reale
- clasa operatorilor.
Clasele sunt pentru o anumita implementare, multimi finite. Totusi, daca in
clasa operatorilor intra de obicei putini operatori (10 – 20), in clasa identificatorilor
sau constantelor vom gasi un numar reletiv mare de elemente, de cele mai multe
ori limitarae aparand in urma implementarii si nu datorita definitiei limbajului.
Sarcina analizorului lexical (scanner) este sa detecteze in sirul de
caractere al PS, subsiruri ce respecta regulile de formare ale atomilor lexicali, sa
clasifice aceste subsiruri si sa le traduca in atomi lexicali, adica in informatii
codificate ce vor pastra esentialul : clasa fiecarui subsir si eventual, modul de
regasire al subsirului. De exemplu, in cazul unui subsir clasificat ca identificator,
atomul lexical va contine un cod numeric, sa zicem 1, reprezentand clasa si un
indicator spre zona in care se gaseste memorat sirul de caractere.
atom lexical
Clasa
1
Valoare
beta
Zona sirurilor
Construirea unui analizor lexical presupune parcurgerea urmatoarelor etape:
Stabilirea simbolurilor de baza
Stabilirea modului de recunoastere, extragere si reprezentare a simbolurilor de baza.
Stabilirea modului de tratare a erorilor.
Proiectarea atomului finit pentru fiecare symbol de baza.
Implementarea analizorului lexical.
Delimitatorii (cuvintele cheie, caracterele speciale precum si combinatiile de
caractere speciale) impreuna cu identificatorii si constantele reprezinta simbolurile de
baza ale unui program sursa. Reprezentarea si structura acestor simboluri de
baza poate fi modificata fara a altera puterea de exprimare a limbajului.
De regula, pornind de la simbolurile de baza pot fi construite automate finite care
sa le accepte.
Sarcina unui analizor lexical este sa extraga urmatorul sibol de baza din textul de
intrare, determinand sfarsitul simbolului in timpul cautarii.
Pentru exemplificare sa consideram caracterul “:” care in limbajul Pascal este un
simbol de baza, nefiind inceputul unui alt simbol de baza. In momentul in care un
analizor Pascal ajunge in starea finala corespunzatoare acestuia se poate opri si
poate accepta simbolul. In acest caz s-a depistat sfarsitul sirului iar in capul de
citire a benzii de intrare este pozitionat pe urmatorul caracter.
Caracterul “:” este de asemenea un simbol de baza Pascal, dar este
inceputul simbolului “:=”. De aceea, analizorul trebuie sa avanseze dincolo de el
pentru a vedea ce urmeaza. Automatul trebuie deci sa retina informatii
referitoare la cea mai recenta stare finala intalnita, asigurandu-se astel o pozitie
de intoarcere. Daca atomul se opreste intr-o stare finala, procesul de obtinere a
unui nou simbol de baza se incheie. In caz contrar, se reface textul de la intrare
in pozitia ultimei stari finale intalnite. Se semnaleaza eroare lexicala doar in cazul
in care nu s-a trecut printr-o stare finala in timpul parcurgerii sirului.
Proiectarea automatului finit pentru determinarea unui anumit simbol de
baza (atom lexical) presupune determinarea starilor automatului, a alfabetului de
intrare si a functiei de tranzitie. Pentru reprezentare se pot folosi diagramele de
tranzitie.
c
A2 0 c
2
: 3
A3
0
;
4
=
: 5 6
A4 0
< 7
8
>
}
/*Daca este cifra */
else
if(isdigit(ch)){
k=0;
do{
Adauga(&k);
ch=getc(f);
}while(isdigit(ch));
/*Atomul este constanta intreaga */
atom.cod=cint;
/*Retine partea fractionara */
if(ch=='.'){
/*Atomul este constanta reala */
atom.cod=creal;
Adauga(&k);
ch=getc(f);
if(isdigit(ch)){
do{
Adauga(&k);
ch=getc(f);
}while(isdigit(ch));
}
}
/*Retine exponentul */
if(ch=='e' || ch=='E'){
/*Atomul este constanta reala */
atom.cod=creal;
Adauga(&k);
ch=getc(f);
if(ch=='+' || ch=='-'){
Adauga(&k);
ch=getc(f);
}
if(isdigit(ch)){
do{
Adauga(&k);
ch=getc(f);
}while(isdigit(ch));
}
}
} /*Daca este doua puncte*/
else
if(ch==':'){
k=0;
Adauga(&k);
atom.cod=cdpct;
ch=getc(f);
if(ch=='='){
Adauga(&k);
atom.cod=catrib;
ch=getc(f);
}
} /*Daca este punct si virgula */
else
if(ch==';'){
k=0;
Adauga(&k);
atom.cod=cpv;
ch=getc(f);
}/*Daca este sfarsit de fisier */
else
if(ch==-1) atom.cod=ceof;
else{ /*Este caracter ilegal */
atom.cod=cbad;
atom.nume[0]=ch;
atom.nume[1]=0;
ch=getc(f);/*Avanseaza la urmatorul
caracter */
}
}
int main(void){
char fisier[17];
// clrscr();
printf("\nDati numele fisierului care se analizeaza ");
scanf("%s",fisier);
if((f=fopen(fisier,"rt"))==NULL){
fprintf(stderr,"Cannot open input file \n");
exit(1);
}
ch=' ';
printf("%5s %-15s\n","*COD*","*NUME*******");
for(;atom.cod !=ceof;){
Analex();
printf("%5d %-15s\n",atom.cod,atom.nume);
}
return 0;
}
Modelul analizorului lexical
Sintaxa atomilor lexicali se prezinta sub forma unei gramatici regulate sau a unui
GIC care genereaza un limbaj regulat. In acest din urma caz exista metode simple de a
transforma gramatica intr-o gramatica regulata echivalenta. In general, restrictia impusa GIC
pentru a putea fi transformata, este ca niciun neterminal sa nu fie autocontinut, adica:
pentru orice A, A Э N, A →+ α A β → [(α = λ sau β = λ]
O solutie simpla pentru a obtine aceasta conditie este ca in productiile gramaticii
sa se foloseasca, daca este posibil, numai un tip de recursivitate: la stanga sau la dreapta.
Odata stabilit tipul atomilor lexicali si avand o gramatica pentru acest limbaj,
problema analizei lexicale apare, in primul rand, ca o problema de decizie: sa stabileasca
despre sirul de caractere daca este sau nu atom lexical. Pentru a vea imaginea completa,
problema de decizie trebuie, in continuare, completata cu problema codificarii atomilor
lexicali si cu probelma semnalarii si tratarii erorilor.
In diferite faze ale compilarii exista sarcini comune ale tratarii erorilor. De aceea,
se obisnuieste ca toate aspectele legate de tratarea erorilor sa se rezolve printr-o colectie
proceduri comune tuturor fazelor. Se va pune in evidenta modul in care se face detectarea
erorilor in analizorul lexical.
In cazul unui limbaj regulat, instrumentul matematic, modulul formal folosit in
conceperea cuvintelor din limbaj este automatul finit, iar problema apartenentei la un limbaj
este decidabila.
Automatul finit poate fi considerat modelul de baza al analizorului lexical. Modelul
va fi completat in momentul proiectarii cu alte facilitati pentru a raspunde ami bine nevoilor
analizei lexicale, in primul rand necesitatii de generare a atomilor lexicali.