Sunteți pe pagina 1din 26

Curs 8

Limbaje de tipul 3
Gramatici regulate
Automate finite
Deterministe
Nedeterministe

Expresii regulate
a, a , ,
E1.E2, E1|E2, E1*, (E1)

Istoric
Paii compilrii
Analiza lexical

Descriere lexical
Interpretare
Interpretare orientat dreapta
Descriere lexical bine format

Lex

1957 Fortran: primul compilator (expresii


aritmetice, instruciuni, proceduri)
1960 Algol: prima utilizare a definiiilor formale
(gramatici, BNF, structura de bloc, recursie)
1970 Pascal: tipuri utilizator, maini virtuale (Pcode)
1972 C: variabilele dinamice, multitasking,
gestionarea ntreruperilor
1983 ADA: primul limbaj standardizat
1985 C++: orientare-obiect, excepii, templateuri
1995 Java: just-in-time compilation
2000 C#: Tehnologia .NET

Uniti
lexicale

Caractere
Cod
surs

Analizor
lexical

Arbore
sintactic
Analizor
sintactic

Analizor
semantic

Arbore
sintactic
decorat
Generator
de cod
Cod main

Asamblare

Cod
intermediar

Interpretare

Def. 1 Fie un alfabet (al unui limbaj de


programare). O descriere lexical peste este o
expresie regulat E = (E1| E2|| En)+, unde n este
numrul unitilor lexicale, iar Ei descrie o unitate
lexical, 1 i n.
Def. 2 Fie E o descriere lexical peste ce
conine n uniti lexicale i w +. Cuvntul w
este corect relativ la descrierea E dac w L(E). O
interpretare a cuvntului w L(E) este o secven
de perechi (u1, k1), (u2, k2), , (um, km), unde w =
u1u2um, ui L(Eki) 1 i m, 1 ki n.

w = alpha := beta = 542


Interpretri ale cuvntului w:
(alpha, Id), (:=, Asignare), (beta, Id), (=, Egal), (542,
Intreg)
(alp, Id), (ha, Id), (:=, Asignare), (beta, Id), (=,
Egal), (542, Intreg)
(alpha, Id), (:, Dp), ( =, Egal), (beta, Id), (=, Egal),
(542, Intreg)

Def. 3 Fie E o descriere lexical peste i w


L(E). O interpretare a cuvntului w, (u1, k1)(u2, k2),
(um, km), este interpretare drept -orientat dac
( i) 1 i m, are loc:
|ui| = max{|v|, v L(E1| E2|| En) Pref(uiui+1um)}.
(unde Pref(w) este mulimea prefixelor cuvntului w ).

Exist descrieri lexicale E n care nu orice cuvnt


din L(E) admite o interpretare drept-orientat.
E = (a | ab | bc)+ i w = abc.

Def. 4 O descriere lexical E este bine -format


dac orice cuvnt w din limbajul L(E) are exact o
interpretare drept-orientat.
Teorem Dat o descriere lexical E este
decidabil dac E este bine format
Def. 5 Fie E o descriere lexical bine format
peste . Un analizor lexical (scanner) pentru E
este un program ce recunoate limbajul L(E) i
produce, pentru fiecare w L(E), interpretarea sa
drept-orientat.

Fie o descriere lexical E peste . Crearea


unui analizor lexical pentru E inseamn:
1. Se construiete automatul finit echivalent A
2. Ain A se obine automatul determinist echivalent
cu E, fie acesta A.
3. (Opional) Automatul minimal echivalent cu A.
4. Implementarea automatului A.

Fie descrierea lexical:

