29.06.2013 Views

Analiza lexicala [pdf] - Andrei

Analiza lexicala [pdf] - Andrei

Analiza lexicala [pdf] - Andrei

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Analiza</strong> Lexicala


Introducere<br />

LEX – program pentru constructia<br />

automata a analizoarelor lexicale<br />

<strong>Analiza</strong> Lexicala = detectarea de atomi<br />

lexicali (tokeni)<br />

Analizor Lexical<br />

Analizor Lexical<br />

folosit ca atare (pentru dezvoltarea de aplicatii<br />

care necesita doar detectare de atomi lexicali)<br />

folosit pentru detectarea atomilor lexicali ce<br />

vor reprezenta intrarea unui Analizor Sintactic


Introducere (2)<br />

Analizor<br />

lexical<br />

TOKEN(name,val)<br />

getToken()<br />

tabela<br />

De<br />

simboli<br />

Parser


Introducere (3)<br />

scrierea unei specificatii LEX este<br />

echivalenta cu scrierea unui set de<br />

modele pe care analizorul generat va<br />

incerca sa le gaseasca pe sirul de<br />

intrare<br />

OBSERVATIE: un analizor lexical<br />

scris cu ajutorul LEX este aproape<br />

sigur mai rapid decat un analizor<br />

lexical scris “de mana”<br />

scanner.l<br />

flex<br />

lex.yy.c<br />

CC<br />

lex.yy.o<br />

LD<br />

scanner<br />

Specificatie<br />

LEX<br />

Cod C<br />

generat<br />

Binar<br />

Optimizat<br />

libfl.a<br />

Cod<br />

Executabil


Expresii Regulate<br />

Expresie Regulata – descriere de<br />

model folosind un metalimbaj<br />

. orice caracter in afara de \n<br />

* zero sau mai multe copii ale expresiei precedente<br />

+ una sau mai multe copii ale expresiei precedente<br />

[] un caracter din multimea de caractere definita intre []<br />

[0-9] un caracter din multimea de toate caracterele dintre limite<br />

[^…] un caracter care nu este in multimea de caractere definita<br />

intre []


Expresii Regulate (2)<br />

? zero sau mai multe aparitii ale expresiei precedente<br />

| specificarea unei alternative<br />

^ inceput de linie (ca prim caracter intr-o ER)<br />

$ sfarsit de linie (ca ultim caracter intr-o ER)<br />

{N} indica de cate ori poate sa apara expresia precedenta (numar fix)<br />

{N}<br />

{N, M} indica de cate ori poate sa apara expresia precedenta (intre N<br />

si M ori)<br />

/ detecteaza un sir care se potriveste cu expresia care precede /, dar<br />

numai cand este succedata de expresia care urmeaza dupa / (fara a<br />

avansa consumarea intrarii)<br />

() grupeaza o serie de expresii intr-o noua expresie<br />

()


Exemple Expresii Regulate<br />

[0-9]<br />

[0-9]+<br />

[0-9]*<br />

-?[0-9]+<br />

-?(([0-9]+)|([0-9]*\.[0-9]+))<br />

^[ \t]*\n<br />

^[ \t]*”/*”.*”*/”[ \t]*\n<br />

o cifra<br />

un numar natural cu cel putin o<br />

cifra<br />

un numar sau sirul vid<br />

un numar intreg (poatea avea<br />

semn)<br />

un numar zecimal cu semn<br />

descrierea unei linii goale (doar<br />

spatii si taburi)<br />

descrierea unei linii care incepe<br />

si se termina cu un comentariu


Structura unei Specificatii<br />

LEX<br />

3 sectiuni<br />

1. sectiune de definitii<br />

2. sectiune de reguli<br />

3. sectiune de rutine<br />

1<br />

2<br />

3<br />

%{<br />

#include <br />

%}<br />

DIGIT [0-9]<br />

ID [a-z][a-z0-9]*<br />

%%<br />

