Sunteți pe pagina 1din 134

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

Curs 9

Paii compilrii
Analiza lexical

Descriere lexical
Interpretare
Interpretare orientat dreapta
Descriere lexical bine format

Lex
Gramatici de tipul 2

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

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

Analiza sintactic ascendent


Parser ascendent general

Gramatici LR(k)
Definiie
Proprieti

Gramatici LR(0)
Teorema de caracterizare LR(0)
Automatul LR(0)

a1

X1

...

ai

...

an

Tabela de
parsare

Control

X1
...
#
p1

p2

...

O configuraie ( #, u#, ) este


interpretat n felul urmtor:
# este coninutul stivei cu simbolul # la
baza.
u# este coninutul intrrii.
este coninutul ieirii.

C0= {(#, w#, )|w T*} mulimea


configuraiilor iniiale.

Parserul ascendent ataat gramaticii G este


perechea (C0, ) unde C0 este mulimea
configuraiilor iniiale, iar este o relaie de
tranziie definit astfel:

(# , au#, ) (# a, u#, ) (deplasare) pentru orice *,


a T, u T*, P*.
(#, u#, ) (#A, u#, r) dac r = A (reducere).
Configuraia (#S, #, ) unde , se numete

configuraie de acceptare.

Orice configuraie, diferit de cea de acceptare, care nu


este n relaia cu nici o alt configuraie este o
configuraie eroare.

Parsere de deplasare/reducere.

Fie gramatica S aSb| . Tranziiile sunt:

(#, u#, ) (#S, u#, 2)


(#aSb, u#, ) (#S, u#, 1)
(#, au#, ) (#a, u#, )
(#, bu#, ) (#b, u#, )

O succesiune de tranziii se numete calcul


(#, #, ) (#S, #, 2)
(#, aabb#, ) (#a, abb#, ) (#aa, bb#, ) (#aaS, bb#, 2)
(#aaSb, b#, 2) (#aS, b#, 21) (#aSb, #, 21) (#S, #,
211)

Parserul este nedeterminist:


Pentru o configuraie de tipul (#, au#, ), S,
exist dou posibiliti (conflict
deplasare/reducere):
(#, au#, ) (#S, au#, r) (reducere cu S)
(#, au#, ) (# a, u#, ) (deplasare)

Pentru o configuraie (#, u#, ) cu =11=22 i


A1, B2, reguli (conflict reducere/reducere)
(#11, u#, ) (# 1A, au#, r1)
(#22, u#, ) (# 2B, au#, r2)

Spunem c un cuvnt wT* este acceptat de


un parser ascendent dac exist mcar un
calcul de forma
(#, w#, ) +(#S, #, )

Pentru ca parserul descris s fie corect,


trebuie ca el s accepte toate cuvintele din
L(G) i numai pe acestea.
Teorema

Parserul ascendent general ataat unei gramatici G


este corect: pentru orice wT*, wL(G) dac i numai
dac n parser are loc calculul (#, w#, ) +(#S, #, ).

Gramatici LR(k):Left to right scanning of the


input, constructing a Rightmost derivation in
reverse, using k symbols lookahead
Definiie
O gramatic G se numete gramatic LR(k), k0,
dac pentru orice dou derivri de forma:
S S dr* Au dr u = u
S S dr* Au dr u = v = v
pentru care k:u = k:v, are loc =, =, A=A

Teorema 1

Dac G este gramatic LR(k), k0, atunci G este


neambigu.

Un limbaj L este (n clasa) (k) dac exist o


gramatic LR(k) care l genereaz
Teorema 2
Orice limbaj (k) este limbaj de tip 2 determinist.

Teorema 3

Orice limbaj de tip 2 determinist este limbaj LR(1).

Teorema 4

Pentru orice limbaj (k), k1, exist o gramatic LR(1)


care genereaz acest limbaj, adic LR(0) LR(1) = LR(k),
k1.

Definiie

Fie G = (V, T, S, P) o gramatic independent de


context redus. S presupunem c simbolul nu
este n . Un articol pentru gramatica G este o
producie A n care s-a adugat simbolul ntr-o
anume poziie din . Notm un articol prin A
dac = . Un articol n care este pe ultima
poziie se numete articol complet.

Definiie

Un prefix viabil pentru gramatica G este orice prefix


al unui cuvnt dac S dr* Au dr u . Dac =
12i = 1spunem c articolul A 12 este
valid pentru prefixul viabil .

Exemplu S A, A aAa | bAb | c | .

Articole: SA, SA, AaAa, AaAa, AaAa,


AaAa, AbAb, AbAb, AbAb, AbAb,
Ac, Ac, A .

Articole valide pentru prefixe viabile:


Prefixul viabil Articole valide Derivarea corespunztoare
ab

AbAb
AaAa
AbAb

SAaAaabAba
SAaAaabAbaabaAaba
SAaAaabAbaabbAbba

SA
AbAb
Ac

SA
SAbAb
SAc

Lema
Fie G o gramatic i A1B2 un articol valid
pentru prefixul viabil . Atunci, oricare ar fi
producia B, articolul B este valid pentru .

Teorema (caracterizare LR(0))

Gramatica G este gramatic LR(0) dac i numai


dac, oricare ar fi prefixul viabil , sunt ndeplinite
condiiile:
1.nu exist dou articole complete valide pentru .
2.dac articolul A este valid pentru , nu exist nici
un articol B1a2, aT, valid pentru .

Teorema
Fie G = (V, T, S, P) o gramatic independent de context. Mulimea
prefixelor viabile pentru gramatica G este limbaj regulat.

Demonstraie
G este G la care se adaug SS.
M = (Q, , , q0, Q), unde:

Q este mulimea articolelor gramaticii G,


= VT, q0= SS
:Qx( {})2Q definit astfel:
(A B, ) = {B | B P}.
(A X, X) = { A X}, X .
(A a, ) = , a T.
(A X, Y) = , X,Y cu X Y.

Se arat c are loc:


(A ^(q0, ) este prefix viabil i A este valid
pentru .

S S, S aSa |bSb | c

Teorema (caracterizare LR(0)). Demonstraie


G este LR(0) i, prin reducere la absurd 1 sau 2
nu are loc
1, 2 au loc si prin reducere la absurd, G nu este
LR(0): exist
S S dr* Au dr u = u
S S dr* Au dr u = v = v
Nu au loc =, =, A=A

Fr a restrnge generalitatea, presupunem c


|| = || ||

Cazul 1: || ||
=12, v=2u, 2T*. Din (1) avem A articol
valid pentru i din (2) avem A12 articol
valid pentru . Dac 2= atunci contrazic (1) iar
altfel contrazic (2).

Cazul 2: || > ||

=u1, v=u1u T* (|u1|1)n derivarea (2), punem


n eviden prima form propoziional care are
prefixul .
SS dr1A1u1dr11u1dr11 1u1=1u1dr v
Avem A i A 111 articole valid pentru

Algoritmul 1(procedura nchidere(t))


Intrare:
Gramatica G = (V, T, S, P);
Mulimea t de articole din gramatica G;

Ieire: t=nchidere( t)={qQ|pt, q (p,)} =


(t,)

t = t ; flag = true;
while( flag ) {
flag = false;
for (AB t ) {
for (B P )
if (Bt ) {
t = t{B};
flag = true;
}//endif
}//endforB
}//endforA
}//endwhile
return t;

Algoritmul 2 Automatul LR(0)


Intrare:Gramatica G = (N, T, S, P) la care s-a
adugat S S;
Ieire:Automatul determinist M = (T, , g, t0, T)
echivalent cu M.

t0=nchidere(S S); T={t0}; marcat(t0)=false;


while( t T && !marcat(t)) { // marcat(t) = false
for( X ) {// = N T
t = ;
for(AX t)
t = t {BX | AX t};
if( t){
t = nchidere( t );
if( tT ) {
T = T{ t };
marcat( t ) = false;
}//endif
g(t, X) = t;
}//endif
}//endfor
}//endfor
marcat( t ) = true;
}// endwhile

S S, S aSa | bSb | c

Definiie Fie G o gramatic i M automatul LR(0)


ataat lui G.

Spunem c o stare a lui M are un conflict reducere/reducere


dac ea conine dou articole complete distincte A,
B.
Spunem c o stare a lui M are un conflict
deplasare/reducere dac ea conine un articol complet
A i un articol cu terminal dup punct de forma
Ba.
Spunem c o stare este consistent dac ea nu conine
conflicte i este inconsistent n caz contrar.

Teorema Fie G o gramatic i M automatul su LR(0).


Gramatica G este LR(0) dac i numai dac automatul
M nu conine stri inconsistente

S aAd | bAB, A cA | c, B d

Grigora Gh., Construcia compilatoarelor.


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

Curs 10-11

Analiza sintactic ascendent


Parser ascendent general

Gramatici LR(k)
Definiie
Proprieti

Gramatici LR(0)
Teorema de caracterizare LR(0)
Automatul LR(0)

a1

X1

...

ai

...

an

Tabela de
parsare

Control

X1
...
#
p1

p2

...

S S, S aSa | bSb | c

Analiza sintactic LR(0)


Mulimile FIRST, FOLLOW
Gramatici SLR(1)
Tabela de parsare SLR(1)
Analiza sintactic SLR(1)

Gramatici LR(1)
Gramatici LALR(1)

Tabela de parsare coincide cu automatul LR(0),


M.
Configuraie: (, u#, ) unde t0T*, uT*, P*.
Configuraia iniial este (t0, w#, ),
Tranziiile:

Deplasare: (t, au#, ) (tt, u#, ) dac g(t, a) = t.


Reducere: (tt, u#, ) ( tt, u#, r) dac A t,
r = A , | t | = | | i t= g (t, A).
Acceptare: (t0t1, #, ) este configuraia de acceptare dac
S S t1, este parsarea acestuia.
Eroare: o configuraie creia nu i se poate aplica nici o
tranziie

char ps[]= w#; //ps este sirul de intrare w


i = 0; // pozitia in sirul de intrare

STIVA.push(t0); // se initializeaza stiva cu t0

while(true) { // se repeta pana la succes sau eroare


t = STIVA.top();
a = ps[i] // a este simbolul curent din intrare
if( g(t, a) { //deplasare
STIVA.push(g(t, a));

i++; //se inainteaza in intrare


}
else {
if(A X1X2Xm t){

if(A == S)

else // reducere

if(a == #)exit( acceptare);


else exit(eroare);

for( i = 1; i m; i++) STIVA.pop();


STIVA.push(g(top(STIVA), A));

} //endif
else exit(eroare);
}//endelse

}//endwhile

S S S E$ E E+T T (E) E T T a

S S S E$ E E+T T (E) E T T a
Stiva

Intrare

Aciune

0
05
03
02
027
0274
02745
02743
02748
027487
0274875
0274879
02748
02748'10'
0279
02
026
01

a+(a+a)$#
+(a+a)$#
+(a+a)$#
+(a+a)$#
(a+a)$#
a+a)$#
+a)$#
+a)$#
+a)$#
a)$#
)$#
)$#
)$#
$#
$#
$#
#
#

deplasare
reducere
reducere
deplasare
deplasare
deplasare
reducere
reducere
deplasare
deplasare
reducere
reducere
deplasare
reducere
reducere
deplasare
reducere
acceptare

Ieire
Ta
ET

Ta
ET

Ta
E E+T
T (E)
E E+T
S E$

Lema 1, 2 Fie G = (N, T, S, P) o gramatic LR(0),


t0, t0 drumuri n automatul LR(0) etichetate cu
respectiv i u, v T*. Atunci, dac n parserul
LR(0) are loc (t0, uv#, ) +(t0, v#, ), atunci n G
are loc derivarea dru i reciproc.
Teorem Dac G este gramatic LR(0) atunci,
oricare ar fi cuvntul de intrare w T*, parserul
LR(0) ajunge la configuraia de acceptare pentru
w, adic (t0, uv#, ) +(t0, v#, ) dac i numai
dac dru

Definiie

Fie G o gramatic pentru care automatul LR(0) conine stri


inconsistente (deci G nu este LR(0)). Gramatica G este gramatic
SLR(1)dac oricare ar fi starea t a automatului LR(0) sunt
ndeplinite condiiile:

Dac A, B t atunci FOLLOW(A) FOLLOW(B) = ;


Dac A, B a t atunci a FOLLOW(A).

Analiza sintactic SLR(1) este similar cu cea LR(0);tabela


de analiz sintactic are dou componente:

Prima, numit ACIUNE, determin dac parserul va face


deplasare respectiv reducere, n funcie de starea ce se afl n
topul stivei i de simbolul urmtor din intrare
Cea de a doua, numit GOTO, determin starea ce se va aduga
n stiv n urma unei reduceri.

FIRST() = {a|a T, st* au } if ( st * )


then {} else .
FOLLOW(A) = {a|a T {}, S
FIRST () }

st

* uA, a

1.for(X )
2.if(X T)FIRST(X)={X} else FIRST(X)=;
3.for(Aa P)
4.FIRST(A)=FIRST(A){a};

5.FLAG=true;

6.while(FLAG){
7.FLAG=false;
8.for(A X1X2Xn P){

9.i=1;

10.if((FIRST(X1) FIRST(A)){
11.FIRST(A)=FIRST(A) (FIRST(X1);

13.}//endif

14.while(i<n&&Xi st * )

12.FLAG=true;

15.if((FIRST(Xi+1) FIRST(A)){
16.FIRST(A)=FIRST(A) FIRST(Xi+1);

17.FLAG=true;i++;
}//endif

}//endwhile
}//endfor
}//endwhile
for(A N)
if(A st * )FIRST(A)=FIRST(A) {};

Intrare: Gramatica G=(N,T,S,P).


Mulimile FIRST(X),X .
=X1X2Xn, Xi ,1in.
Ieire: FIRST().
1.FIRST()=FIRST(X1)-{};i=1;
2.while(i<n && Xi + ){
3.FIRST()=FIRST()(FIRST(Xi+1)-{});
4.i=i+1;
}//endwhile
5.if(i==n && Xn + )
6.FIRST()=FIRST() {};

Fie gramatica:
S E | B, E , B a | beginSC end,
C | ; SC
FIRST(S) = {a, begin, } FIRST(E) = {}
FIRST(B) = {a, begin} FIRST(C) = {;, }.
FIRST(SEC) = {a, begin, ;, },
FIRST(SB)= {a, begin},
FIRST(;SC)= {;}.

FOLLOW(S).
Dac A BX P i + , atunci FIRST(X) {} FOLLOW (B).

S * 1A 1 1BX1 * 1BX1 i atunci rezult


FIRST(X)-{} FOLLOW (B).

Dac A B P atunci FIRST()-{}


FOLLOW (B).

Dac A B P i + , atunci FOLLOW(A)


FOLLOW(B).

1. for(A )FOLLOW(A)=;
2.FOLLOW(S)={};
3.for(A X1X2Xn){
4.i=1;
5.while(i<n){
6.while(Xi N)++i;
7.if(i<n){
8.FOLLOW(Xi)= FOLLOW(Xi)
(FIRST(Xi+1Xi+2Xn)-{});
9.++i;
}//endif
}//endwhile
}//endfor

10.FLAG=true;
11.while(FLAG){
12.FLAG=false;
13.for(A X1X2Xn){
14.i=n;
15.while(i>0 && Xi N){
16.if(FOLLOW(A) FOLLOW(Xi)){
17.FOLLOW(Xi)=FOLLOW(Xi) FOLLOW(A);
18.FLAG=true;
19.}//endif
20.if(Xi + )--i;
21.else continue;
22.}//endwhile
23.}//endfor
24.}//endwhile

Fie gramatica:
S E | B, E , B a | begin SC end,
C | ; SC
FOLLOW(S)=FOLLOW(E)=FOLLOW(B) ={, ; , end}
FOLLOW(C) = {end}.

Definiie

Fie G o gramatic pentru care automatul LR(0) conine stri


inconsistente (deci G nu este LR(0)). Gramatica G este gramatic
SLR(1)dac oricare ar fi starea t a automatului LR(0) sunt
ndeplinite condiiile:

Dac A, B t atunci FOLLOW(A) FOLLOW(B) = ;


Dac A, B a t atunci a FOLLOW(A).

Analiza sintactic SLR(1) este similar cu cea LR(0);tabela


de analiz sintactic are dou componente:

Prima, numit ACIUNE, determin dac parserul va face


deplasare respectiv reducere, n funcie de starea ce se afl n
topul stivei i de simbolul urmtor din intrare
Cea de a doua, numit GOTO, determin starea ce se va aduga
n stiv n urma unei reduceri.

Intrare:
Gramatica G = (N, T, S, P) augmentat cu S S;
Automatul M = (Q, , g, t0, Q );
Mulimile FOLLOW(A), AV

Ieire:
Tabela de analiz SLR(1) compus din dou pri:
ACIUNE(t, a), t Q, a T { # },
GOTO(t, A), t Q, A N.

for(t Q)
for (a T) ACTIUNE(t, a) = eroare;
for (A V) GOTO(t, A) = eroare;
for(t Q}{
for(A a t)
ACTIUNE(t,a)=D g(t, a);//deplasare in g(t, a)
for(B t ){// acceptare sau reducere
if(B == S) ACTIUNE(t, a) = acceptare;
else
for(a FOLLOW(B)) ACTIUNE(t,a)=R B;
}// endfor
for (A N) GOTO(t, A) = g(t, A);
}//endfor

Deplasare: (t, au#, )(tt, u#, ) dac ACTIUNE(t, a)=Dt;


Reducere: (tt, u#, )( tt, u#, r) ACTIUNE(t, a) = Rp
unde p= A , |t| = || i t= GOTO(t, A);
Acceptare: (t0t, #, ) dac ACTIUNE(t,a) = acceptare;
Analizorul se oprete cu acceptarea cuvntului de analizat
iar este parsarea acestuia (irul de reguli care s-a aplicat,
n ordine invers, n derivarea extrem dreapt a lui w).
Eroare: ( t, au#, ) eroare dac ACTIUNE(t,a) = eroare;
Analizorul se oprete cu respingerea cuvntului de
analizat.

Intrare:
Gramatica G = (N, T, S, P) care este SLR(1) ;
Tabela de parsare SLR(1) ( ACTIUNE, GOTO);
Cuvntul de intrare w T*.

Ieire:
Analiza sintactic (parsarea) ascendent a lui w
dac w L(G);
eroare, n caz contrar.

Se folosete stiva St pentru a implementa


tranziiile deplasare/reducere

char ps[] = w#; //ps este cuvantul de intrare w


int i = 0; // pozitia curenta in cuvantul de intrare
St.push(t0); // se initializeaza stiva cu t0
while(true) { // se repeta pana la succes sau eroare
t = St.top();
a = ps[i] // a este simbolul curent din intrare
if(ACTIUNE(t,a) == acceptare) exit(acceptare);
if(ACTIUNE(t,a) == Dt){
St.push(t);
i++; // se inainteaza in w
}//endif
else {
if(ACTIUNE(t,a) == R A X1X2Xm){
for( i = 1; i m; i++) St.pop();
St.push(GOTO(St.top, A));
} //endif
else exit(eroare);
}//endelse
}//endwhile

0.S E, 1.E E+T, 2.E T, 3.T T*F, 4.T F,


5.F (E), 6.F a

G nu este LR(0) strile 1, 2, 9 conin conflict


de deplasare/reducere

FOLLOW(S)={#}, FOLLOW(E)={#,+,)}

Gramatica este SLR(1) pentru c:


n starea 1: + FOLLOW(S);
n starea 2: * FOLLOW(E);
n starea 9: * FOLLOW(E).

Stiva

Intrare

Actiune

Iesire

a*(a+a)#

deplasare

05

*(a+a)#

reducere

6.F a

03

*(a+a)#

reducere

4.T F

02

*(a+a)#

deplasare

027

(a+a)#

deplasare

0274

a+a)#

deplasare

02745

+a)#

reducere

6.F a

02743

+a)#

reducere

4.T F

02742

+a)#

reducere

2.E T

02748

+a)#

deplasare

Stiva

Intrare

Actiune

Iesire

027486

a)#

deplasare

0274865

)#

reducere

6.F a

0274863

)#

reducere

4.T F

0274869

)#

reducere

1.E E+T

02748

)#

deplasare

02748(11)

reducere

5.F (E)

027(10)

reducere

3.T T*F

02

reducere

2.E T

01

acceptare

Definiie
Fie G = (V, T, S, P) o gramatic redus. Un articol LR(1)
pentru gramatica G este o pereche (A , a), unde A
este un articol LR(0), iar a FOLLOW(A) (se pune # n loc de
).
Definiie
Articolul (A 12, a) este valid pentru prefixul viabil
1dac are loc derivarea
S dr*Au 12u
iar a = 1:u (a = # dac u = ).

Teorema
O gramatic G = (V, T, S, P) este gramatic LR(1) dac i
numai dac oricare ar fi prefixul viabil , nu exist dou
articole distincte, valide pentru , de forma(A , a), (B
, b) unde a FIRST( b).

Nu exist conflict deplasare/reducere. Un astfel de conflict


nseamn dou articole (A , a) i (B a, b) valide
pentru acelai prefix.
Nu exist conflict reducere/reducere. Un astfel de conflict
nseamn dou articole complete(A , a) i (B , a)
valide pentru acelai prefix

Pentru a verifica dac o gramatic este LR(1) se


construiete automatul LR(1) n mod asemntor ca la
LR(0):

Automatul are ca stri mulimi de articole LR(1)


Tranziiile se fac cu simboluri ce apar dup punct
nchiderea unei mulimi de articole se bazeaz pe faptul c dac
articolul (B A, b) este valid pentru un prefix viabil atunci
toate articolele de forma (A , a)unde a FIRTS(a) sunt valide
pentru acelai prefix.

flag= true;
while( flag) {
flag= false;

for ( (A B, a) I) {

for B P)
for( b FIRST(a)){
if( (B , b) I) {
I = I{(B , b)};
flag= true;
}//endif
}//endforb
}//endforB
}//endforA
}//endwhile
return I;

S,#));T={t };marcat(t )=false;

t0 = nchidere((S

while( tT&& !marcat(t)){ // marcat(t) = false


for( X ) {
t = ;

for( (A X ,a) t )
t = t {(B X ,a) | (B B X,a) t};

if( t ){
t = nchidere( t );
if( tT) {
T= T { t };
marcat( t ) = false;
}//endif
g(t, X) = t;
} //endif
} //endfor
marcat( t ) = true;
} // endwhile

Teorema

Automatul LR(1) pentru o gramatic G, se folosete


pentru a verifica dac G este LR(1)

Automatul M construit n algoritmul 2 este determinist i


L(M) coincide cu mulimea prefixelor viabile ale lui G. Mai
mult, pentru orice prefix viabil , g(t0,) reprezint mulimea
articolelor LR(1) valide pentru .

Conflict reducere/reducere: Dac n T exist o stare ce


conine articole de forma (A , a), (B , a) atunci
gramatica nu este LR(1);
Conflict deplasare/reducere: Dac n Texist o stare ce
conine articole de forma (A , a) i (B 1a2, b),
atunci G nu este LR(1).
O gramatic este LR(1) dac orice stare t Teste liber de
conflicte

L=R|R, L

*R|a, R

Curs 12

Definiie
Fie G = (V, T, S, P) o gramatic redus. Un articol LR(1)
pentru gramatica G este o pereche (A , a), unde A
este un articol LR(0), iar a FOLLOW(A) (# n loc de ).
Definiie
Articolul (A 1 2, a) este valid pentru prefixul viabil
1dac are loc derivarea
S dr*Au 12u
iar a = 1:u (a = # dac u = ).

Teorema
O gramatic G = (V, T, S, P) este gramatic LR(1) dac i
numai dac oricare ar fi prefixul viabil , nu exist dou
articole distincte, valide pentru , de forma(A , a), (B
, b) unde a FIRST(b).

Nu exist conflict deplasare/reducere. Un astfel de conflict


nseamn dou articole (A , a) i (B a, b) valide
pentru acelai prefix.
Nu exist conflict reducere/reducere. Un astfel de conflict
nseamn dou articole complete(A , a) i (B , a)
valide pentru acelai prefix
Pentru a verifica dac o gramatic este LR(1) se
construiete automatul LR(1) n mod asemntor ca la
LR(0):

Automatul are ca stri mulimi de articole LR(1)


Tranziiile se fac cu simboluri ce apar dup punct
nchiderea unei mulimi de articole se bazeaz pe faptul c dac
articolul (B A, b) este valid pentru un prefix viabil atunci
toate articolele de forma (A , a)unde a FIRTS(a) sunt valide
pentru acelai prefix.

flag= true;
while( flag) {
flag= false;

for ( (A B, a) I) {

for B P)
for( b FIRST(a)){
if( (B , b) I) {
I = I {(B , b)};
flag = true;
}//endif
}//endforb
}//endforB
}//endforA
}//endwhile
return I;

t0 = nchidere((S S,#));T={t0};marcat(t0)=false;
while( tT&& !marcat(t)){ // marcat(t) = false
for( X ) {
t = ;
for( (A X ,a) t )
t = t {(B X ,a) | (B B X,a) t};
if( t ){
t = nchidere( t );
if( tT) {
T= T { t };
marcat( t ) = false;
}//endif
g(t, X) = t;
} //endif
} //endfor
marcat( t ) = true;
} // endwhile

Teorema

Automatul LR(1) poate fi folosit pentru a verifica dac


G este LR(1)

Automatul M construit n algoritmul 2 este determinist i


L(M) coincide cu mulimea prefixelor viabile ale lui G. Mai
mult, pentru orice prefix viabil , g(t0,) reprezint mulimea
articolelor LR(1) valide pentru .

Conflict reducere/reducere: Dac n T exist o stare ce


conine articole de forma (A , a), (B , a) atunci
gramatica nu este LR(1);
Conflict deplasare/reducere: Dac n Texist o stare ce
conine articole de forma (A , a) i (B 1a2, b),
atunci G nu este LR(1).
O gramatic este LR(1) dac orice stare t T este liber de
conflicte

S L=R|R, L *R|a, R L

for(t T)
for (a T) ACTIUNE(t,
for (A V) GOTO(t, A)
for(t T}{
for((A a, L) t)
ACTIUNE(t,a)=D g(t,
for((B , L) t ){//

a) = eroare;
= eroare;

a);//deplasare in g(t, a)
acceptare sau reducere

for(c L) {
if(B == S) ACTIUNE(t, a) = acceptare;
else ACTIUNE(t,c)=R B;//reducere cu B

}//endfor
}// endfor
for (A N) GOTO(t, A) = g(t, A);
}//endfor

0:SS, 1:S L=R, 2:S R, 3:L *R, 4:L a, 5:R L

Fie cuvintele
***a
a=**a
*a=**a

Analiza LR(1)?

Definiie
Fie t o stare n automatul LR(1) pentru G. Nucleul
acestei stri este mulimea articolelor LR(0) care
apar ca prime componente n articolele LR(1) din t.

Defininiie
Dou stri t1 i t2 ale automatului LR(1) pentru
gramatica G sunt echivalente dac au acelai
nucleu.

Fiecare stare a automatului LR(1) este o mulime


de articole LR(1). Pornind de la dou stri t1 i t2
putem vorbi de starea t1 t2.
Fie t1= {(L *R., {=, # })}, t2= {(L *R., #)}, atunci
t1t2=t1 pentru c t2 t1 .

Definiie
Fie G gramatic LR(1) i M = (Q, , g, t0, Q) automatul
LR(1) corespunztor. Spunem c gramatica G este
LALR(1) ( Look Ahead LR(1)) dac oricare ar fi perechea
de stri echivalente t1, t2 din automatul LR(1), starea
t1t2 este liber de conflicte.

Intrare: Gramatica G = (N, T, S, P) augmentat cu


S S;
Ieire: Tabela de analiz LALR(1) ( ACIUNE i
GOTO ).
Algoritm:
1. Se construiete automatul LR(1), M = (Q, , g, t0, Q)
Fie Q = {t0, t1,, tn}. Dac toate strile din Q sunt libere
de conflict, urmeaz 2, altfel algoritmul se oprete
deoarece gramatica nu este LR(1).

2. Se determin strile echivalente din Q i, prin


reuniunea acestora, se obine o nou mulime de stri Q
= {t0, t1,, tm}
3. Dac n Q exist stri ce conin conflicte, algoritmul
se oprete deoarece gramatica G nu este LALR(1).

4. Se construiete automatul M = (Q, , g, t0, Q),


unde tQ:
5. Dac t Q atunci g(t, X) = g(t, X), X;
6. Dac t = t1t2, t1, t2,Q, atunci

7. g(t, X) = g(t1, X)g(t2, X).

8. Se aplic algoritmul pentru construirea tabelei de


parsare LR(1) pornind de la automatul M. Tabela
obinut se numete tabela LALR(1) pentru
gramatica G.

Pentru gramatica discutat anterior avem


411 = 4, 512 = 5, 713 = 7, 810 = 8

Exist gramatici LR(1) care nu sunt LALR(1).


S aAb | bAd | aBd | bBb
A e
B e

Curs 13

Analiza sintactic descendent


Parser (Analizor de sintax) descendent general

Gramatici LL(1)

Definiie
Caracterizare
FIRST, FOLLOW
Tabela de parsare
Algoritmul de analiz sintactic LL(1)

O configuraie (u#, #,) este


interpretat n felul urmtor:
# este coninutul stivei cu simbolul # la
baz.
u# este coninutul intrrii.
este coninutul ieirii.

Dac C este mulimea configuraiilor atunci


CxC este relaia de tranziie definit astfel:
(u#, A#,) (u#, #,r), unde r = AP. (aplicare
regul, expandare)
(uv#, u#, ) (v#, #,). (potrivire)
( #, #, ) este configuraie de acceptare dac .
O configuraie c pentru care nu exist c astfel ca
cc produce eroare.
Configuraii iniiale: (w#, S#, ) unde wT*

1.EE+T, 2.ET, 3.TT*F, 4.TF, 5.F(E), 6.Fa


Intrare

Stiv

Ieire

a+a*a#

E#

a+a*a#

E+T#

a+a*a#

T+T#

12

a+a*a#

F+T#

124

a+a*a#

a+T#

1246

a*a#

T#

1246

a*a#

T*F#

12463

a*a#

F*F#

124634

a*a#

a*F#

1246346

a#

F#

1246346

a#

a#

12463466

12463466

Teorema (de corectitudine a analizorului)

Fie gramatica redus G=(N,T,S,P) i wT*. Atunci, are loc


(w#,S#,)+(#,#,) (acceptare) dac i numai dac wL(G) i
este o derivare exrem stng a cuvntului w.

Lema 1

Dac n analizorul sintactic descendent ataat gramaticii


G=(N,T,S,P) are loc calculul (uv#,u#,)+(v#,#,), atunci n
gramatica G are loc derivarea stu, oricare ar fi u,vT*,
, *, P*.

Lema 2

Dac n gramatica G are loc derivarea stu i 1:N{}


atunci n parserul descendent are loc calculul:
(uv#,u#,)+(v#,#,), vT*.

Demonstraii: inducie dup lungimea lui

Parserul este nedeterminist


Exist tipuri de gramatici pentru care este
determinist?
Construirea unei tabele de parsare

LL(k): Parsing from Left to right using Leftmost


derivation and k symbols lookahead.
Informal, o gramatic este LL(k) dac tranziia
de tip aplicare producie din parser se face cu
o unic regul A determinat prin
urmtoarele k simboluri de la intrare.

Definiie
k: reprezint primele k simboluri din (sau dac ||<k)
:k reprezint ultimele k simboluri din (sau dac ||<k)

Defininiie
O gramatic independent de context redus este
gramatic LL(k), k1, dac pentru orice dou
derivri de forma:
S*stuAstu1*stux
S*stuAstu2*stuy
unde u, x, yT*, pentru care k:x = k:y, are loc 1 = 1.

Teorema

Orice gramatic LL(k) este neambigu.

Teorema

Dac G este o gramatic stng recursiv, atunci nu


exist nici un numr k astfel nct G s fie LL(k).

Teorema

Clasele de limbaje LL(k)formeaz o ierarhie infinit:


(0)(1)(2)(k)(k+1)

Lema

Exist limbaje care nu sunt LL(k) pentru nici o


valoare kN.

Teorem
O gramatic G = (N, T, S, P) este gramatic LL(1)
dac i numai dac pentru orice AN i pentru
orice dou producii A1|2 are loc:
FIRST (1 FOLLOW (A))FIRST (2 FOLLOW (A)) =

1.for(AN)
2.for(aT{#})
3.M(A,a)=;
4.for(p=AP){
5.for(aFIRST()-{})
6.M(A,a)=M(A,a){(,p)};
7.if(FIRST()){
8.for(bFOLLOW(A)){
9.if(b== ) M(A,#)=M(A,#){(,p)};
10.else M(A,b)=M(A,b){(,p)};
}//endfor
}//endif
}//endfor
11.for(AN)
12.for(aT{#})
13.if(M(A,a)=) M(A,a)={eroare};

S aSa | bSb | c
M

(aSa, 1)

(bSb, 2)

(c, 3)

eroare

S aSa | bSb | a | b | c |
M

(aSa, 1)
(a, 3)
(, 6)

(bSb, 2)
(b, 4)
(, 6)

(c, 5)

(, 6)

Configuraia iniial: (w#, S#, )


Tranziii
(u#, A#,) (u#, #,r), dac M(A, 1:u#)=(, r),
(expandare)
(uv#, u#,) (v#, #,) (potrivire)
(#, #,) acceptare, dac (acceptare)
(au#, b#,) eroare dac a b
(u#, A#,) eroare dac M(A, 1:u#)=eroare

1. S E, 2. S B, 3. E , 4. B a, 5. B
begin SC end, 6. C , 7. C ;SC

Intrare

Stiv

Aciune

Ieire

begin a;;a end#

S#

expandare

begin a;;a end#

B#

expandare

begin a;;a end#

begin SC end#

potrivire

a;;a end#

SC end#

expandare

a;;a end#

BC end#

expandare

a;;a end#

aC end#

potrivire

;;a end#

C end#

expandare

;;a end#

;SC end#

potrivire

;a end#

SC end#

expandare

;a end#

EC end#

expandare

;a end#

C end#

expandare

;a end#

;SC end#

potrivire

a end#

SC end#

expandare

a end#

BC end#

expandare

a end#

aC end#

potrivire

end#

C end#

expandare

end#

end#

potrivire

acceptare

Fie G = (N, T, S, P) o gramatic n form redus

Fie AN imediat recursiv

Fie AA1|A2| Ak|1|1| toate regulile care


ncep cu A. Fie PA mulimea acestor reguli.
Gramatica G unde A nu este recursiv imediat
G=(N{A}, T, S, P)
P=P-PA {A1A|2A|kA|, A1A|2A|}

E E+T |E -T |-T |T
T T*F | T/ F | F
F (E) | a
E TE | -TE
E +T E|-TE |
T FT
T *FT | /FT |
F (E) | a

Factorizarea este o transformare aplicat asupra


unei gramatici pentru a obine o gramatic
echivalent, eventual LL(1)
Dac exist produciile
A1, A2 cu || > 1

(deci gramatica nu este LL(1)), acestea se


nlocuiesc cu AA, A un nou neterminal, i
produciile A1 i A2. Metoda de
transformare se numete factorizare la stnga

Fie gramatica
S if E then S | if E then S else S | a
Eb

factorizarea la stnga: = if E then S


Gramatica echivalent va fi
S if E then S S | a
S else S |
Eb

Prin factorizare nu este sigur c obinem o gramatic


LL(1).
Putem rezolva ambiguitatea alegnd regula Selse S
n M(S, else). Aceast alegere ar corespunde asocierii
lui else pentru acel if precedent cel mai apropiat de
el, soluie adoptat de majoritatea limbajelor de
programare.

Este dovedit pe baza


Teoremei de corectitudine a parserului descendent
general,
Teoremei de caracterizare a gramaticilor LL(1)
Modului n care a fost construit tabela de parsare

Grigora Gh., Construcia compilatoarelor.


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

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