litera a | b ||z
cifra 0 | 1 || 9
identificator litera (litera| cifra)*
semn + | numar (semn | ) cifra+
operator + | -| * | / | < | > | <= | >= | < >
asignare :=
doua_puncte :
cuvinte_rezervate if| then|else
paranteze ) | (

Ai
An
Ao
q0

Aa
Ad
Ac
Ap

liter, cifr
liter

1
cifr

cifr

cifr

#o

operator {+,-}

#o

:
5

#n

+,-

),(

#i sau #c

6
7

#a

#d
#p

Bell Laboratories 1975 M.E. Lesk i E. Schmidt


Standard n UNIX ncepnd cu versiunea a 7-a
Variante:
FLEX (Fast LEXical Analyzer Generator)
http://flex.sourceforge.net/
PCLEX lansat de Abraxax Software Inc. (Windows)
YooLex (Yet another Object-Oriented Lex)
http://yoolex.sourceforge.net/
Flex++: http://www.kohsuke.org/flex++bison++/
(variantele Bison, Flex care produc cod C++)

Cod surs lex


fisier.l

Cod surs C

executabil

lex.yy.c
lex ll fisier.l

a.out
gcc lex.yy.c

Trei segmente, separate de %%


Declaraii
Reguli
Cod C

Declaraiile conin
Declaraii C, ntre secvenele rezervate %{, %}
Definiii Lex pentru segmentul de reguli

O definiie Lex are forma


<nume> <expresie_regulat>
Expresiile regulate sunt construite pornind de la
orice caracter i folosind operatorii
" \[ ] ^ -? . * + | () / {} % <>

cifra [0-9]
litera [a-zA-Z]

Simbol

Descriere

orice caracter cu excepia newline

secven escape

zero sau mai multe copii ale expresiei precedente

una sau mai multe copii ale expresiei precedente

zero sau o copie a expresiei precedente

negaie

a|b

a sau b

()

grupare de caractere

a+b

literalul"a+b

[]

clasa de caractere

Expresia
abc
abc*
abc+
a(bc)+
a(bc)?
[abc]
[a-z]
[a\-z]
[-az]
[A-Za-z0-9]+
[ \t\n]+
[^ab]
[a^b]
[a|b]
a|b

Candidai ce se potrivesc
abc
ab abc abcc abccc ...
abc abcc abccc ...
abc abcbc abcbcbc ...
a abc
unul dintre caracterele: a, b, c
orice liter mic
unul din caracterele: a, -, z
unul din caracterele: -, a, z
unul sau mai multe caractere alfanumerice
spaii
orice cu excepia caracterelor: a, b
unul din caracterele : a, ^, b
unul din caracterele : a, |, b
unul din caracterele : a, b

Seciunea de reguli

exp_1
exp_2
.
.
.
exp_n

{Aciune_1}
{Aciune_2}

{Aciune_n}

Regulile sunt aplicate n ordinea scrierii


Prima regul care accept cuvntul este
aleas

Nume

Descriere

int yylex(void)

Apelul ctre analizor

char *yytext

pointer la cuvntul gsit

yyleng

lungimea cuvntului gsit

yylval

valoarea asociat cuvntului

FILE *yyout

fiierul de ieire

FILE *yyin

fiierul de intrare

%{
int yylineno;
%}
%%
^(.*)\n printf("%4d\t%s", ++yylineno, yytext);
%%
int main(int argc, char *argv[]) {
yyin = fopen(argv[1], "r");
yylex();
fclose(yyin);
}

letter [A-Za-z]
digit [0-9]
%{
int count;
%}
%%
{letter}({letter}|{digit})* {count++;}
.{}
%%
int main(void) {
yylex();
printf("number of identifiers = %d\n", count);
return 0;
}

%{
int nchar, nword, nline;
%}
%%
\n { nline++; nchar++; }
[^ \t\n]+ { nword++, nchar += yyleng; }
. { nchar++; }
%%
int main(void) {
yylex();
printf("%d\t%d\t%d\n", nchar, nword, nline);
return 0;
}

%{
# include <stdio.h>
%}
litera [a-zA-Z]
cifra [0-9]
cifre ({cifra})+
semn [+-]
operator [+*/<>=-]
spatiu [' \t\n]
%%
"if" | "then" | "else
({litera})({litera}|{cifra})*
{cifre}|({semn})({cifre})
{operator}
\:\=
\:
(\()|(\))
{spatiu}
.
%%
int main( ){
yylex( );
return 0;
}

{printf("%s
{printf("%s
{printf("%s
{printf("%c
{printf("%s
{printf("%c
{printf("%c
{}
{printf("%c

cuvant rezervat\n", yytext);}


identificator\n", yytext);}
numar intreg\n", yytext);}
operator\n", yytext[0]);}
asignare\n", yytext);}
doua puncte\n", yytext[0]);}
paranteza\n", yytext[0]);}
caracter ilegal\n", yytext[0]);}

Grigora Gh., Construcia compilatoarelor.


Algoritmi fundamentali, Editura Universitii
Alexandru Ioan Cuza, Iai, 2005

S-ar putea să vă placă și