analiza lexicala

19
Analiza lexicala Analiza lexicala

Upload: flashh

Post on 21-Jun-2015

547 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Analiza lexicala

Analiza lexicala

Analiza lexicala

Page 2: 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.

Page 3: Analiza lexicala

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

Valoare

zona sirurilor

1

beta

Page 4: Analiza lexicala

In mod curent, indicatia (valoarea) este prelucrata spre a servi altor scopuri. De exemplu: pentru fiecare identificator ne intereseaza daca el apare pentru prima data in program, sau ce reprezinta el in general, atributele sale.

In acest scop, compilatorul mentine o zona rezervata pentru Tabela de Simboluri (TS), care este un “dictionar” al tuturor identificatorilor si constantelor din program. In aceasta tabela trebuie cautat identificatorul depistat in sirul de intrare, iar in loc de indicator spre sir, in atomul lexical se plaseaza un indicator spre intrarea din TS corespunzatoare identificatorului.

atom lexical

Clasa

Valoare

Zona sirurilor

1

Nume/ valoare Atribute

beta

Page 5: Analiza lexicala

Construirea unui analizor lexical presupune parcurgerea urmatoarelor etape:Stabilirea simbolurilor de bazaStabilirea 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 decaractere 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.

Page 6: Analiza lexicala

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.

Exemplu: Presupunem ca un limbaj are urmatoarele simboluri de baza:identificatori;constante caractere speciale;succesiuni de caractere speciale;cuvinte cheie.

O reprezentare a gramaticilor pentru aceste simboluri poate fi urmatoarea:

Page 7: Analiza lexicala

indetificator -> litera (litera|cifra)litera →’A’|…|’Z’.cifra →’0’|…|’9’.constante →cifra.caracter_special →’:’| ‘;’.succesiune_caractere_speciale →”:=”| “<>”.cuvant_cheie →’and’|’begin’.Automatele finite corespunzatoare sunt urmatoarele:

lA1 l,c

cA2 c

:A3

;

0 11

0 2

0

3

4

Page 8: Analiza lexicala

=

:

A4

<

>

unde l reprezinta litera iar c cifra.

Pentru a reprezenta analizorul lexical se construieste un automat global pentru recunoasterea simbolurilor de baza ale limbajului. Acesta se realizeaza prin cuplarea celor 4 automate pe starea initiala 0, astfel:

A1 A2

l c

: :

; <

A3 A4

0

5

7

6

8

1

0

2

3

4

=>

5 6

7 8

Page 9: Analiza lexicala

Pentru a extrage simbolul de baza care incepe dupa o pozitie p in sirul de intrare trebuie sa recunoastem si sa stergem caracterele nesemnificative – ca de exemplu spatiile albe (blanc) si comentariile (/* orice sir format din caractere diferite de * si /) – trebuie sa folosim automatul pentru a citi simbolul si sa fixam pozitia finala p’.

Eliminarea caracterelor nesemnificative se poate face astfel:Spatiu alb orice car inafara de * si /

/ * *

/

Analizorul lexical trebuie sa tina seama de urmatoarele cerinte:- pentru fiecare tranzitie intr-o stare finala se introduce o actiune semantica care va codifica corespunzator atomul lexical;- in cazul tuturor tranzitiilor care provin din automatele A1 si A2 se va introduce o actiune care va concatena caracterul curent de la intrare la un sir dat.- in caz de eroare, se va introduce cate o actiune semantica pentru tratarea acesteia.

0 9 10 11

Page 10: Analiza lexicala

Problema rezolvataSa se implementeze un analizor lexical care sa recunoasca:-identificatori;-constante reale;-constante intregi-caracterele speciale ‘:’ si ‘;’-secventa de aractere speciale “:=”-cuvintele cheie “begin”, “end”.

Se vor construi, dupa modelul anterior urmatoarele gramatici:

1. indetificator →litera (litera | cifra)*litera →’a’ | ‘A’ …|’Z’.cifra → ‘0’ |…|’9’.

2.constanta_intreaga → cifra+

3. constanta_reala → cifra+ scara | cifra+ ’.’cifra+ [scara]scara → ‘e’ [‘+’ | ‘-‘] constanta_intreaga.

Se va folosi o structura de date de tip inregistrare care va contine urmatoarele campuri: codul atomului lexical si valoarea sa.

Page 11: Analiza lexicala

Algoritmul in pseudocod:* initializeaza nume=” “ -cat_timp ch este spatiu alb repeta|citeste ch - - daca ch este litera atunci| - repeta| | * adauga caracterul ch la nume| | citeste ch| | pana ch este diferit de litera sau cifra| -| - daca * nume este cuvant cheie atunci| | *codifica corespunzator| | astfel| | * atomul este identificator| -| altfel daca ch este cifra atunci| - repeta| | * adauga caracterul ch la nume| | citeste ch| | pana ch este diferit de cifra| -|

Page 12: Analiza lexicala

|* atomul este constanta intreaga| - daca ch este ‘.’ atunci| | * atomul este constanta reala| | * adauga caracterul la nume| | citeste ch| | - daca ch este cifra atunci| | - repeta| | | | * adauga caracterul ch la nume| | | | citeste ch| | | | pana ch este diferit de cifra| | | -| | -| -| - daca ch este ‘e’ sau ‘E’ atunci| | * atomul este constanta reala| | * adauga caracterul la nume| | citeste ch| | - daca ch este ‘+’ sau ‘-‘ atunci| | | * adauga semnul in nume| | | citeste ch| | -

Page 13: Analiza lexicala

| | - daca ch este cifra atunci| | | - repeat| | | | * adauga caracterul ch la nume| | | | citeste ch| | | | pana ch este diferit de cifra| | | -| | -| -| altfel daca ch este ‘:’ atunci| * adauga ch la nume| citeste ch| - daca ch este ‘=’ atunci| | * secventa “:=”| | citeste ch| | altfel| | * Caracterul special ‘:’| -| altfel daca ch este ‘;’ | * Caracterul special ‘;’| citeste ch| altfel| * atom necunoscut| citeste ch -

Page 14: Analiza lexicala

Programul C este:#include <stdio.h>#include <string.h>#include <ctype.h>#include <conio.h>#include <stdlib.h>#define dim 25

typedef enum {cid,cint,creal,cdpct,cpv,catrib,cbegin,cend,cbad,ceof }tipAtom ;struct {tipAtom cod; char nume[dim]; } atom;FILE *f;int ch;

void Adauga(int *k){if(*k < dim-1) {

atom.nume[*k]=ch;atom.nume[*k+1]=0;(*k)++;

}}void Analex(void){

static int k;/*Initializare atom */

atom.cod=cbad;atom.nume[0]=0;/*Elimina spatiile*/while(isspace(ch)) ch=getc(f);/*Daca este litera */

Page 15: Analiza lexicala

if(isalpha(ch)){k=0;Adauga(&k);ch=getc(f);while(isalnum(ch)){

Adauga(&k);ch=getc(f);

}if(!strcmp(atom.nume,"begin"))

atom.cod=cbegin;else

if(!strcmp(atom.nume,"end")) atom.cod=cend;

else atom.cod=cid;

}/*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 */

Page 16: Analiza lexicala

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));

} }

Page 17: Analiza lexicala

} /*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 */}

}

Page 18: Analiza lexicala

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;

}

Page 19: Analiza lexicala

Modelul analizorului lexicalSintaxa 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.