Analiza lexicala [pdf] - Andrei
Analiza lexicala [pdf] - Andrei
Analiza lexicala [pdf] - Andrei
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.