{DIGIT}+ printf( "An integer”);<br />

%%<br />

int main(void)<br />

{<br />

yyin = fopen( "f.in", "r");<br />

yylex();<br />

}


Sectiunea de Definitii<br />

poate contine orice secventa de cod C<br />

ce se doreste copiata ca atare in<br />

programul final (aceaste secvente sunt<br />

delimitate de “%{“ si “%}”)<br />

aceasa sectiune mai poate contine de<br />

asemenea definitii (ce vor fi folosite<br />

apoi in sectiunea de reguli) sau<br />

declaratii de stari


Exemplu sectiune de<br />

definitii<br />

%{ unsigned charCount = 0;<br />

unsigned wordCount = 0;<br />

unsigned lineCount = 0;<br />

%}<br />

word [^ \t\n]+<br />

eol \n<br />

%x COMMENT


Sectiune de Reguli<br />

fiecare regula formata din MODEL si<br />

ACTIUNE (separate prin spatii)<br />

Programul generat de LEX va executa<br />

ACTIUNEA de fiecare data cand va detecta<br />

MODELUL asociat<br />

MODELELE sunt specificate prin expresii<br />

regulate<br />

sectiunea de reguli este delimitata de<br />

caracterele “%%”


Exemplu sectiunea de<br />

reguli<br />

%%<br />

[ \t]+ ; /* se ignora spatiile goale */<br />

[a-zA-Z]+ {printf(“Acesta este un cuvant %s\n”, yytext);}<br />

-?(([0-9]+)|([0-9]*\.[0-9]+)) {printf(“Acesta este un numar %s\n”,<br />

yytext);}<br />

.|\n ECHO; /* este oricum actiunea implicita */<br />

%%


Sectiunea de Rutine<br />

contine orice secventa de cod C<br />

trebuie sa contina apelul catre<br />

analizorul lexical yylex()<br />

poate folosi sau redefini<br />

variabile/functii/macrouri ce sunt<br />

generate de LEX in fisierul final


Exemplu sectiune de rutine<br />

int main( int argc, char * argv[] )<br />

{<br />

if( argc > 1 )<br />

{<br />

FILE * file;<br />

file = fopen( argv[1], "r" );<br />

if( !file )<br />

{<br />

fprintf( stderr, "Could not open %s\n",argv[1]);<br />

exit(1);<br />

}<br />

yyin = file;<br />

}<br />

yylex();<br />

return 0;<br />

}


Reguli<br />

intr-un text ce contine o specificatie LEX<br />

fiecare linie va trebui sa inceapa din coloana<br />

intii<br />

LEX executa actiunea asociata celui mai<br />

lung model posibil<br />

Atunci cand se poate alege intre doua<br />

modele la fel de lungi, se alege intotdeauna<br />

cel care a fost specificat primul in sectiunea<br />

de definitii


Stari LEX<br />

se pot crea stari (start conditions)<br />

rolul lor este de a descrie informatiile<br />

dependente de context intr-o specificatie<br />

LEX<br />

precedarea unei reguli de o stare anunta<br />

analizorul ca regula se aplica doar cand<br />

analizorul este in starea respectiva<br />

Pot fi inclusive sau exclusive<br />

restul regulilor sunt valabile in toate celelalte<br />

stari (mai putin in starile exclusive)


Exemplu Stari<br />

%s MAGIC<br />

%%<br />

.+ { BEGIN INITIAL;<br />

printf("Magic:");ECHO; }<br />

magic BEGIN MAGIC;<br />

%%<br />

void main(){ yylex(); }


Tot despre stari<br />

identifica orice stare<br />

YY_START : intoarce un intreg<br />

(valoarea interna a starii curente)<br />

Sunt disponibile rutine pentru accesul<br />

la stiva de stari (yy_push_state, etc.)


Variabile accesibile<br />

utilizatorului<br />

char *yytext : textul pentru tokenul<br />

curent<br />

int yyleng : lungimea tokenului curent<br />

FILE *yyin : fisierul de intrare<br />

FILE *yyout : fisierul in care scrie<br />

ECHO


Alte macro-uri si rutine<br />

accesibile utilizatorului<br />

ECHO<br />

REJECT<br />

yymore()<br />

yyless(n)<br />

yywrap()


Lucrul cu mai multe buffere<br />

de intrare<br />

yy_create_buffer<br />

yy_switch_to_buffer<br />

yy_delete_buffer<br />

yy_scan_string


Exemple Complete/<br />

Mai multe informatii<br />

Documentatia online<br />

http://cs.pub.ro/~pt/<br />

A. Aho, R. Sethi, J.D.Ullman –<br />

Compilers, Techniques and Tools<br />

(cartea cu dragon)


Expresii regulate in Java


java.util.regex<br />

Pattern<br />

Matcher<br />

PatternSyntaxException


Exemplu<br />

import java.util.regex.*;<br />

public class RegEx {<br />

public static void main(String args[]) {<br />

String myRegex = "abc*";<br />

Pattern pattern = Pattern.compile(myRegex);<br />

Matcher matcher = pattern.matcher("abccabcabccc");<br />

while (matcher.find()) {<br />

System.out.println("Found it : " + matcher.group());<br />

}<br />

}<br />

}


Cuantificatori<br />

Greedy<br />

Reluctant<br />

Posessive


Cuantificatori (2)<br />

xfooxxxxxxfoo<br />

Greedy: *.foo => xfooxxxxxxfoo<br />

Reluctant: *?.foo => xfoo<br />

Posessive: *+.foo =>


Documentatie<br />

http://java.sun.com/docs/books/tutorial/essential/regex/intro.html


Exercitii<br />

Pentru un fisier text, afisati toate liniile<br />

de text precedate de numarul liniei<br />

Scrieti un scurt program similar ca<br />

functionalitate cu utilitarul Linux ‘wc’<br />

Dezvoltati exemplul anterior: daca<br />

fisierul-sursa contine comentarii (stil C<br />

sau C++ -- /* …*/ sau // …), continutul<br />

comentariilor se va ignora in calculul<br />

statisticilor.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!