Sunteți pe pagina 1din 144

Irina Athanasiu 3/1/2002 Limbaje formale i automate

1
1 INTRODUCERE - ORGANIZAREA UNUI COMPILATOR................................ 2
1.1 Analiza lexicala......................................................................................................................................... 4
1.2 Analiza sintactic...................................................................................................................................... 4
1.3 Analiza semantic..................................................................................................................................... 5
1.4 Generarea de cod intermediar................................................................................................................. 5
1.5 Optimizarea codului intermediar............................................................................................................ 5
1.6 Generarea codului obiect ......................................................................................................................... 6
1.7 Optimizarea codului obiect...................................................................................................................... 6
1.8 Gestiunea tabelei de simboluri ................................................................................................................ 6
1.9 Detectarea erorilor ................................................................................................................................... 6
2 ELEMENTE DE TEORIA LIMBAJELOR FORMALE........................................ 7
2.1 Gramatici .................................................................................................................................................. 7
2.1.1 Ierarhia Chomsky............................................................................................................................... 8
2.1.1.1 Exerciii ........................................................................................................................................ 9
2.1.2 Verificarea limbajului generat de ctre o gramatic ........................................................................ 10
2.1.2.1 Exerciii ...................................................................................................................................... 11
2.1.3 Transformri asupra gramaticilor independente de context............................................................. 11
2.1.3.1 Eliminarea ambiguitii............................................................................................................... 12
2.1.3.2 Eliminarea - produciilor .......................................................................................................... 16
2.1.3.3 Eliminarea recursivitii stnga................................................................................................... 16
2.1.3.4 Factorizare stnga ....................................................................................................................... 18
2.1.3.5 Eliminarea simbolilor neterminali neutilizai.............................................................................. 19
2.1.3.6 Substituia de nceputuri(corner substitution)............................................................................. 20
2.1.4 Construcii dependente de context ................................................................................................... 22
2.1.4.1 Exerciii ...................................................................................................................................... 23
2.1.5 Proprieti ale limbajelor independente de context.......................................................................... 24
2.1.5.1 Exerciii ...................................................................................................................................... 25
2.2 Mulimi regulate, expresii regulate. ...................................................................................................... 25
2.3 Acceptoare............................................................................................................................................... 28
2.3.1 Automate finite ................................................................................................................................ 29
2.3.1.1 Construcia unui automat finit nedeterminist care accept limbajul descris de o expresie regulat
dat 30
2.3.1.2 Conversia unui automat finit nedeterminist (AFN) ntr-un automat finit determinist(AFD)...... 34
2.3.1.3 Construcia unui automat finit determinist care accept limbajul descris de o expresie regulat
dat 37
2.3.1.4 Simularea unui automat finit determinist.................................................................................... 43
2.3.1.5 Simularea unui automat finit nedeterminist ................................................................................ 44
2.3.1.6 Probleme de implementare pentru automatele finite deterministe i nedeterministe.................. 45
2.3.1.7 Minimizarea numrului de stri pentru AFD.............................................................................. 46
Irina Athanasiu 3/1/2002 Limbaje formale i automate

2
2.3.2 Automate cu stiv (pushdown) ........................................................................................................ 49
2.3.2.1 Automate cu stiv cu acceptare prin stiv goal......................................................................... 52
2.3.2.2 Relaia ntre automate cu stiv i limbajele independente de context......................................... 53
2.3.3 Maina Turing.................................................................................................................................. 57
2.3.3.1 Calcule realizate de Maina Turing ............................................................................................ 60
2.3.3.2 Compunerea mainilor Turing.................................................................................................... 63
2.3.3.3 Extensii pentru maina Turing.................................................................................................... 67
2.3.3.4 Automate liniar mrginite........................................................................................................... 73
2.3.3.5 Relaia ntre maina Turing i gramatici ..................................................................................... 74
2.3.3.6 Elemente de calculabilitate ......................................................................................................... 77
2.3.3.6.1 Maina Turing Universal................................................................................................... 77
2.3.3.7 . Maina Turing cu limit de timp............................................................................................... 81
3 2. ANALIZA LEXICAL.................................................................................. 83
3.1 Interfaa analizorului lexical ................................................................................................................. 87
3.2 Un exemplu elementar de analizor lexical............................................................................................ 89
4 ANALIZA SINTACTIC.................................................................................. 99
4.1 Analiza sintactica top - down............................................................................................................... 103
4.1.1 Analiza sintactica predictiva (descendent recursiva) ..................................................................... 104
4.1.1.1 Gramatici LL(1)........................................................................................................................ 109
4.1.1.2 Tratarea erorilor n analiza predictiv....................................................................................... 115
4.1.2 Analiza sintactica bottom-up ......................................................................................................... 117
4.1.2.1 Analiza sintactica de tip deplaseaza i reduce .......................................................................... 117
4.1.2.2 Implementarea analizei sintactice bottom-up deplaseaz i reduce.......................................... 117
4.1.2.3 Analiza sintactica de tip LR(k) ................................................................................................. 121
4.1.2.3.1 Analiza SLR...................................................................................................................... 129
4.1.2.3.2 Analiza canonica LR......................................................................................................... 136
4.1.2.3.3 Analiza sintactic LALR................................................................................................... 142
1 Introducere - organizarea unui compilator

Un compilator este un program complex care realizeaz traducerea unui program surs ntr-un
program obiect. De obicei programul surs este scris ntr-un limbaj de nivel superior celui n care este
scris programul obiect.
Structura general pentru un compilator este:

Irina Athanasiu 3/1/2002 Limbaje formale i automate

3
program sursa
|
+-----------------+
| preprocesor | pas 1
+-----------------+
| pas 2
+ - - - - - - - | - - - - - - - - - - - - - - - - - - - - - - +
| | |
| | |
| +------------------+ +--------------------+ |
| | analiza lexicala |--------->| analiza sintactica | |
| | |<---------| | |
| +------------------+ +--------------------+ |
| | | | |
| +------------------+ +--------------------+ |
| | gestiunea tabelei| | analiza semantica | |
| | de simboli |<---------| | |
| +------------------+ +--------------------+ |
| | | |
| | +--------------------+ |
| +------------------->| generarea de cod | |
| | intermediar | |
| +--------------------+ |
+ - - - - - - - - - - - - - - - - - - - - - - | - - - - - - -+
| cod intermediar
|
+--------------------+
pas 3 | optimizare |
| cod intermediar |
+--------------------+
|
| cod intermediar
+--------------------+
pas 4 | generarea de cod |
| obiect |
+--------------------+
|
| cod obiect
+--------------------+
pas 5 | optimizare |
| cod obiect |
+--------------------+
|
limbaj de asamblare
sau
cod main

Preprocesorul realizeaz activiti de tip macro substituie, eliminarea comentariilor, etc.
Al doilea pas reprezint de fapt componenta principal a compilatorului (celelalte componente ar
putea s lipseasc). Efectul execuiei acestui pas const din verificarea corectitudinii formale a textului
programului i traducerea acestui text ntr-o form intermediar.
Urmtorii trei pai realizeaz prelucrri asupra programului n cod intermediar n scopul mbuntirii
performanelor acestuia (optimizarea) i generrii programului obiect.
Pasul cel mai complex dintr-un compilator rmne pasul 2 n care se realizeaz cele mai importante
operaii fr de care nu poate avea loc procesul de compilare. ntr-un compilator real cele cinci
componente care l formeaz: analiza lexical, analiza sintactic, analiza semantic, gestiunea tabelei de
simboli i generarea de cod nu sunt neaprat identificabile sub forma unor proceduri ori funcii distincte ci
Irina Athanasiu 3/1/2002 Limbaje formale i automate

4
sunt realizate printr-un ansamblu de funcii care coopereaz. n cele ce urmeaz aceste componente vor fi
descrise separat pentru simplificarea expunerii.
1.1 Analiza lexicala

Aceast faz a compilatorului realizeaz traducerea textului programului ntr-o forma mai uor de
prelucrat de ctre celelalte componente. Analizorul lexical consider textul primit la intrare ca fiind format
din uniti lexicale pe care le recunoate producnd atomi lexicali. Un atom lexical poate s fie de
exemplu, un cuvnt cheie al limbajului (for, while, etc) dar i un numr sau un nume. Nu exist o
coresponden biunivoc ntre irurile de intrare i atomii lexicali. Adic, dac pentru atomul lexical
corespunztor cuvntului cheie while exist un singur ir de intrare, pentru atomul lexical corespunztor
unui numr ntreg pot s existe foarte multe iruri de intrare. Una dintre deciziile ce trebuie luate la
nceputul proiectrii unui compilator const din stabilirea atomilor lexicali. De exemplu, se pune problema
dac s existe cte un atom lexical pentru fiecare operator de comparaie (<, <=, >, >=) sau s existe un
unic atom lexical - corespunztor operaiei de comparaie. n primul caz generarea de cod poate s fie mai
simpl. Pe de alt parte existena unui numr mare de atomi lexicali poate complica n mod exagerat
analiza sintactic. n general, operatorii care au aceeai prioritate i asociativitate pot s fie grupai
mpreun.
Rolul unui analizor lexical este de a traduce irurile de intrare n atomi lexicali. Un atom lexical este
reprezentat printr-un cod numeric care specifica clasa acestuia i o serie de atribute care sunt specifice
fiecrei clase. Astfel, poate s existe clasa operatorilor relaionali pentru care un atribut trebuie s se
specifice tipul concret al operatorului. Tipul atomului lexical este necesar pentru analiza sintactic n timp
ce valoarea atributului este semnificativ pentru analiza semantic i generarea de cod. Pentru un atom
lexical de tip numr atributele vor descrie tipul numrului i valoarea acestuia.
Un analizor lexical apare n general ca o funcie care interacioneaz cu restul compilatorului printr-o
interfa simpl : ori de cte ori analizorul sintactic are nevoie de un nou atom lexical va apela analizorul
lexical care i va da atomul lexical urmtor.
1.2 Analiza sintactic

Analiza sintactic descompune textul programului sursa n componentele sale "gramaticale",
construind un arbore care reflect aceast structur. S considerm de exemplu expresia :

A * B + C * D

Aceast expresie poate s fie descris de urmtorul tip de arbore numit arbore sintactic:

+
/ \
/ \
/ \
* *
/ \ / \
/ \ / \
A B C D

n acest arbore au fost evideniate relaiile (din punctul de vedere al modului de evaluare) ntre
componentele expresiei. Dac se dorete ns s se evidenieze structura expresiei din punctul de vedere al
unitilor sintactice din care este format, atunci se va utiliza pentru reprezentarea expresiei un arbore de
derivare (parse tree). Pentru exemplul considerat un arbore de derivare ar putea s fie de forma:

Irina Athanasiu 3/1/2002 Limbaje formale i automate

5
expresie
/ | \
expresie + expresie
/ / / \ \ \
/ / / \ \ \
/ / / \ \
expresie * expresie expresie * expresie
| | | |
nume nume nume nume
| | | |
A B C D

Orice analizor sintactic realizeaz traducerea unui ir de atomi lexicali ntr-un astfel de arbore de
derivare care descrie relaia ierarhic ntre o descriere general a propoziiei analizate (rdcina arborelui)
i irul de atomi lexicali din care este format (frunzele). Un analizor sintactic poate s construiasc efectiv
o structur de date de tip arbore (cu pointeri i nregistrri) sau poate s sintetizeze informaiile din care se
poate face construcia acestuia.
1.3 Analiza semantic

Aceast faz este de obicei incorporat n faza de analiz sintactic. Rolul acestei faze const din
verificarea din punct de vedere semantic a structurilor recunoscute drept corecte din punct de vedere
sintactic. Majoritatea verificrilor realizate de ctre aceast faz se refer la tipurile construciilor. De
asemenea aceast faz completeaz arborele de derivare cu o serie de informaii necesare generrii de cod.
1.4 Generarea de cod intermediar

Nici aceasta faz nu este ntotdeauna separat de analiza sintactic, exist compilatoare care
genereaz cod chiar n timpul analizei sintactice. Generarea de cod se face prin parcurgerea arborelui de
derivare. Forma intermediar care se genereaz reprezint codul obiect pentru o main virtual. Utilizarea
formelor intermediare se justifica prin cteva argumente. n primul rnd anumite optimizri nu se pot face
n timpul analizei sintactice i sunt dificil de realizat pe un text de program ntr-un limbaj de programare
de nivel foarte sczut. De exemplu scoaterea expresiilor constante n afara ciclurilor. Alt motiv este
utilizarea aceleai faze de optimizare i generare de cod main pentru diferite limbaje de programare,
respectiv utilizarea aceleai faze de analiza sintactic, semantic i generare de cod intermediar pentru a
implementa acelai compilator (limbaj) pe maini diferite. Cu alte cuvinte pentru a realiza implementri
portabile pentru compilatoare. De asemenea utilizarea unei maini virtuale permite realizarea mai simpl
de compilatoare incrementale sau interpretoare performante. Acest tip de translatoare execut direct
(interpreteaz) codul intermediar fr a mai trece prin fazele urmtoare - editare de legturi, ncrcare, etc.,
dar i fr a recunoate de fiecare dat o instruciune care a fost deja tratat, cum s-ar ntmpla dac
interpretarea s-ar face la nivel de limbaj surs.
Dezavantajul utilizrii unei forme intermediare const n mod evident din mrirea timpului necesar
pentru execuia unei compilri.
1.5 Optimizarea codului intermediar

Aceast faz identific optimizrile posibile asupra codului n limbaj intermediar. De exemplu pentru
o secven ca:

Irina Athanasiu 3/1/2002 Limbaje formale i automate

6
for(....){
a[i * c] = b[i * d] + e + f;
...
}

Se observ c o parte din calcule se pot efectua o singur dat nainte de ciclul for, rezultatele
respective se pot memora n variabile temporare, etc. Desigur astfel de optimizri pot s fie fcute i de
ctre programator. Este de preferat ns s se pstreze claritatea programului, iar acest tip de transformri
s fie realizate de ctre compilator.
1.6 Generarea codului obiect

Aceast faz depinde de maina pentru care compilatorul trebuie s genereze cod i care poate s fie
diferit de maina pe care se execut compilatorul (cazul cross compilatoarelor). Aceast faz depinde de
arhitectura mainii int. Ideea este c pentru fiecare instruciune n limbaj intermediar se va alege o
secven echivalent de instruciuni obiect.
1.7 Optimizarea codului obiect

i aceast faz depinde de maina pentru care se genereaz cod. i anume se identific secvene de
cod main care pot s fie nlocuite cu instruciuni mai rapide.
1.8 Gestiunea tabelei de simboluri

n tabela de simboluri se nregistreaz identificatorii utilizai n program i informaii asupra acestora.
Aceste informaii pot s se refere la tip, domeniu de valabilitate; dac este vorba de identificatori de tip
nume de funcie la aceste informaii se adaug i signatura funciei (numrul i tipul argumentelor, modul
de transfer i eventual tipul rezultatului). n general o tabel de simboluri este o structur de date care
conine cte o nregistrare pentru fiecare identificator avnd cmpuri pentru atributele posibile.
Introducerea simbolurilor n tabela se face de ctre analizorul lexical. Atributele acestora sunt completate
n tabela de ctre analizoarele sintactic i semantic.
1.9 Detectarea erorilor

Fiecare faz a unui compilator poate s identifice prezena unei erori specifice. De exemplu, n analiza
lexical ntlnirea unui ir care nu corespunde unui atom lexical; n analiza sintactica se identific erori
legate de structura instruciunilor. Ca de exemplu pentru irul:

int real alfa;

fiecare atom lexical n parte este corect dar nu formeaz mpreun o propoziie corect din punct de
vedere sintactic. n faza de analiz semantic se verific dac construciile corecte din punct de vedere
sintactic sunt corecte i din punct de vedere semantic. De exemplu dac la nivelul sintaxei poate s apar
ca fiind corecta o expresie de forma: nume + nume, fr nici o restricie asupra tipului identificatorilor
corespunztori, este rolul analizei semantice s identifice ca eronat o expresie n care primul nume este al
unui vector iar al doilea nume este al unei proceduri.
Problema cea mai dificil legat de tratarea erorilor const din modul n care se continu analiza dup
identificarea unei erori, pentru c un compilator care se oprete la prima eroare ntlnit nu este prea
comod de utilizat. Excepie face modul de abordare utilizat n primele versiuni ale compilatorului pentru
TURBO Pascal pentru care la ntlnirea unei erori se revine n regim de editare pentru corectarea acesteia.
Irina Athanasiu 3/1/2002 Limbaje formale i automate

7
2 Elemente de teoria limbajelor formale

Fie T o mulime de simboluri denumita alfabet. Orice submulime a mulimii T* reprezint un limbaj
asupra alfabetului T. Elementele limbajului se numesc propoziii. Dac limbajul este finit atunci el poate
s fie definit prin enumerare. De exemplu considernd alfabetul B = {0, 1} atunci L = {01, 10, 101} este
un limbaj. Mulimea cuvintelor din limbajul natural este i el un limbaj pentru care se poate pune
problema enumerrii tuturor cuvintelor, chiar dac lista care ar rezulta este imens, deci este un limbaj
reprezentabil prin enumerare. Dar cazul interesant este cel n care limbajul este infinit. S considerm de
exemplu limbajul "irurilor formate din 0 i 1 a cror lungime este divizibila cu 3". Evident este vorba de
un limbaj infinit. Textul prin care am specificat limbajul constituie o reprezentare finit a limbajului. Nu
este singura soluie posibil de reprezentare finit. De exemplu dac notam cu L limbajul respectiv atunci:

L = { w {0,1}* | |w| mod 3 = 0}

este un alt mod de a specifica acelai limbaj.
Se pune problema dac dndu-se un limbaj oarecare este posibil ntotdeauna construirea unei
reprezentri finite. S considerm c o astfel de reprezentare finit se realizeaz utiliznd simboli dintr-un
alfabet finit A. Se poate demonstra c mulimea A
*
este infinit numrabil (se poate construi o bijecie f :
N A
*
). Deci exist o mulime infinit numrabil de reprezentri finite. Numrul de limbaje ce se pot
construi utiliznd simboli dintr-un alfabet dat T, este 2
|T*|
deci mulimea limbajelor este infinit
nenumrabila. Rezult deci c ar trebui s reprezentm un numr infinit nenumrabil de obiecte avnd la
dispoziie numai un numr infinit numrabil de reprezentri. Din acest motiv nu orice limbaj va putea s
fie reprezentabil ntr-un mod finit. Nu putem s oferim un exemplu de limbaj pentru care nu avem o
reprezentare finit pentru c exemplul ar fi tocmai o reprezentare finit a limbajului respectiv. Spre
norocul nostru, nu suntem interesai de toate limbajele ci numai de o clas mai mic a limbajelor infinite
cu reprezentri finite.
n general exist doua mecanisme distincte de definire finit a limbajelor: prin generare sau prin
recunoatere. n primul caz este vorba de un "dispozitiv" care tie s genereze toate propoziiile din limbaj
(i numai pe acestea) astfel nct alegnd orice propoziie din limbaj ntr-un interval finit de timp
dispozitivul va ajunge s genereze propoziia respectiv. n al doilea caz este vorba de un "dispozitiv" care
tie s recunoasc (s accepte ca fiind corecte) propoziiile limbajului dat.
2.1 Gramatici

O gramatic reprezint cel mai important exemplu de generator de limbaje. Prin definiie o gramatic
este G = (N, T, P, S) unde :

N este o mulime finit de simboli numit mulimea simbolilor neterminali;
T este o mulime finit de simboli numit mulimea simbolilor terminali,
(T N = );
P este o submulime finit din (N T)
*
N (N T)
*
x (N T)
*
; numit mulimea produciilor
gramaticii. Un element (, ) P este notat cu i se numete producie.
S N este un simbol special numit simbol de start al gramaticii G.

n cele ce urmeaz vom utiliza o serie de notaii devenite "clasice". i anume :

literele mici de la nceputul alfabetului latin (a,b,c,...) reprezint elemente din T (simboli terminali);
literele mici de la sfritul alfabetului latin (u, v, x,...) reprezint elemente din T* (iruri de simboli
terminali);
Irina Athanasiu 3/1/2002 Limbaje formale i automate

8
literele mari de la nceputul alfabetului latin (A, B, C,...) reprezint elemente din N (simboli
neterminali);
literele mari de la sfritul alfabetului latin (U, V, X,...) reprezint elemente din N T (simboli
terminali sau neterminali);
literele alfabetului grecesc (, , ...) reprezint iruri din (N T)* (iruri de simboli terminali i
neterminali).

O form propoziional pentru o gramatic G se definete recursiv n modul urmtor:

(1) S este o form propoziional;
(2) dac este o forma propoziional i exist o producie atunci este o
form propoziional.

O form propoziional care conine numai simboli terminali se numete propoziie generat de G.
Notm cu L(G) mulimea tuturor propoziiilor generate de G altfel spus L(G) este limbajul generat de
gramatica G.
Se observ c o gramatic este o reprezentare finit (toate elementele sale sunt finite) pentru un limbaj
care poate s fie infinit. Conform observaiei fcute la nceputul acestui capitol nu orice limbaj are o
reprezentare finit, cu alte cuvinte nu pentru orice limbaj exist o gramatic care s l reprezinte.
Dou gramatici G i G' sunt echivalente dac i numai dac L(G) = L(G').
Asupra formelor propoziionale se definete o relaie numit relaie de derivare n modul urmtor.
Fie i doua forme propoziionale, dac i numai dac exist w1, w2 i P astfel nct
= w1 w2 i = w1 w2.
Relaia poate s fie extins obinndu-se derivarea n k pai. i anume
k
dac exist
0
,
1
,
...,
k
forme propoziionale astfel nct =
0
,
i-1

i
,1 i k i
k
= .
nchiderea tranzitiv a relaiei se noteaz cu
+
. nchiderea tranzitiv i reflexiv a relaiei se
noteaz cu =
*
>.
S considerm de exemplu gramatica G = ({A,S}, {0,1}, P, S) unde P = {S 1A1, S 0S0, 1A
11A1, A } (cu s-a notat irul vid de simboli). O derivare posibil este:

S 0S0 00S00 001A100 0011A1100 00111100

deci 00111100 este o propoziie n L(G).

n general L(G) = { w | w T
+
, S
+
w}.
2.1.1 Ierarhia Chomsky.

Noam Chomski este lingvist i lucreaz n domeniul limbajelor naturale. Ierarhia care i poarta
numele a rezultat dintr-o ncercare a acestuia de a formaliza limbajele naturale. Gramaticile sunt clasificate
conform complexitii produciilor n urmtoarea ierarhie :

gramatici de tip 0 (fr restricii) - au produciile de forma:

cu (N T)
*
N (N T)
*
, (N T)
*


gramatici de tip 1 (dependente de context) - au produciile de forma :

A , , (N T)
*
, A N, (N T)
+


Irina Athanasiu 3/1/2002 Limbaje formale i automate

9
sau de forma

S

n al doilea caz S nu apare n membrul drept al nici unei producii. Se utilizeaz termenul de
dependen de context deoarece producia A poate s fie interpretat sub forma - dac
simbolul neterminal A apare ntre i atunci poate s fie nlocuit cu .

gramatici de tip 2 (independente de context) - au produciile de forma :

A , A N, (N T)
*
.

Denumirea de independent de context apare n contrast cu gramaticile de tipul 1 (dependente de
context)

gramatici de tip 3 (regulate la dreapta) au producii de forma:

A aB cu A N , B (N {}) si a T
+
.

Corespunztor gramaticilor, despre limbajele generate de acestea se poate spune respectiv c sunt
regulate, independente de context, dependente de context sau de tipul zero. Se poate arata c un limbaj ce
poate s fie generat de o gramatic regulat poate s fie generat i de ctre o gramatic independent de
context. Un limbaj independent de context poate s fie generat i de o gramatic dependent de context iar
un limbaj dependent de context poate s fie generat i de o gramatic de tipul zero. Deoarece cu ct o
gramatic este mai restrictiv ea reprezint un mecanism mai simplu, suntem ntotdeauna interesai de cea
mai restrictiv gramatic care reprezint un limbaj dat.
S considerm cteva exemple:

a) G1 = ({S},{0,1},{S 0S, S 1S, S }, S). Se observ c G1 este o gramatic regulat care
genereaz limbajul {0,1}*
b) G2 = ({S, A},{0,1},{S AS, S , A , A 0, A 1}, S). Se observ c G2 este o
gramatic independent de context iar limbajul generat este tot {0,1}*. Rezult deci c un acelai limbaj
poate s fie definit de mai multe gramatici diferite eventual chiar de tipuri diferite.
c) G3 = ({, T, F},{a, +, *, (, )}, P, ) cu P = { + T, T, T T * F, T F, F (), F
a}. S considerm un exemplu de derivare n aceast gramatic :

+ T T + T F + T a + T a + T * F a + F * F a + a * F a + a * a.

Se observ c gramatica G3 este o gramatic independent de context i este o gramatica care descrie
limbajul expresiilor aritmetice cu paranteze care se pot forma cu operandul a i cu operatorii + i *.
n cele ce urmeaz pentru simplificarea notaiilor dac pentru un neterminal exist mai multe producii
: A w1, A w2, ... A wk le vom reprezenta sub o form mai compact: A w1 | w2 | ... | wk.

De asemenea pentru specificarea unei gramatici nu vom mai preciza n general dect mulimea
produciilor sale, celelalte elemente rezultnd n mod banal din aceasta.
2.1.1.1 Exerciii

S se construiasc gramaticile care genereaz limbajul:

Irina Athanasiu 3/1/2002 Limbaje formale i automate

10
1. irurilor formate din simboli a i b avnd un numr egal de a i b.
2. {a
n
b
n
| n 1}
3. {a
n
b
m
c
m
d
n
| n 1, m 1}
4. {a
n
b
n
c
m
d
m
| n 1, m 1}
5. irurilor formate cu simboli a i b care nu conin subirul abb
6. irurilor formate cu simboli a i b avnd lungimea divizibil cu 3
7. {a
i
b
j
| i /= j, i, j > 0}
8. {a
m
b
n
| n < m sau n > 2m, n, m 1}
9. irurilor formate dintr-un numr par de simboli a i un numr impar de simboli b
10.irurilor formate din simboli a, b i c, pentru care toi simboli a apar nainte de toi
simboli b iar toi simboli b apar nainte de toi simboli c
11.{a
n
b
n
c
n
| n >_ 1}
12.{xcx
R
|x {a,b}*}, {xx
R
|x {a,b}*}, {x = x
R
|x {a,b}
*
}
13.{xx | x {a,b}*}
14.{a
n
b
n
c
n
| n 1 }
15.listelor de elemente care pot s nu conin nici un element, respectiv trebuie s conin
cel puin un element, construirea listei este asociativ dreapta respectiv stnga (vor
rezulta 4 variante)

2.1.2 Verificarea limbajului generat de ctre o gramatic

n toate exemplele considerate pn acum s-a fcut "ghicirea" gramaticii care genereaz un limbaj dat
sau a limbajului generat de ctre o gramatic dat. Se pune ns problema cum se poate demonstra
corectitudinea rezultatului unei astfel de ghiciri. S considerm de exemplu gramatica:

G = ({S}, {(,)}, {S (S)S | }, S)

Aceast gramatica genereaz toate irurile de paranteze bine nchise (echilibrate). Dorim ns s
demonstrm aceast afirmaie. De fapt aici trebuie s demonstrm egalitatea a dou mulimi: mulimea
reprezentat de limbajul generat de G i mulimea irurilor de paranteze bine formate. Deci demonstraia
presupune demonstrarea dublei incluziuni. Adic trebuie s demonstrm c orice ir derivat din S satisface
condiia enunat i apoi trebuie s demonstrm incluziunea n sens invers. Dndu-se un ir de paranteze
bine nchise trebuie s artm c acest ir poate s fie derivat din S. Pentru prima parte a demonstraiei
vom utiliza inducia asupra numrului de pai n derivare. Considerm c irul vid care se obine ntr-un
pas din S este un ir de paranteze bine nchise. S presupunem c pentru toate derivrile realizate n mai
puin de n pai se obin iruri de paranteze bine nchise i s considerm o derivare de exact n pai. O
astfel de derivare poate s arate ca :

S (S)S
*
(x)S
*
(x)y

unde x i y sunt iruri de terminale derivate din S n mai puin de n pai, adic sunt iruri de paranteze
bine nchise. Rezult c irul (x)y este un ir de paranteze bine nchise. Cu alte cuvinte orice ir derivat din
S este "corect".
S considerm acum i includerea n sens invers. De data asta demonstraia se face prin inducie
asupra lungimii irului. Pentru primul pas observm c irul vid este un ir derivabil din S. S presupunem
acum ca orice ir cu mai puin de 2n simboli este derivabil din S. S considerm un ir w de paranteze bine
nchise avnd lungimea de 2n, cu n mai mare sau egal cu 1. Sigur irul ncepe cu o parantez deschis. Fie
(x) cel mai scurt prefix format din paranteze bine nchise. Se observ c w = (x)y, unde x i y sunt iruri
Irina Athanasiu 3/1/2002 Limbaje formale i automate

11
de paranteze bine nchise de lungime mai mic dect 2n. n acest caz x i y pot s fie derivate din S.
Rezult c exist o derivare:

S (S)S * (x)y

n care pentru obinerea irurilor x i respectiv y s-au utilizat mai puin de 2n pai i deci w este un ir
derivabil din S. Desigur o astfel de demonstraie este practic imposibil de realizat pentru un limbaj
"adevrat". n general se pot face ns demonstraii "pe poriuni".

2.1.2.1 Exerciii

1. Fie gramatica G : S AA, A AAA, a, A bA, Ab, s se arate ca limbajul L(G) este limbajul
tuturor irurilor formate din simboli a avnd un numr par de simboli.
2. Fie gramatica G : S aB | bA, A a | aS | bAA, B b | bS | aBB s se arate ca L(G) este setul
tuturor irurilor din {a,b}
+
care au un numr egal de apariii pentru a i pentru b.

2.1.3 Transformri asupra gramaticilor independente de context

Din punctul de vedere al procesului de compilare, gramaticile sunt utilizate pentru faza de analiz
sintactic, pentru care se utilizeaz gramatici independente de context. Exist o serie de metode de analiza
sintactic, bine puse la punct att din punct de vedere teoretic ct i practic. Fiecare dintre aceste metode
impune ns o serie de restricii asupra gramaticilor utilizate. n general atunci cnd se construiete o
gramatic se pleac de la forma general a structurilor pe care aceasta trebuie s le descrie i nu de la
metoda de analiza sintactica ce va fi utilizat. n acest mod se obine o gramatic ce poate s fie "citit"
uor de ctre proiectant. Pentru a satisface ns condiiile impuse de ctre metodele de analiza sintactic
sau de ctre generarea de cod, se realizeaz transformri asupra gramaticilor. Aceste transformri trebuie
s pstreze neschimbat limbajul generat. n cele ce urmeaz vom prezenta cteva transformri tipice
asupra gramaticilor independente de context. Pentru a explica semnificaia acestor transformri n
contextul analizei sintactice vom prezenta nti noiunea de arbore de derivare.
Un arbore de derivare este o reprezentare grafic pentru o secven de derivri (de aplicri ale relaiei
ntre formele propoziionale). ntr-un arbore de derivare nu se mai poate identifica ordinea n care s-a
fcut substituia simbolilor neterminali. Fiecare nod interior arborelui, reprezint un neterminal.
Descendenii unui nod etichetat cu un neterminal A sunt etichetai de la stnga la dreapta prin simbolii
care formeaz partea dreapt a unei producii care are n partea stnga neterminalul A. Parcurgnd de la
stnga la dreapta frunzele unui astfel de arbore se obine o form propoziional. S considerm de
exemplu din nou gramatica irurilor de paranteze bine formate:

G = ({S}, {(,)}, {S (S)S | }, S)

Fie urmtoarea secven de derivri:

S ( S ) S ( ( S ) S ) S ( () S ) S
( () ( S ) S ) S ( () () S ) S
( () () ) S ( () () ) ( S ) S
+
( ()() ) ()

Se obine arborele de derivare:
Irina Athanasiu 3/1/2002 Limbaje formale i automate

12
S

/ / \ \
/ / \ \
/ / \ \
( S ) S

/ / \ \ / / \ \
/ / \ \ ( S ) S
/ / \ \ | |
( S ) S
|
/ / \ \
/ / \ \
( S ) S
| |


Arborele de derivare este construit de ctre analizorul sintactic. Aceasta construcie se poate face
pornind de la rdcin aplicnd succesiv producii - n acest caz se spune c analiza sintactic este top-
down (descendent). Dar, se poate porni i invers de la irul de atomi lexicali (frunze) identificndu-se
simbolii neterminali din care se poate obine un ir de atomi lexicali. n acest caz se spune c analiza
sintactic este de tip bottom-up (ascendent).
Deoarece arborele de derivare descrie relaia ierarhica ntre entitile sintactice (neterminale) i atomii
lexicali (terminale) se poate asocia o interpretare n termeni de evaluare a entitilor sintactice. Astfel,
considernd de exemplu gramatica expresiilor aritmetice pentru irul a + a * a se obine arborele derivare :


/ | \
/ | \
+ T
| / | \
T / | \
| T * F
F | |
| F a
a |
a

n care se poate observa c a fost evideniat faptul c operaia de nmulire este prioritar fa de
operaia de adunare (aspect semantic).
2.1.3.1 Eliminarea ambiguitii

O gramatic care produce mai muli arbori de derivare pentru aceeai propoziie este o gramatic
ambigu. Deoarece exist tehnici de analiz sintactic care lucreaz numai cu gramatici neambigue vom
ncerca s construim gramatici care genereaz acelai limbaj i care sunt neambigue. S considerm de
exemplu urmtoarea gramatic :

instr if expresie then instr |
if expresie then instr else instr |
alte_instr

S construim arborele de derivare pentru propoziia :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

13

if E1 then if E2 then S1 else S2

instr
/ /\ \
/ / \ \
/ / \ \
/ expr \ \
/ / \ then \
if / E1 \ \
------- instr
/ /\ \ \ \
/ / \ \ \ \
/ / \ \ \ \
/ expr \ \ \ \
/ / \ then \ \ \
if / E2 \ \ \ \
------- instr \ \
/ \ else \
/ S1 \ instr
------ / \
/ S2 \
------

Pentru aceast propoziie mai exist ns un arbore de derivare.

instr
/ / \ \ \ \
/ / \ \ \ \
/ / \ \ \ \
/ expr \ \ \ \
/ / \ then \else \
if / E1 \ \ \
------- instr instr
/ \ / \
/ /\ \ / S2 \
/ / \ \ ------
if / then\
expr instr
/ \ / \
/ E2 \ / S1 \
------ ------

n toate limbajele de programare care accept construcii de tip if then else se consider cu sens prima
derivare n care fiecare clauza else este atribuit instruciunii if cea mai interioar. Rezult deci condiia pe
care trebuie s o satisfac o instruciune if. Instruciunea cuprins ntre then i else trebuie s nu fie o
instruciune if sau s fie o instruciune if cu clauza else. Rezult urmtoarea gramatic obinut prin
transformarea gramaticii anterioare:

instr if_cu_else| if_fara_else
if_cu_else if expresie then if_cu_else else if_cu_else |
alte_instr
if_fara_else if expresie then instr |
if expresie then if_cu_else else if_fara_else

Se observ c aceast gramatic genereaz acelai limbaj cu gramatica anterioar dar accept o
derivare unic pentru propoziia :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

14

if E1 then if E2 then S1 else S2

instr
|
if_fara_else
/ /\ \
/ / \ \
/ / \ \
/ expr \ \
/ / \ then \
if / E1 \ \
------- instr
|
if_cu_else
/ /\ \ \ \
/ / \ \ \ \
/ / \ \ \ \
/ expr \ \ \ \
/ / \ then \ \ \
if / E1 \ \ \ \
------- instr \ \
/ \ else \
/ S1 \ instr
------ / \
/ S2 \
------

Se numete producie ambigu o producie care are n partea dreapt mai multe apariii ale aceluiai
simbol neterminal. Existena unei producii ambigue nu implic faptul c gramatica este ambigu. S
considerm gramatica G = ({S, A}, {a, b, c }, {S aAbAc, A a | b}). Se observ c aceast gramatic
nu este ambigu, gramatica genernd limbajul {aabac, aabbc, abac, abbc}
S considerm de exemplu i gramatica pentru expresii aritmetice:

G = ({}, {a, +, *}, { + | * | a}, )

Gramatica G este o gramatic ambigu (se poate verifica uor utiliznd de exemplu irul a + a * a). n
gramatica G nu au fost evideniate relaiile de preceden dintre operatori. Aceasta gramatica poate s fie
transformata ntr-o gramatica neambigu n care operaia de nmulire este mai prioritar dect cea de
adunare n doua moduri:

1. + T | T
T T * F | F
F a

2. T + | T
T F * T | F
F a

Fie irul a * a * a. Pentru cele doua gramatici se obin arborii de derivare respectivi:

Irina Athanasiu 3/1/2002 Limbaje formale i automate

15

| |
T T
/ | \ / | \
/ | \ / | \
T * F F * T
/ | \ | | / | \
/ | \ a a / | \
T * F F * T
| | | |
F a a F
| |
a a

Se observ c primul arbore evideniaz asociativitatea stnga a operatorului * n timp ce al doilea
arbore evideniaz asociativitatea dreapta. n funcie de definiia limbajului este de preferat prima variant
sau a doua.
n cazul general dac pentru un neterminal A exist produciile:

A A B A |
1
|
2
| ... |
n
, BN,
1
, ...
n
T*

acestea pot s fie nlocuite cu:

A A' B A | A'
A' A |
1
|
2
| ... |
n


Producia A' A poate s fie eliminat (exist i A A') i se obine:

A A' B A | A'

A'
1
|
2
| ... |
n


Dac se construiete arborele de derivare se observ c n acest caz se utilizeaz asociativitatea
dreapt. Pentru a se descrie asociativitatea stnga se utilizeaz transformarea:

A A B A' | A'
A'
1
|
2
| ... |
n
.

Trebuie s remarcam ns faptul c exist limbaje pentru care nu se pot construi gramatici neambigue.
Un astfel de limbaj se numete inerent ambiguu. De exemplu limbajul :

L = { a
i
b
j
c
k
d
l
| i = k sau j = l, i, j, k, l 0}

este inerent ambiguu. O gramatic care descrie acest limbaj va trebui probabil s considere c L este
de fapt reuniunea a dou limbaje:

L = { a
n
b
j
c
n
d
l
| n, j, l 0} i L = { a
i
b
n
c
k
d
n
| i, n, j, k 0}

Un ir de forma a
p
b
p
c
p
d
p
va face parte din ambele limbaje i deci probabil c va avea doi arbori de
derivare. Exemplul anterior nu constituie ns o demonstraie, o demonstraie adevrat depete ca
dificultate cadrul textului curent.
Irina Athanasiu 3/1/2002 Limbaje formale i automate

16
2.1.3.2 Eliminarea - produciilor

Se spune ca o gramatic este - free dac satisface una dintre urmtoarele condiii:
a. Nu exist nici o producie care s aib n partea dreapta irul vid
b. Exist o singura producie care are n partea dreapta irul vid i anume o producie de forma S
. Simbolul S nu apare n acest caz n partea dreapt a nici unei producii.

Algoritmul de transformare pleac de la gramatica G = (N, T, P, S) i construiete gramatica G' = (N',
T, P', S') care satisface condiiile :

(i) L(G) = L(G')
(i) G' este - free.

Descrierea algoritmului este :

i = 0
N
i
= {A | A P}
repeta
i = i + 1
N
i
= { A | A P, a N*
i-1
} N
i-1
pn N
i
= N
i-1

N
e
= N
i

dac S N
e
N' = N {S'}
P' = {S' , S' S}
altfel
N' = N
S' = S
P' =

pentru fiecare p P executa
dac p este de forma : A a
0
B
1
a
1
... B
k
a
k
, k 0,
B
i
N
e
, 1 i k, a
j
((N \ N
e
) T)
*
, 0 j k
P' = P' ({A a
0
X
1
a
1
... X
k
a
k
| X
i
{B
i
, }} \{A })

altfel
P' = P' {p}



Fie de exemplu gramatica S aSbS | bSaS | . Aplicnd algoritmul anterior se obine:

S' S, S aSbS | aSb | abS | ab | bSaS | bSa | baS | ba
2.1.3.3 Eliminarea recursivitii stnga

O gramatic este recursiv stnga dac exist un neterminal A astfel nct exist o derivare A
+
A
pentru (T N)*. O analiz sintactic descendent determinist nu poate s opereze cu o astfel de
gramatic, deci este necesar o transformare. S considerm nti cazul cel mai simplu pentru care n
gramatic exist producii de forma A A | . n acest caz limbajul generat este de forma
n
cu n 0.
Acelai limbaj poate s fie generat de ctre gramatica: A A', A' A'| .
Irina Athanasiu 3/1/2002 Limbaje formale i automate

17
S considerm de exemplu gramatica expresiilor aritmetice :

+ T | T, T T * F | F, F () | a

Se observ c pentru un ir de forma a + a * a, examinnd numai primul simbol terminal(a) nu este
clar cu care dintre produciile pentru trebuie s se nceap derivarea. Aplicnd ideea anterioar se obine
:

T ', ' +TE' | , T FT', T' *FT' | , F () | a

n acest caz derivarea va ncepe sigur prin aplicarea produciei TE' i se obine derivarea TE'
FT''. n acest moment se vede c pentru F trebuie s se aplice producia F a. Deci se obine
+

aT''. Urmeaz simbolul terminal + datorit cruia pentru T' se va aplica producia T' , etc.
n general dac pentru un neterminal A exist produciile :

A A
1
|A
2
| ... |A
m
|
1
|
2
| ... |
n


unde
i
nu ncepe cu A, 1 i n, se pot nlocui aceste producii cu :

A
1
A' |
2
A' | ... |
n
A'
A'
1
A' |
2
A' | ... |
m
A'|

Aceast construcie elimin recursivitatea stng imediat. S considerm ns gramatica:

A
1
A
2
a | b
A
2
A
3
c | d
A
3
A
1
e | f

cu A
1
simbolul de start al gramaticii. Se observ c este posibil urmtoarea derivare:

A
1
A
2
a => A
3
ca => A
1
eca

deci gramatica este recursiv stnga. Se observ c dac am considerat o ordine a simbolilor, toate
produciile mai puin ultima, respect regula "un simbol neterminal este nlocuit de un ir care ncepe cu
alt simbol neterminal cu un numr de ordine mai mare". Existena unei producii care nu respect condiia
conduce la apariia recursivitii stnga.
Dac gramatica nu permite derivri de tipul A
+
A (fr cicluri) i nu conine - producii poate s
fie transformat n vederea eliminrii recursivitii stnga utiliznd urmtorul algoritm, obinndu-se o
gramatic echivalent fr recursivitate stnga.



Irina Athanasiu 3/1/2002 Limbaje formale i automate

18

Se aranjeaz neterminalele n ordinea A1, ..., An
pentru i = 1 pn la n executa
pentru j = 1 pn la i - 1 executa
nlocuiete fiecare producie de forma A
i
A
j
cu
produciile A
i

1
|
2
| ... |
k

unde A
j

1
|
2
| ... |
k
sunt toate produciile
pentru A
j


elimin recursivitatea stnga ntre produciile A
i



S considerm pasul i. Produciile A
k
A
l
care au mai rmas (pentru care k < i), au l > k. n aceasta
iteraie prin variaia lui j se ajunge ca pentru orice producie de forma A
i
A
m
, m i. Dac se elimin
recursivitatea direct rmne m > i. S considerm de exemplu din nou gramatica :

A
1
A
2
a | b, A
2
A
2
c | A
1
d | e

Considerm pentru neterminale ordinea : A
1
, A
2
. Pentru A
1
(i = 1) nu exist recursivitate stnga
direct deci nu se face nici o modificare. Pentru i = 2, producia A
2
A
1
d se inlocuiete cu A
2

A
2
ad | bd. Rezult deci c A
2
A
2
c | A
2
ad | bd | e.
Eliminnd recursivitatea stnga se obine :

A
1
A
2
a | b, A
2
bdA
2
' | eA
2
', A
2
' cA
2
' | adA
2
' |
2.1.3.4 Factorizare stnga

Acest tip de transformare este util pentru producerea unei gramatici potrivite pentru analiza sintactic
descendent de tip determinist. Ideea este c dac nu este clar care dintre produciile alternative poate s
fie aplicat pentru un neterminal se va amna luarea unei decizii pn cnd s-a parcurs suficient din irul
de intrare pentru a se putea lua o decizie. S considerm de exemplu produciile :

S A b S | A
A B c A | B
B a | dSd

S presupunem c ncercm s construim irul derivrilor pentru a b a c a pornind de la simbolul de
start al gramaticii. Din recunoaterea simbolului a la nceputul irului nu se poate nc trage concluzia care
dintre cele doua producii corespunztoare neterminalului S trebuie s fie luata n considerare (abia la
ntlnirea caracterului b pe irul de intrare se poate face o alegere corect). n general pentru producia A
1 | 2 dac se recunoate la intrare un ir nevid derivat din nu se poate tii dac trebuie aleas
prima sau a doua producie. Corespunztor este util transformarea: A A', A' 1 | 2.
Algoritmul de factorizare funcioneaz n modul urmtor. Pentru fiecare neterminal A se caut cel mai
lung prefix comun pentru dou sau mai multe dintre produciile corespunztoare neterminalului A. Dac
atunci se nlocuiesc produciile de forma A
1
|
2
| ... |
n
| (unde reprezint alternativele
care nu ncep cu ) cu :


A A' |
A'
1
|
2
| ... |
n

Irina Athanasiu 3/1/2002 Limbaje formale i automate

19

A' este un nou neterminal. Se aplic n mod repetat aceast transformare pn cnd nu mai exist dou
alternative producii cu un prefix comun pentru acelai simbol neterminal.
Relund exemplul considerat se obine :

S AX
X bS |
A BY
Y cA |
B a | dSd

Deci n analiza irului a b a la ntlnirea simbolului b pentru neterminalul Y se va utiliza producia Y
, n acest mod rezult irul de derivri :

S AX BYX aYX ...
2.1.3.5 Eliminarea simbolilor neterminali neutilizai

Un simbol neterminal neutilizat este un simbol care:
nu poate s apar ntr-o form propoziional, adic ntr-un ir derivat din simbolul de start al
gramaticii (simbol inaccesibil)
din care nu poate deriva un ir format numai din simboli terminali (simbol nefinalizabil)
care apare n formele propoziionale numai datorit sau mpreun cu simboli neterminali ce
satisfac una dintre condiiile anterioare.
Pornind de la o gramatic G = (N, T, P, S) se poate obine o gramatic fr simboli nefinalizai i care
satisface urmtoarele condiii:

(i) L(G) = L(G')
(i) A N, A
+
w, w T
*
.

utiliznd urmtorul algoritm :

N
0
=
i = 0
repeta
i = i + 1
N
i
= { A | A P si (N
i-1
T)
*
} N
i-1

pn N
i
= N
i-1
N' = N
i

P' P conine numai produciile din P care au n partea stnga simboli din N' si n
partea dreapta simboli din N' si T.

Prin inducie asupra numrului de pai se poate demonstra corectitudinea algoritmului. S considerm
ca exemplu o gramatic avnd produciile : P = {S A, A a, B b, B a}, se observ c B este un
simbol neterminal inaccesibil. Aparent condiia de inaccesibilitate pentru un neterminal const din ne
apariia n partea dreapt a unei producii. Dac ns considerm o gramatic avnd produciile: {S A,
A a, B cC, C bB} se observ c este necesar o alt condiie.
Pornind de la o gramatic G = (N, T, P, S) se poate construi o gramatic fr simboli inaccesibili G' =
(N', T, P', S) care s satisfac condiiile:
(i) L(G) = L(G')
Irina Athanasiu 3/1/2002 Limbaje formale i automate

20
(i) A N', w (N T)
*
, S w i A apare n w

utiliznd urmtorul algoritm.


N
0
= {S}
i = 0
repeta
i = i + 1;
N
i
= {A | A apare n partea dreapta a unei producii
pentru un neterminal din N
i-1
} N
i-1
pn N
i
= N
i-1

N' = N
i

P' conine numai producii care corespund neterminalelor din
N' si care conin n partea dreapta simboli neterminali numai din N'

Prin inducie asupra numrului de pai se poate determina corectitudinea algoritmului. Utiliznd
algoritmii pentru eliminarea simbolilor nefinalizai i cel pentru eliminarea simbolilor inaccesibili se
obine o gramatic care nu conine simboli neutilizai. Ordinea n care se aplic aceti algoritmi nu este
indiferent. S considerm de exemplu gramatica cu produciile:

S a | A, A AB, B b.

Dac se aplic nti algoritmul pentru eliminarea simbolilor nefinalizai, rmn produciile S
a i B b. Prin eliminarea simbolilor inaccesibili rmne numai producia S a. Dac ns se
aplic nti algoritmul pentru eliminarea simbolilor inaccesibili i apoi cel pentru eliminarea simbolilor
nefinalizai vor rmne pn la sfrit produciile S a i B b, adic nu se obine o gramatic fr
simboli neutilizai. Rezultatul obinut nu este ntmpltor n sensul c nu se poate gsii un exemplu pentru
care ordinea corect de aplicare a celor doi algoritmi s fie invers. Ideea este c prin eliminarea unui
simbol neterminal neaccesibil nu pot s apar simboli neterminali nefinalizai, n timp ce prin eliminarea
unui simbol neterminal nefinalizat pot s apar simboli neterminali inaccesibili deoarece anumii simboli
neterminali puteau s fie accesibili numai prin intermediul simbolului neterminal respectiv.
2.1.3.6 Substituia de nceputuri(corner substitution)

Anumite metode de analiz sintactic impun ca partea dreapt a fiecrei producii care nu este irul
vid s nceap cu un terminal. S considerm de exemplu gramatica avnd produciile:

lista a(numr) lista | *elem lista | a
elem a(numr) | *elem

n acest caz dac pe irul de intrare se gsete terminalul a nu este clar care dintre produciile pentru
neterminalul lista trebuie s fie utilizat.

Dac factorizm produciile neterminalului lista:

lista aX | *elem lista
X (numr) lista |
elem a(numr) | *elem

Irina Athanasiu 3/1/2002 Limbaje formale i automate

21
Se observ ca n acest caz n funcie de simbolul terminal curent se poate decide n mod determinist
care este producia urmtoare ce trebuie s fie aplicat pentru derivare (construirea arborelui de derivare).
O gramatic independent de context pentru care este ndeplinit condiia ca partea dreapt a oricrei
producii ncepe cu un terminal sau este irul vid se numete gramatic de tip Q. O form particular de
gramatica de tip Q este forma normal Greibach. n acest caz nu exist --producii cu excepia cel mult a
unei --producii corespunztoare simbolului de start al gramaticii. n cazul n care aceasta producie
exist simbolul de start al gramaticii nu apare n partea dreapt a nici unei producii. n forma normal
Greibach produciile sunt de forma Aa cu a T i N
*
. S presupunem c o gramatic are
produciile:

P a
1

1
| a
2

2
| ... | a
n

n
|

unde a
i
T, i j a
i
a
j
, 1 i, j n. O procedur care recunoate irurile derivate din P este de
forma:

p(){
switch (caracter_urmtor){
case a1 : avans(); a1 /* tratare a1 */
case a2 : avans(); a2
...
case an : avans(); an
default: /* ? - producie */
}
}

Pe baza transformrilor anterioare se poate elabora un algoritm pentru construirea unei gramatici n
forma normal Greibach pentru o gramatic independent de context care nu este recursiv stnga.
Se definete nti o relaie de ordine asupra neterminalelor unei gramatici. i anume A < B dac exist
o producie A B . Considernd aceast relaie se observ c se poate construi o relaie parial de
ordine care poate s fie extinsa la o relaie liniar de ordine. Dac gramatica pentru care se construiete
aceast relaie nu este recursiv dreapta atunci produciile celui "mai mare" neterminal ncep sigur cu
simboli terminali. Rezult algoritmul:
Se construiete relaia de ordine asupra N astfel nct
N = {A
1
, A
2
, ..., A
n
} si A
1
< A
2
< ... < A
n
.
pentru i = n - 1 pn la 1 pas = -1 executa
fiecare producie de forma A
i
A
j
cu i < j se nlocuiete cu A
i

1
| ... |

m
unde A
j

1
| ...|
m
(se observa ca
1
, ...,
m
ncep cu terminale)

pentru fiecare producie de forma p = A a X1 ... Xk execut
pentru i = 1 pn la k execut
dac X
i
T
N = N {Xi'}
P = P { Xi' Xi}


P = P \ {p} {A aX1'X2' ... Xk'}


Prin inducie asupra numrului de pai se poate demonstra c algoritmul realizeaz transformarea
dorit. De exemplu pentru gramatica expresiilor aritmetice n forma fr --producii:

Irina Athanasiu 3/1/2002 Limbaje formale i automate

22
T ' | T ,
' +TE' | +T,
T FT' | F,
T' *FT' | *F
F () | a

Relaia de ordine liniar poate s fie ' < < T' < T < F. Se pornete de la F, pentru care toate
produciile ncep cu un terminal. Rezult modificarea produciilor pentru T:

T () T' | a T' | () | a.

Urmeaz T' care nu necesit transformri. Pentru se obine:

()T'' | a T' ' | ()' | aE' | ()T' | aT' | () | a

De asemenea ' nu se modific. Rezult urmtoarea gramatic n forma normal Greibach:

(EAT'' | a T' ' | (EAE' | aE' | (EAT' | aT' | (EA | a
' +TE' | +T
T (EA T' | a T' | (EA | a.
T' *FT' | *F
F (EA | a
A )

2.1.4 Construcii dependente de context

Anumite construcii specifice limbajelor de programare nu pot s fie descrise prin limbaje
independente de context. S considerm cteva exemple :
1. Fie limbajul L1 = {wcw| w {0,1}*}. Acest limbaj realizeaz abstractizarea condiiei ca un
identificator s fie declarat nainte de a fi utilizat. L1 nu poate s fie generat de o gramatic
independent de context. Din acest motiv condiia ca un identificator s fie definit nainte de a fi
utilizat nu pot s fie verificat prin analiz sintactic, deci va fi verificat de ctre analiza
semantic.
2. Fie limbajul L2 = {a
n
b
m
c
n
d
m
| n > 1, m > 1}. Acest limbaj realizeaz abstractizarea corespondenei
ca numr ntre numrul de parametrii cu care au fost declarate procedurile i numrul de
parametrii cu care se utilizeaz acestea. Nici acest limbaj nu pot fi descris de o gramatic
independent de context. Pe de alt parte limbajul L2' = {a
n
b
n
| n > 1}, poate s fie descris de
gramatica : S a S b | a b. Deci i aici dup o prim recunoatere fcut n analiza sintactic,
partea de dependen de context va fi rezolvat de ctre faza de analiz semantic.

Observaie

n general interpretnd gramaticile ca algoritmi de generare de iruri crora le corespund ca
echivaleni algoritmi de recunoatere de iruri, se constat c pentru cazul limbajelor regulate este necesar
ca pentru recunoatere s se fac o numrare pn la o valoare finit (care poate ns s fie orict de mare).
Astfel c limbajul LR = {a
n
b
n
| 0 n 20000000000000} este un limbaj regulat. Numrul de a-uri
ntlnite poate s fie memorat n neterminalele. De altfel, LR este un limbaj finit i deci automat este
regulat (produciile gramatici pot s reprezinte de fapt lista irurilor care formeaz limbajul). Limbajul
Irina Athanasiu 3/1/2002 Limbaje formale i automate

23
LR1 = {w {0,1}* | |w| mod 3 = 0} este infinit i regulat. Se observ c pentru recunoaterea irurilor
este necesar s se numere cte dou elemente. n schimb limbajul LI = {a
n
b
n
| 0 n} nu este regulat,
algoritmul pe care s-ar baza recunoaterea irurilor nu are o limit. Tratarea unei astfel de situaii se face n
mod natural utiliznd un contor infinit sau o stiv.
2.1.4.1 Exerciii

1. Fie gramatica:

A BC | a. B CA | Ab, C AB | cC | b

S se construiasc gramatica echivalenta nerecursiva stnga

2. S se elimine simbolii neutilizai pentru gramatica:

S A | B, A aB | bS | b, B AB | BA, C AS|b

3. S se construiasc gramatica echivalenta fr -producii pentru gramatica:

S ABC, A BB | , B CC | , C AA | b

4. S se construiasc un algoritm care verific dac pentru o gramatic dat G, L(G) este mulimea
vid. S se demonstreze c algoritmul este corect
Irina Athanasiu 3/1/2002 Limbaje formale i automate

24
2.1.5 Proprieti ale limbajelor independente de context

Limbajele formale sunt mulimi - putem s aplicm asupra lor operaii caracteristice mulimilor :
reuniune, intersecie, diferen dar i operaii specifice cum este de exemplu concatenarea. Dac L1 i L2
sunt dou limbaje, concatenarea lor este un limbaj L = L1L2 astfel nct:

L = { w | w = xy, x L1, y L2}

O alt operaie specific ce se poate aplica asupra unui limbaj formal L este "Kleen star". Notaia
utilizat pentru rezultat este L
*
i reprezint mulimea irurilor obinute prin concatenarea a zero sau mai
multe iruri din L (concatenarea a zero iruri este irul vid, concatenarea unui singur ir este el nsui etc.).
Se va utiliza i notaia L
+
pentru LL
*
.
Dac aplicnd o operaie asupra oricror doua limbaje independente de context obinem un limbaj
independent de context vom spune c mulimea limbajelor independente de context este nchis sub
operaia respectiv. Se poate demonstra c mulimea limbajelor independente de context este nchis sub
operaiile: reuniune, concatenare i Kleen star.
S demonstrm de exemplu nchiderea sub operaia de reuniune. Fie doua gramatici G1 = (N1, T1, P1,
S1), G2 = (N2, T2, P2, S2). Putem ntotdeauna s presupunem c N1 N2 = eventual prin redenumirea
simbolilor neterminali din una dintre gramatici). Gramatica corespunztoare limbajului reuniune a
limbajelor generate de ctre cele doua gramatici se poate construi n modul urmtor:

G = (N, T, P, S), N = N1 N2 {S}, T = T1 T2, P = P1 P2 {S S1 | S2}

Pentru a demonstra c limbajul L(G) = L(G1) L(G2) trebuie s demonstrm includerea mulimilor
n ambele sensuri. Dac w L(G) nseamn c a fost obinut printr-o derivare ca S S1
*
w sau S
S2
*
w. Deci un ir derivat din S aparine limbajului L(G1) L(G2). Invers dac alegem un ir w
L(G1) L(G2) el este obinut dintr-o derivare din S1 sau din S2, deci se poate construi o derivare pentru
acest ir i n G. Construcii similare se pot face i pentru operaia de concatenare i pentru operaia Kleen
star. De exemplu L(G1)* pentru o gramatica G1 = (N1, T1, P1, S1) poate s fie generat de ctre:

G = (N1, T1, P1 {S1 | S1 S1}, S1)

Clasa limbajelor independente de context nu este nchis la operaiile de intersecie i complementare.
S considerm de exemplu limbajele L1 = {a
n
b
n
c
m
| n,m 0}, L2 = {a
m
b
n
c
n
| n,m 0}.
Limbajul L = L1 L2 este "cunoscut" ca fiind un limbaj dependent de context. S presupunem acum
c pentru un limbaj independent de context generat de ctre gramatica G = (N, T, P, S), limbajul
complementar, adic T* - L(G) este ntotdeauna independent de context. n acest caz, fie L un limbaj
obinut prin intersecia a dou limbaje independente de context: L1 i L2. Se poate scrie:

L = L1 L2 = T
*
- ((T
*
- L1) (T
*
- L2)).

Dac mulimea limbajelor independente de context este nchis la operaia de complementare atunci
(T
*
- L1) i (T
*
- L2) sunt limbaje independente de context i la fel este i reuniunea lor i la fel va fi i
complementarea limbajului obinut prin reuniune. Adic ar rezulta c L1 L2 este un limbaj independent
de context ceea ce deja tim c nu este adevrat.
Dup cum s-a constatat acelai limbaj poate s fie descris de mai multe gramatici, eventual de tipuri
diferite. Este util gsirea unui criteriu prin care s se indice tipul restrictiv al gramaticilor care pot s
descrie un limbaj dat, ntr-o manier mai precis dect observaia de la pagina 24. De exemplu s
considerm limbajul:
Irina Athanasiu 3/1/2002 Limbaje formale i automate

25

{ a
n
*
n
| n > 1 }

Se pune problema dac exist o gramatica independent de context care s-l genereze. Urmtorul
rezultat ne d un criteriu cu ajutorul cruia putem s demonstrm c o gramatic nu este independent de
context.

Lema de pompare Fie L un limbaj independent de context. Atunci, exist o constanta k care este
caracteristic limbajului astfel nct dac z L i |z| k, atunci z poate s fie scris sub forma z = uvwxy
cu vx , |vwx| k , |w| 1 i pentru orice i, uv
i
wx
i
y L.
S utilizm rezultatul anterior pentru a studia limbajul:

L = { a
n
*
n
| n > 1 }

s presupunem c L este independent de context. nseamn c exist un numr k (asociat limbajului)
astfel nct dac n * n k atunci a
n x n
= uvwxy astfel nct v i x nu sunt amndou iruri vide i |vwx| k.
S presupunem ca n este chiar k ( k * k > k). Rezult ca uv
2
wx
2
yL. Deoarece |vwx| k rezult 1 |vx| <
k deci lungimea irului iniial k x k < |uv
2
wx
2
y| < k x k + k. Dup k x k urmtorul ptrat perfect este (k +
1) x (k + 1) care este mai mare deci k x k + k, adic |uv
2
wx
2
y| nu poate s fie un ptrat perfect, deci L nu
poate s fie generat de o gramatic independent de context.

2.1.5.1 Exerciii
1. S se arate c limbajul { a
n
b
n
c
n
| n > 1 } nu este independent de context
2. S se arate c limbajul { a
n
b
n
c
j
| n > 1, j < n } nu este independent de context
2.2 Mulimi regulate, expresii regulate.

Fie T un alfabet finit. Se numete mulime regulat asupra alfabetului T mulimea construit recursiv
n modul urmtor:

1. este o mulime regulat asupra alfabetului T;
2. Dac a T atunci {a} este o mulime regulat asupra alfabetului T;
3. Dac P i Q sunt mulimi regulate atunci PQ, PQ, P
*
sunt mulimi regulate asupra alfabetului T.
4. Nimic altceva nu este o mulime regulat.

Se observ deci c o submulime a mulimii T
*
este o mulime regulat asupra alfabetului T dac i
numai dac este mulimea vida, este o mulime care conine un singur simbol din T sau poate s fie
obinut din aceste dou tipuri de mulimi utiliznd operaiile de reuniune (P Q), concatenare (PQ) sau
nchidere P*.
Descrierea mulimilor regulate se poate face cu ajutorul expresiilor regulate. O expresie regulat este
la rndul ei definit recursiv n modul urmtor (prin analogie cu definiia mulimilor regulate) :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

26
1. este o expresie regulata care descrie mulimea ;
2. a T este o expresie regulat care descrie mulimea {a};
3. dac p,q sunt expresii regulate care descriu mulimile P i Q atunci :
a. (p + q) sau (p | q) este o expresie regulat care descrie mulimea P Q;
b. (pq) este o expresie regulat care descrie mulimea PQ;
c. (p)* este o expresie regulat care descrie mulimea P
*
.
4. nimic altceva nu este o expresie regulat.

De exemplu expresia (0 | 1)* reprezint mulimea {0,1}*, expresia regulat : (00 | 11)*((01 | 10)(00 |
11)*(01 | 10)(00 | 11)*)* reprezint mulimea care conine toate irurile formate din 0 i 1 i care conin un
numr par din fiecare simbol. n particular pp
*
este notat cu p
+
. ntre operatorii utilizai n descrierea
mulimilor regulate exist o serie de relaii de preceden. Cea mai prioritar operaie este operaia de
nchidere (notat cu *), urmeaz operaia de concatenare, cel mai puin prioritar este operaia + (|). De
exemplu, expresia regulat (0 | (1(0)*)) poate s fie scrisa i sub forma 0 | 10*.
Expresiile regulate au o serie de proprieti. Fie , , , expresii regulate. Spunem ca = dac i
numai dac i descriu aceleai mulimi regulate. Sunt adevrate urmtoarele proprieti :

1. | = | 2. | ( |) = ( | ) |
3. () = () 4. ( |) = |
5. ( | ) = | 6. ? = ? =
7. * = | * 8. (*)* = *
9. | =

Utiliznd expresii regulate se pot construi i rezolva ecuaii avnd ca soluii expresii regulate. S
considerm de exemplu ecuaia:

X = aX + b

unde a,b i X sunt expresii regulate. Se poate verifica uor c X = a * b este o soluie a acestei ecuaii.
Dac a este o expresie regulat care poate s genereze irul vid atunci soluia prezentat anterior nu este
unic. S nlocuim n ecuaie pe X cu expresia regulat:

a*(b + )

Se obine:

a
*
(b + ) = a[a
*
(b + )] + b =
= a
+
b + a
+
+ b =
= (a
+
+ )b + a
+
= a
*
b + a
*

= a
*
(b + )

Se numete punct fix al unei ecuaii cea mai mic soluie a ecuaiei respective.

Propoziie Dac G este o gramatic regulat atunci L(G) este o mulime regulata.
Demonstraia acestei teoreme se face prin construcie. Nu vom face demonstraia dar vom considera
un exemplu de construcie. Fie gramatica G = ({A, B, C}, {0,1}, P,A) cu P = {A 1A | 0B, B 0B | 1C,
C 0B| 1A| }. Se cere s se construiasc expresia regulat care genereaz acelai limbaj ca i G. Se pot
scrie urmtoarele ecuaii:
A = 1A + 0B
B = 0B + 1C
Irina Athanasiu 3/1/2002 Limbaje formale i automate

27
C = 0B + 1A +

Din prima ecuaie se obine: A = 1
*
0B. Din a doua ecuaie se obine: B = 0
*
1C. nlocuind n A se
obine: A = 1
*
00
*
1C = 1
*
0+1C. nlocuind n a treia ecuaie se obine:

C = 0
+
1C + 1
+
0
+
1C +
C = ( + 1
+
)0
+
1C + = 1
*
0+1C
C = (1
*
0
+
1)*

Rezult:

A = 1
*
0
+
1 (1
*
0
+
1)
*
A = (1
*
0
+
1)
+

Mulimea regulat descrie irurile de 0 i 1 care se termin cu sub irul 01. Evident o expresie mai
simpl pentru descrierea aceluiai limbaj este:

(0 | 1)*01

Se observ c se poate considera c limbajul se obine prin concatenarea a doua limbaje unul descris
de expresia (0 | 1)
*
i cellalt descris de expresia 01. Rezult urmtoarea gramatic:

S AB
A 0A | 1A |
B 01

Se observ c gramatica obinut nu este regulat. S transformm aceast gramatic prin substituie
de nceputuri:

S 0AB | 1AB | B
A 0A | 1A |
B 01

Se obine:

S 0S | 1S |01

Utiliznd factorizarea:

S 0X | 1S
X S | 1

Din nou prin nlocuire de nceputuri se obine:

X 0X | 1S |1

Aplicnd factorizarea:

X 0X | 1Y
Y S |
Irina Athanasiu 3/1/2002 Limbaje formale i automate

28

Rezult gramatica descris de produciile:

S 0X | 1S
X 0X | 1Y
Y 0X | 1S | .

Se observ c s-a ajuns la aceeai gramatic cu cea iniial ( desigur dac redenumim neterminalele).
Expresiile regulate reprezint o metod alternativ generativ pentru definirea limbajelor regulate.
Limbajele definite de gramatici regulate sunt utilizate la nivelul analizei lexicale, n majoritatea limbajelor
de programare modul de scriere al numelor i al identificatorilor pot s fie descrise de gramatici respectiv
de expresii regulate. Construirea expresiilor regulate corespunztoare atomilor lexicali reprezint prima
etapa n proiectarea unui analizor lexical.
2.3 Acceptoare

Un acceptor este un dispozitiv format dintr-o band de intrare, o unitate de control i o memorie
auxiliar.

+---------------
|a0|a1|...|an|
+---------------
\ cap de citire
\
+---------+
| unitate |
| de |
| control |
+---------+
|
+-----------+
| memorie |
| auxiliara |
+-----------+

Banda de intrare este formata din elemente n care se nscriu simbolii din irul de intrare. La un
moment dat capul de citire este fixat pe un simbol. Funcionarea dispozitivului este dat de aciunile
acestuia. ntr-o aciune capul de citire se poate deplasa la stnga sau la dreapta sau poate s rmn
nemicat. n cadrul unei aciuni unitatea de control are acces la informaia din memoria auxiliar pe care o
poate modifica. Se observ ca acest model este foarte general. Utiliznd diferite restricii asupra benzii de
intrare, organizrii i accesului la memoria auxiliar se obin diferite cazuri particulare de acceptoare.
O aciune a acceptorului este formata din :
deplasarea capului de citire la stnga sau la dreapta sau meninerea capului de citire pe aceeai poziie
i / sau;
memorarea unei informaii n memoria auxiliar i / sau;
modificarea strii unitii de control.

Comportarea unui acceptor poate s fie descris n funcie de configuraiile acestuia. O configuraie
este format din urmtoarele informaii :

starea unitii de control;
coninutul benzii de intrare i poziia capului de citire;
Irina Athanasiu 3/1/2002 Limbaje formale i automate

29
coninutul memoriei.

Rezult c o aciune a acceptorului poate s fie precizat prin configuraia iniial (nainte de aciune)
i cea final (dup execuia aciunii).
Dac pentru o configuraie dat sunt posibile mai multe aciuni atunci spunem c acceptorul este
nedeterminist altfel este determinist.
Un acceptor are o configuraie iniial n care unitatea de control este ntr-o stare iniial, capul de
citire este fixat pe simbolul cel mai din stnga al irului de intrare iar memoria are un coninut iniial
specific. Acceptorul are o configuraie final pentru care capul de citire este situat pe simbolul cel mai din
dreapta de pe banda de intrare. Se spune c dispozitivul a acceptat un ir de intrare w dac pornind din
configuraia iniial ajunge n configuraia finala. Eventual, noiunea de acceptare poate s fie condiionata
i de ajungerea ntr-o anumit stare a unitii de control sau de un anumit coninut al memoriei auxiliare.
Evident dac acceptorul este nedeterminist dintr-o configuraie iniial pot avea loc mai multe evoluii.
Dac exist ntre acestea una pentru care se ajunge la o configuraie final atunci se spune c dispozitivul a
acceptat irul de intrare.
Limbajul acceptat de ctre un acceptor este format din mulimea irurilor acceptate de ctre acesta.
Pentru fiecare tip de gramatica din ierarhia Chomsky exist o clasa de acceptoare care definesc
aceeai clas de limbaje. Dintre acestea cele utilizate pentru implementarea compilatoarelor sunt
automatele finite care sunt acceptoare pentru limbaje regulate i automatele cu stiv (push-down), care
sunt acceptoare pentru limbajele independente de context. Automatele finite sunt acceptoare fr memorie
auxiliar iar automatele cu stiv sunt acceptoare pentru care accesul la memoria auxiliar se face conform
unui mecanism de tip stiv.
2.3.1 Automate finite

Un automat finit este un obiect matematic AF = (Q, T, m, s0, F) unde :

Q este mulimea finit a strilor;
T este o mulime finit numit alfabet de intrare;
m : Q x (T {}) P(Q) este funcia parial a strii urmtoare;
s0 Q este o stare numit stare de start;
F Q este o mulime de stri numit mulimea strilor finale (de acceptare).

Dac pentru q Q, a T m(q,a) este definit, atunci m(q,a) se numete tranziie, dac a = atunci
m(q,a) se numete -tranziie. Se observ ca pentru o combinaie stare(q Q), intrare(a T) pot s
corespund mai multe stri urmtoare, deci aa cum a fost definit, automatul este nedeterminist (AFN).
Pentru reprezentarea unui automat finit se pot utiliza dou moduri de reprezentare, printr-o tabela de
tranziie sau printr-un graf. S considerm de exemplu automatul care accepta limbajul definit de expresia
(a | b)* abb. Poate s fie descris sub forma urmtoarei tabele :

simbol de intrare
stare a b
0 {0, 1} {0}
1 - {2}
2 - {3}
3 - +

Se observ c n fiecare intrare este specificat mulimea strilor urmtoare n care se trece pentru
starea i simbolul corespunztor intrrii respective. Acelai automat finit poate s fie descris de urmtorul
graf de tranziie :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

30

a
---
\ /
+---+ +---+ +---+ +---+
start | | a | | b | | b |+-+|
-------->| 0 |-->| 1 |-->| 2 |-->||3||
| | | | | | |+-+|
+---+ +---+ +---+ +---+
/ \
---
b

Se observ c pentru fiecare stare exist cte un nod, ntre dou noduri exist un arc etichetat cu un
simbol de intrare dac i numai dac se poate trece din starea reprezentat de primul nod n starea
reprezentat de al doilea nod la aplicarea la intrare a simbolului cu care este etichetat arcul. De remarcat
modul n care a fost specificat starea final.
Se spune c un automat finit accept un ir de intrare dac exist o cale n graful de tranziie ntre
nodul care reprezint starea de start i un nod care reprezint o stare final, astfel nct irul simbolilor
care eticheteaz arcele care formeaz aceast cale este irul de intrare. De exemplu irul aabb este acceptat
de automatul descris anterior, care va executa urmtoarele micri:

a a b b
0 0 1 2 3

Se observa c pentru acelai ir de intrare exist i alte secvene de intrri care ns nu duc ntr-o stare
de acceptare:

a a b b
0 0 0 0 0

Un caz particular al automatelor finite este dat de automatele finite deterministe (AFD). n cazul
automatelor finite deterministe definiia funciei strii urmtoare se modific:

m : S x T S.

Se observ c sunt satisfcute urmtoarele restricii:

1. nu exist -tranziii;
2. pentru (q, a) Q x T este definit cel mult o tranziie.

Se observ ca n acest caz, pentru un ir de intrare dat, n graful de tranziie exist cel mult o cale care
pornete din starea de start i duce ntr-o stare de acceptare.
2.3.1.1 Construcia unui automat finit nedeterminist care accept limbajul descris de o expresie regulat dat

Algoritmul pe care l vom prezenta utilizeaz direct structurile din definiia expresiilor regulate. Se
pleac de la o expresie regulat r asupra unui alfabet T i se obine un automat finit nedeterminist (N) care
accept limbajul L(r).
Pentru construirea automatului se identific n structura expresiei r structurile care n mod recursiv
compun expresia i se construiesc automatele finite nedeterministe (AFN) elementare corespunztoare.

Irina Athanasiu 3/1/2002 Limbaje formale i automate

31
1. Pentru expresia , automatul care accept limbajul corespunztor este :

+---+ +-----+
start | | |+---+|
------->| i |------>|| f ||
| | |+---+|
+---+ +-----+

2. Pentru expresia a, automatul care accept limbajul corespunztor este :


+---+ +-----+
start | | a |+---+|
-------->| i |------>|| f ||
| | |+---+|
+---+ +-----+

3. Fie dou expresii regulate r,t pentru care s-au construit automatele finite nedeterministe
corespunztoare N(r) i N(t).
a. pentru expresia regulat r|t limbajul corespunztor este acceptat de :


Irina Athanasiu 3/1/2002 Limbaje formale i automate

32
-------------------------
| +---+ +-----+ |
| | | N(r) |+---+| |
--------->| |-- >|| ||----
/ | | | |+---+| | \
/ | +---+ +-----+ | \
+---+ / | | \ +-----+
| |/ ------------------------- \|+---+|
->| i | || f ||
| |\ ------------------------- /|+---+|
+---+ \ | | / +-----+
\ | +---+ +-----+ | /
\ | | | N(t) |+---+| | /
---------->| |-- >|| ||---/
| | | |+---+| |
| +---+ +-----+ |
| |
-------------------------

b. pentru expresia regulat rt limbajul corespunztor este acceptat de :

----------------------------
| |
--------------+----------- |
| +---+ | +---+ | +-----+ |
| | | N(r) | | | | N(t)|+---+| |
--------->| i |--- -+> | |---- >|| f ||----
| | | | | | | |+---+| |
| +---+ | +---+ | +-----+ |
| | | |
--------------+----------- |
| |
----------------------------

Se observ ca n acest caz starea final a automatului corespunztor expresiei r coincide cu starea
iniial a automatului corespunztor expresiei t.
c. pentru expresia regulata r* limbajul corespunztor este acceptat de :


+-<------------+
| |
-----|--------------|-----
+---+ | +---+ +---+ | +-----+
| | | | | N(r) | | | |+---+|
---->| i |----------> | |--- ---> | |-------->|| f ||
| | | | | | | | |+---+|
+---+ | +---+ +---+ | +-----+
| | | /\
| -------------------------- |
| |
+---------------------------------------------+


d. pentru expresia (r) limbajul corespunztor este acceptat de automatul care accepta N(r).

Irina Athanasiu 3/1/2002 Limbaje formale i automate

33
Se observ c pentru fiecare AFN - elementar se adaug cel mult o stare iniial i o stare final.
Corespunztor pentru o expresie regulat dat automatul va avea un numr de stri egal cu maxim dublul
numrului de simboli de intrare care apar n expresie. Compunerea acestor automate elementare va
produce evident un automat care recunoate limbajul generat de expresie. De exemplu pentru expresia
regulata : (a|b)*abb se obine :
pentru fiecare a din expresie :


+---+ +-----+
| | a |+---+|
-------->| i |------> || f ||
| | |+---+|
+---+ +-----+

pentru fiecare b din expresie :

+---+ +-----+
| | b |+---+|
-------->| i |------> || f ||
| | |+---+|
+---+ +-----+

pentru a | b :

+---+ +-----+
| | a |+---+|
----------> | |------>|| ||----
/ | | |+---+| \
/ +---+ +-----+ \
+---+ / \ +-----+
| |/ \|+---+|
->| i | || f ||
| |\ /|+---+|
+---+ \ / +-----+
\ +---+ +-----+ /
\ | | b |+---+| /
---------->| |------>|| ||---/
| | |+---+|
+---+ +-----+

n final se obine :









Irina Athanasiu 3/1/2002 Limbaje formale i automate

34

---------------+
/ |
/ +-+ +-+ |
/ | |a | | |
/ / >|2|->|3|\ |
/ / | | | | \ |
+-+ +-+ / +-+ +-+ +-+ +-+ +-+ +-+ +--+
| | | |/ | | | |a | |b | |b |--|
> |0|->|1| |6|->|7|->|8|->|9|->|10|
| | | |\ /| | | | | | | | |--|
+-+ +-+ \ +-+ +-+ / +-+ +-+ +-+ +-+ +--+
\ \ | |b | | / /\
\ \ > |4|->|5|/ /
\ | | | | /
\ +-+ +-+ /
\ /
--------------------

2.3.1.2 Conversia unui automat finit nedeterminist (AFN) ntr-un automat finit determinist(AFD)

Din exemplele anterioare s-a observat c un acelai limbaj reprezentat de expresia regulat (a | b)*
abb poate s fie recunoscut de dou automate diferite - unul nedeterminist i unul determinist.

Propoziie Pentru orice automat finit nedeterminist exist un automat finit determinist care accept
acelai limbaj.

Avnd n vedere aceast echivalen ntre cele dou automate se pune problema, cum se poate
construi un automat determinist echivalent unui automat nedeterminist dat. n cele ce urmeaz vom
considera c automatul finit nedeterminist a fost construit pornind de la o expresie regulat pe baza
construciei prezentate n capitolul anterior. Algoritmul care construiete automatul determinist utilizeaz
o metod de construire a submulimilor unei mulimi date. Diferena ntre automatele deterministe i cele
nedeterministe este dat de cardinalitatea funciei m. Automatul determinist se va construi calculnd n
mod recursiv strile acestuia, simulnd n paralel toate evoluiile posibile pe care le poate parcurge
automatul nedeterminist. Starea iniial a automatului finit determinist va corespunde mulimii strilor din
automatul nedeterminist n care se poate ajunge pornind din starea iniiala s0 i utiliznd numai -tranziii.
Orice stare s' a automatului determinist corespunde unei submulimi Q' Q a automatului nedeterminist.
Pentru aceasta stare i un simbol de intrare a T,

m(s',a) = {s Q | ( q Q')(s = m(q,a))}.

Rezult deci c n funcionarea AFD care simuleaz de fapt funcionarea AFN se urmresc simultan
toate "cile" pe care poate evolua automatul finit nedeterminist. Algoritmul care construiete automatul
finit determinist echivalent cu un automat nedeterminist dat utilizeaz dou funcii : -nchidere i mutare.
Funcia -nchidere : P(Q) P(Q) determin pentru fiecare mulime Q' Q setul strilor n care se poate
ajunge datorit -tranziiilor. Considernd o stare q a automatului finit determinist (AFD), aceasta
reprezint de fapt o submulime Q' Q a automatului nedeterminist. Notm cu

-nchidere(Q) = -nchidere({s})
sQ
Irina Athanasiu 3/1/2002 Limbaje formale i automate

35

unde dac s S este o stare care nu are -tranziii atunci:

-nchidere({s}) = {s}

altfel

-nchidere({s}) = -nchidere({s'}) {s}
s' m(s,)

Construcia funciei -nchidere pentru o mulime Q' se poate face utiliznd urmtorul algoritm :

A = Q', B =
ct timp A \ B execut
fie t A \ B
B = B {t}
pentru fiecare u Q astfel nct m(t,) = u executa
A = A {u}


-nchidere(Q') = A

Funcia mutare : P(Q) x T P(Q) este utilizat pentru construcia strii urmtoare a automatului
determinist. Astfel pentru o stare q a automatului determinist, cruia i corespunde o mulime Q' Q, i o
intrare a T,

mutare(Q,a) = m(s,a)
sQ'
Construcia automatului determinist se face prin construcia unei tabele de tranziii tranz_AFD[] i a
unei mulimi de stri stari_AFD.

stari_AFD = {-inchidere({s0})}
A =
ct timp stari_AFD \ A execut
fie t stari_AFD \ A
A = A {t}
pentru fiecare a T execut
B = -inchidere(mutare(t,a))
stari_AFD = stari_AFD {B}
tranz_AFD[t,a] = B



Fie automatul nedeterminist :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

36

---------------+
/ |
/ +-+ +-+ |
/ | |a | | |
/ / >|2|->|3|\ |
/ / | | | | \ |
+-+ +-+ / +-+ +-+ +-+ +-+ +-+ +-+ +--+
| | | |/ | | | |a | |b | |b |--|
> |0|->|1| |6|->|7|->|8|->|9|->|10|
| | | |\ /| | | | | | | | |--|
+-+ +-+ \ +-+ +-+ / +-+ +-+ +-+ +-+ +--+
\ \ | |b | | / /\
\ > |4|->|5|/ /
\ | | | | /
\ +-+ +-+ /
\ /
--------------------

Se observ c

-inchidere(0) = {0, 1, 2, 4, 7}, -inchidere(mutare({0,1,2,4,7}),a)) = -inchidere({3,8}) =
{1,2,3,4,6,7,8}. Dac q1 = {0,1,2,4,7}, q2 = {1,2,3,4,6,7,8} atunci tran_AFD(q1,a) = q2. Continund se
obine urmtoarea tabel de tranziie :

stare | intrare | multime corespunzatoare AFN
| a | b |
-----------+----+----+--------------------------------------
q1 | q2 | q3 | {0,1,2,4,7} -inchidere({0})
-----------+----+----+--------------------------------------
q2 | q2 | q4 | {1,2,3,4,6,7,8} -inchidere({3,8})
-----------+----+----+--------------------------------------
q3 | q2 | q3 | {1,2,4,5,6,7} -inchidere({5})
-----------+----+----+--------------------------------------
q4 | q2 | q5 | {1,2,4,5,6,7,9} -inchidere({5,9})
-----------+----+----+--------------------------------------
q5 | q2 | q3 | {1,2,4,5,6,7,10} -inchidere({5,10})
------------------------------------------------------------

Graful automatului finit determinist care a rezultat este:










Irina Athanasiu 3/1/2002 Limbaje formale i automate

37
b
---
\ /
+---+
| | b
b >| q3|<---------------------+
/ +-| | |
+---+ /a | +---+ |
start | |/ | +---+ +---+ +------+
------>| q1| a \/| | b | | b |+----+|
| |---> | q2|------>| q4|----->|| q5 ||
+---+ | | | | |+----+|
+---+ +---+ +------+
/\ || a | |
-- |+-<--------+ |
a | |
| a |
+--<--------------------+


Se observ c s-a obinut un automat cu 5 stri fa de 4 stri ct avea automatul finit determinist cu
care s-au exemplificat automatele finite deterministe. Deci algoritmul utilizat nu produce neaprat o
soluie optim.

2.3.1.3 Construcia unui automat finit determinist care accept limbajul descris de o expresie regulat dat
O expresie regulat poate s fie reprezentat sub forma unui arbore (sintactic). De exemplu pentru
expresia regulata (a|b)*abb rezult arborele:

.
/ \
/ \
. b
/ \
/ \
. b
/ \
/ \
* a
|
/ \
/ \
a b

Se observ c n nodurile interioare apar operatori iar frunzele sunt reprezentate de ctre simbolii de
intrare. Exist trei operatori (|, *, .). Pentru a simplifica construciile considerm pentru orice expresie
regulata i un simbol de sfrit pe care l vom nota cu # astfel nct orice expresie regulata r va fi
reprezentat de r#. Relund pentru expresia anterioar va rezulta graful:




.
Irina Athanasiu 3/1/2002 Limbaje formale i automate

38
/ \
/ \
. #
/ \
/ \ 6
. b
/ \
/ \ 5
. b
/ \
/ \ 4
* a
|
/ \ 3
/ \
a b

1 2

Vom ataa fiecrei frunze un cod unic, de exemplu acest cod poate s fie reprezentat de poziia
simbolului respectiv n expresia regulat.
Fie C mulimea codurilor ataate fiecrei frunze i N mulimea nodurilor arborelui. Fie c funcia de
codificare i c
-1
funcia invers (c : N C). Definim patru funcii:
nullable : N {adevrat, fals}
firstpos : N P(C)
lastpos : N P(C)
followpos : C P(C)

Funcia nullable este o funcie logic care are valoarea adevrat dac i numai dac subarborele
corespunztor nodului respectiv reprezint o expresie regulat care poate s genereze irul vid. Astfel
funcia nullable aplicat subarborelui:

|
/ \
a b

are valoarea fals n schimb aplicat asupra subarborelui:

*
|
a

are valoarea adevrat.
Funcia firstpos aplicat unui subarbore are ca valoare mulimea codurilor frunzelor corespunztoare
poziiilor de nceput pentru subirurile care pot s fie generate de ctre expresia regulat corespunztoare
subarborelui respectiv. De exemplu pentru nodul rdcin al subarborelui:
Irina Athanasiu 3/1/2002 Limbaje formale i automate

39

x (a | b)* a
. 1 2 3
/ \
/ \
* a firstpos(x) = {1,2,3}
|
/ \ 3 lastpos(x) = {3}
/ \
a b
1 2

Funcia lastpos aplicat unui subarbore are ca valoare setul codurilor frunzelor corespunztoare
poziiei de sfrit pentru subirurile care pot s fie generate de ctre expresia regulat corespunztoare
subarborelui respectiv.
Funcia followpos este definit asupra mulimii codurilor frunzelor. Dac i este un cod i i este asociat
simbolului x, (i = c
-1
(x)) atunci followpos(i) este mulimea codurilor j (j = c
-1
(z)) care satisfac urmtoarea
condiie: xy (etichetate cu i i respectiv j ) pot s apar ntr-un ir generat din rdcin.
Altfel spus dac se consider irurile obinute din cuvintele din L(r) (limbajul generat de expresia
regulat) prin nlocuirea simbolilor din T cu codurile asociate frunzelor din graf care le genereaz,
followpos(i) conine toate codurile care pot s apar imediat dup i n aceste iruri. De exemplu
followpos(1) = {1,2,3}. Pentru a calcula funcia followpos trebuie s se calculeze funciile firstpos i
lastpos care la rndul lor necesit calculul funciei nullable. Regulile pentru calculul funciilor nullable,
firstpos i lastpos sunt urmtoarele :

forma nod n nullable(n) firstpos(n) lastpos(n)
n este o frunz
cu eticheta
adevrat
n este o frunz
cu eticheta
avnd codul i
fals {i} {i}
n |
/ \
/ \
c1 c2
nullable(c1)
sau
nullable(c2)
firstpos(c1)

firstpos(c2)
lastpos(c1)

lastpos(c2)

n .
/ \
/ \
c1 c2
nullable(c1)
si
nullable(c2)
dac nullable(c1)
firstpos(c1)

firstpos(c2)
altfel
firstpos(c1)
dac nullable(c2)
lastpos(c1)

lastpos(c2)
altfel
lastpos(c2)
n *
|
c
adevrat firstpos(c) lastpos(c)


Pentru a calcula followpos(i) care indic ce coduri pot s urmeze dup[ codul i conform arborelui se
utilizeaz dou reguli :

1. dac n este un nod corespunztor operatorului de concatenare cu subarborii c1 i c2 (respectiv stnga
dreapta) atunci dac i este un cod din lastpos(c1) toate codurile din firstpos(c2) sunt n mulimea
followpos(i).
Irina Athanasiu 3/1/2002 Limbaje formale i automate

40
2. dac n este un nod corespunztor operatorului *, i i este un cod din lastpos(n) atunci toate codurile
din firstpos(n) sunt n mulimea followpos(i).

Pentru arborele anterior valorile funciilor firstpos i lastpos sunt reprezentate n stnga respectiv
dreapta fiecrui nod.

{1,2,3} .{6}
/ \
/ \
/ \
{1,2,3} .{5} {6}#{6}
/ \ 6
/ \
/ \
{1,2,3} .{4} {5}b{5}
/ \ 5
/ \
/ \
{1,2,3} .{3} {4}b{4}
/ \ 4
/ \
/ \
{1,2} *{1,2} {3}a{3}
| 3
{1,2} | {1,2}
/ \
/ \
/ \
{1} a{1} {2}b{2}
1 2

Singurul nod pentru care funcia nullable are valoarea adevrat este nodul etichetat cu *. Pe baza
acestor valori s calculm followpos(1). n followpos(1) vor apare codurile din firstpos pentru nodul
etichetat cu * i codurile din firstpos pentru subarborele dreapta corespunztor operatorului de concatenare
(followpos(1) = followpos(2) = {1,2,3}. Rezult urmtoarele valori :

nod followpos
1 {1,2,3}
2 {1,2,3}
3 {4}
4 {5}
5 {6}
6 -

Pornind de la aceste valori se poate construi un graf n care fiecare nod reprezint un cod iar ntre
dou noduri corespunztoare codurilor i i j exist un arc dac j followpos(i).

Irina Athanasiu 3/1/2002 Limbaje formale i automate

41
---
\ /
+---+
+- | |
| | 1 |\ +---+ +---+ +---+ +-----+
| +-| | \| | | | | | |+---+|
| | +---+ | 3 |- | 4 |- | 5 |- || 6 ||
| | +---+ | | | | | | |+---+|
| | | | /+---+ +---+ +---+ +-----+
| +>| 2 |/
+----| |
+---+
/\
--
Pe baza unui astfel de graf se poate obine un automat finit nedeterminist fr -tranziii, etichetnd
arcele n modul urmtor. Dac ntre nodul i i nodul j exist un arc acesta va fi etichetat cu simbolul care
are codul j. Fiecare stare a automatului corespunde unui nod din graf. Automatul are ca stri iniiale strile
din firstpos pentru nodul rdcin. Strile finale sunt strile asociate cu simbolul #. Automatul care a
rezultat, avnd mai multe stri iniiale nu se ncadreaz de fapt n definiia pe care am dat-o pentru un
automat finit. Dac ns mai adugm o stare suplimentar care s reprezinte unica stare iniial din care
pe baza unor -tranziii ajungem ntr-una dintre strile automatului obinut, se vede c ne ncadrm n
definiia considerat

a
---
\ /
+---+
+-> | | a
| | 1 |\ +---+ +---+ +---+ +-----+
| +-| | \| | b | | b | | # |+---+|
a |b | +---+ | 3 |-> | 4 |->| 5 |->|| 6 ||
| | +---+ | | | | | | |+---+|
| | | | /+---+ +---+ +---+ +-----+
| +>| 2 |/ a
+----| |
+---+
/\
--
b
Mai interesant ns este faptul c funcia followpos poate s fie utilizat pentru construirea unui
automat determinist utiliznd un algoritm similar celui pentru construirea submulimilor.
Irina Athanasiu 3/1/2002 Limbaje formale i automate

42
stari_AFD = { first_pos(radacina) } // multime de multimi de coduri
A =
ct timp stari_AFD \ A execut
fie t stari_AFD \ A // mulime de coduri
A = A {t}
pentru fiecare a T execut
X = { followpos(p) | c
-1
(p) = a}
p t
daca X
stari_AFD = stari_AFD {X}
tranz_AFD(t,a) = X




n algoritm firstpos(rdcin) este valoarea funciei firstpos aplicat nodului rdcin.
Se observ c firstpos(rdcina) corespunde cu -inchidere(s0) iar followpos(p) reprezint -
nchidere(mutare(...)).
Aplicnd acest algoritm i rezultatele anterioare se obine automatul finit determinist reprezentat de
urmtorul graf :

b b
-- --------<---------------------+
\/ / | (a | b)* a b b #
+---+ / | 1 2 3 4 5 6
start | 1,|/ +---+ +---+ +------+
| | | 1,| | 1,| |+----+|
-----> | 2,| a | 2,| b | 2,| b ||1,2,||
| 3 |----->| 3,|---- | 3,|----||3,6 ||
+---+ | 4 | | 5 | |+----+|
+---+ +---+ +------+
/\ || a | |
-- |+-<--------+ |
a | |
| a |
+--<---------------------+

Fie q1 = firstpos(rdcina) = {1,2,3}. Se observ c r(1) = r(3) = a, r(2) = r(4) = r(5) = b. Pentru q1 i
a se obine q2 = followpos(1) followpos(3) = {1,2,3,4}, deci tranz_AFD(q1,a) = q2. Pentru q2 i b,
followpos(2) = {1,2,3} = q1 i tranz_AFD(q1,b) = q1, etc.
Nici aceasta construcie nu garanteaz faptul c automatul obinut este minim.
Irina Athanasiu 3/1/2002 Limbaje formale i automate

43
2.3.1.4 Simularea unui automat finit determinist

Construim un algoritm care urmeaz s rspund la ntrebarea - dndu-se un automat finit determinist
D i un ir, este irul acceptat de ctre automat ?
Algoritmul utilizeaz funciile mutare (care determin starea urmtoare pentru o stare i un simbol de
intrare dat) i caracterul_urmtor (care obine caracterul urmtor din irul de intrare).

s = s0
c = caracterul_urmtor
cat timp c eof executa
s = mutare(s,c)
c = caracterul_urmtor

daca s F
atunci rezultat "DA"
altfel rezultat "NU"


Dac aplicm acest algoritm pentru automatul :

b
--------------
b / \
--- / \
\ / V \
+---+ +---+ +---+ +---+
start | | a | | b | | b |+-+|
------> | 0 |>| 1 |> | 2 |> ||3||
| | | | | | |+-+|
+---+ +---+ +---+ +---+
/\

| |
-- | | | |
a | +-----+ |
| a |
+---------------+
a

care accepta limbajul (a | b)* abb, pentru irul ababb, se observ c va parcurge secvena de stri
012123.
Irina Athanasiu 3/1/2002 Limbaje formale i automate

44
2.3.1.5 Simularea unui automat finit nedeterminist

Prezentm n continuare un algoritm pentru simularea unui automat finit nedeterminist. Algoritmul
citete un ir de intrare i verific dac automatul l accepta sau nu. Se consider c automatul a fost
construit direct pornind de la expresia regulat. n consecin automatul va satisface urmtoarele
proprieti:

1. are cel mult de dou ori mai multe stri fa de numrul de simboli i operatori care apar n expresia
regulat;
2. are o singur stare de start i o singur stare de acceptare. Dintr-o stare de acceptare nu pleac nici o
tranziie;
3. din fiecare stare pleac fie o tranziie pentru un simbol din alfabetul de intrare T, fie o -tranziie sau
doua -tranziii.

Se consider c exist un mecanism prin care se poate stabilii faptul c s-a ajuns la sfritul irului de
intrare (test de tip eof). Algoritmul de simulare se aseamn cu cel utilizat pentru construcia unui automat
finit determinist echivalent cu automatul N, diferenele constau n faptul c pentru fiecare mulime de stri
Q n care poate s ajung automatul pentru un prefix al irului x se consider pentru construirea mulimii
Q' de stri urmtoare numai simbolul curent din irul x. n momentul n care s-a ajuns la sfritul irului
(s-a ajuns la eof) dac n setul strilor curente este inclus i o stare de acceptare (final), atunci rspunsul
este "DA" altfel rspunsul este "NU".

S = -inchidere({s0}) # -inchidere(S) = {s' Q | s S, s' m(s,)} S
a = caracterul_urmtor
ct timp a eof execut
S = -inchidere(mutare(S,a)) # mutare(S,a) = m(s',a)
s' S
a = caracterul_urmtor


daca S F
atunci rezultat "DA"
altfel rezultat "NU"


Algoritmul poate s fie implementat eficient utiliznd dou liste i un vector indexat cu strile
automatului finit nedeterminist. ntr-o list se pstreaz mulimea strilor curente ale automatului, n
cealalt mulimea strilor urmtoare. Utiliznd algoritmul de calcul al strilor urmtoare pentru -tranziii
se calculeaz setul -nchidere pentru o stare dat. Vectorul este utilizat pentru a asigura funcionarea listei
ca o mulime n sensul c dac o stare este coninuta n list atunci ea nu trebuie s mai poat fi adugat.
Dup ce s-a terminat calculul -inchiderii pentru o stare se face schimbarea rolului celor dou liste.
Deoarece fiecare stare are cel mult dou tranziii, fiecare stare poate s produc cel mult dou stri noi. Fie
|N| numrul de stri pentru AFN. Deoarece n lista pot s fie memorate maximum |N| stri, calculul strii
urmtoare se poate face ntr-un timp proporional |N|. Deci timpul necesar pentru simularea AFN pentru
irul de intrare x va fi proporional cu |N| x |x|. S relum de exemplu automatul :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

45

---------------+
/ |
/ +-+ +-+ |
/ | |a | | |
/ / > |2|->|3|\ |
/ / | | | | \ |
+-+ +-+ / +-+ +-+ +-+ +-+ +-+ +-+ +--+
| | | |/ | |? | |a | |b | |b |--|
> |0|->|1| |6|->|7|->|8|->|9|->|10|
| | | |\ /| | | | | | | | |--|
+-+ +-+ \ +-+ +-+ / +-+ +-+ +-+ +-+ +--+
\ \ | |b | | / /\
\ > |4|->|5|/ /
\ | | | | /
\ +-+ +-+ /
\ /
--------------------

Acest AFN accept expresia regulata (a|b)*abb. S considerm de exemplu irul de intrare x = ab.
Evoluia celor dou liste va fi urmtoarea :


lista 1 lista 2
a
--------->

-i({0}) = {0,1,2,4,7} -i({3,8}) = {1,2,3,4,6,7,8}

b
<------------

-i({5,9}) = {1,2,4,5,6,7,9}

Se observ c s-a ajuns la mulimea {1,2,4,5,6,7,9} care nu conine o stare de acceptare deci irul x nu
este acceptat de ctre automat.
2.3.1.6 Probleme de implementare pentru automatele finite deterministe i nedeterministe

n compilatoare, automatele finite sunt utilizate pentru implementarea analizoarelor lexicale.
Specificarea atomilor lexicali se face sub forma de expresii regulate. Din acest motiv este interesant s
discutm modul n care pornind de la o expresie regulat putem s ajungem la un program care s
realizeze "execuia" sau altfel spus simularea automatului finit corespunztor. Din cele prezentate anterior
se observ c dndu-se o expresie regulat r i un ir de intrare x exist doua metode pentru a verifica dac
x L(r).
Se poate construi automatul finit nedeterminist (AFN) corespunztor expresiei regulate. Dac
expresia regulata r conine |r| simboli atunci aceasta construcie se face ntr-un timp proporional cu |r|.
Numrul maxim de stri pentru AFN este de maximum 2 x |r|, iar numrul de tranziii pentru fiecare stare
este 2 (conform construciei), deci memoria maxim necesar pentru tabela de tranziii este proporional
cu |r|. Algoritmul de simulare pentru AFN are un numr de operaii proporional cu |Q| x |x| deci cu |r| x |x|
(unde |x| reprezint lungimea irului x). Dac |x| nu este foarte mare soluia este acceptabil.
O alt abordare posibil este construirea automatului finit determinist (AFD) corespunztor
automatului finit nedeterminist construit pornind de la expresia regulat. Simularea AFD se face ntr-un
Irina Athanasiu 3/1/2002 Limbaje formale i automate

46
timp proporional cu |x| indiferent de numrul de stri ale AFD. Aceast abordare este avantajoas dac
este necesar verificarea mai multor iruri de lungime mare pentru o aceeai expresie regulat (vezi de
exemplu situaia n care un editor de texte are o funcie de cutare pentru un subir de o form general
dat). Pe de alta parte exist expresii regulate pentru care AFD-ul necesit un spaiu de memorie
exponenial n numrul de simboli i operatori din expresia regulata. S considerm de exemplu expresia :

(a|b)*a(a|b)(a|b)...(a|b)

care reprezint un ir de simboli a i b i care se termina cu (n -1) simboli (a|b). irul reprezentat de
aceasta expresie regulat este format din cel puin n simboli a i b, astfel nct exist un simbol a pe
poziia n de la sfritul irului. Se observ c un AFD pentru recunoaterea acestei expresii trebuie s
memoreze ultimele n caractere, deci sunt necesare cel puin 2
n
stri (pentru a codifica toate combinaiile
posibile de caractere a i b de lungime n).
O alta abordare este de a utiliza un AFD, fr a construi ntreaga tabela de tranziii. Ideea este de a
determina o tranziie numai dac este necesar. Odat calculat o tranziie aceasta este memorat ntr-o
memorie asociativ. Ori de cte ori este necesar o tranziie se face nti o cutare n memoria asociativ.
Dac nu se gsete se face calculul.
Concentrnd rezultatele se obine urmtoarea tabel :


AFN AFD
complexitate construcie O(|r|) O(|r| x |T|)
memorie ocupat O(|r|) O(c
|r|
)
complexitate simulare O(|r| x |x|) O(|x|)
2.3.1.7 Minimizarea numrului de stri pentru AFD

Se poate demonstra c fiind dat o mulime regulata exist un unic automat finit determinist cu numr
minim de stri care accept limbajul generat de mulimea respectiv. n cele ce urmeaz considerm c
automatul finit are funcia de tranziie definit pentru ntreg domeniul Q X T. Dac exist combinaii (s,i)
Q x T pentru care m(s,i) nu este definit considerm o extindere a automatului pentru care adugm o
stare d. Pentru i T, m(d, i) = d, pentru s Q, i T pentru care m(s,i) este nedefinit n automatul
iniial vom considera c m(s, i) = d.
Construim o extensie a funciei m, m : x T* Q n modul urmtor :

1. ( s Q) (m(s, ) = s)
2. ( s Q)( w T*)(i I)(m(s, wi) = m(m(s, w), i)

Fie w T* spunem c w separ strile s, t Q dac i numai dac m(s,w) F i m(t,w) F sau
m(t,w) F i m(s,w) F.
Un automat este redus dac i numai dac pentru oricare dou stri q1, q2 F exist o secven de
intrare care s le separe. Problema construirii automatului redus echivalent unui automat dat este de fapt
problema construirii partiiilor induse de o relaie de echivalen. Iniial, considerm ca mulimea Q este
mprit n F, Q - F i {d}. Fie P = { Q - F, F, {d}}. n continuare pentru o mulime de stri A P, pentru
care |A| > 1, se parcurg simbolii de intrare. Dac pentru un simbol a i strile q1, q2 A, m(q1, a) i
m(q2, a) fac parte din elemente diferite din P nseamn c strile succesoare strilor q1 i q2 nu fac parte
din aceeai mulime a partiiei. Corespunztor Q va fi mprit n 4 mulimi, etc. Algoritmul corespunztor
este:
Descrierea algoritmului de minimizare este:

Irina Athanasiu 3/1/2002 Limbaje formale i automate

47
P = {F, Q - F, {d}}
repeta
P' = P
repeta
alege A P, Q ne marcat si marcheaz A
new =
daca |A| > 1
alege first A
A' = A - {first}
cat timp A' executa
alege next A'
A' = A' - {next}
se_imparte = false
T' = T
cat timp T' si nu se_imparte executa
alege a T'
T' = T' - {a}
goto_first = tranz_AFD[first,a]
goto_next = tranz_AFD[next, a]
daca goto_next si goto_first sunt n elemente
(multimi) diferite din P
new = new {next}
se_imparte = true



daca new
P = P - {A}
A = A - new
P = P {A}{new}

pana nu mai exist A P ne marcat

pana P = P'

Algoritmul utilizat nu este optim din punct de vedere al timpului de execuie. La fiecare pas mulimea
de stri Q se mparte n cel mult dou noi mulimi : new i Q \ new. Exist algoritmi pentru care numrul
de operaii este proporional cu n log n. S considerm urmtorul exemplu :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

48
b
---
\ /
+---+
| | b
b > | 2 |<---------------------+
/ +-| | |
+---+ /a | +---+ |
start | |/ | +---+ +---+ +------+
-------| 0 | a \/| | b | | b |+----+|
| |---> | 1 |---->| 3 |--->|| 4 ||
+---+ | | | | |+----+|
+---+ +---+ +------+
/\ || a | |
-- |+-<--------+ |
a | |
| a |
+--<--------------------+

Iniial P = {{0, 1, 2, 3}, {4}}, A = {0, 1, 2, 3}. Fie first = 0, next = 1, m(0, a), m(1, a) A; m(0, b),
m(1, b) A. Pentru next = 2, m(0, a) A, m(2, a) A; m(0, b) A, m(2,b) A. Continund pentru next
= 3, m(0, b) A dar m(3, b) A, deci new = {3}. S-a obinut P = {{0, 1, 2}, {3}, {4}}. Se observ c P
P'. Urmeaz A = {0, 1, 2}. Se obine m(0, b) Q dar de aceasta data m(1, b) A. Rezult P = {{0, 2},
{1}, {3}, {4}}. Pentru A = {0, 2} se obine m(0, a), m(2, a) {1}; m(0, b), m(2, b) A. Se obine
automatul finit determinist cu numr minim de stri:

b b
-- --------<--------------------+
\/ / |
+---+ / |
start | |/ +---+ +---+ +-----+
-----> |02 | a | | b | | b |+---+|
| |--- | 1 |------>| 3 |--- || 4 ||
+---+ | | | | |+---+|
+---+ +---+ +-----+
/\ || a | |
-- |+-<--------+ |
a | |
| a |
+--<--------------------+
Irina Athanasiu 3/1/2002 Limbaje formale i automate

49
2.3.2 Automate cu stiv (pushdown)

Un astfel de automat are o memorie organizat ca o stiv :

+---------------
|a0|a1|...|an| banda de intrare
+---------------
\ cap de citire
\
+---------+
| unitate | +----+
| de |---| z1 |
| control | |----|
+---------+ | z2 |
|----|
|... | memoria stiva
| |
|----|
| zn |
+----+

Un automat cu stiv (PDA) este un obiect matematic P = (Q, T, Z, m, q0, z0, F) unde:

Q - este o mulime finit de simboli ce reprezint strile posibile pentru unitatea de control a
automatului;
T - este mulimea finit a simbolilor de intrare;
Z - este mulimea finit a simbolilor utilizai pentru stiv;
m - este o funcie, m : S x (T {}) x Z P(S x Z*) este funcia care descrie modul n care se obine
starea urmtoare i informaia care se introduce n stiv pentru o combinaie stare, intrare, coninut
stiv dat;
q0 Q este starea iniial a unitii de control;
z0 Z este simbolul aflat n vrful stivei n starea iniial;
F Q reprezint mulimea finit a strilor finale.

O configuraie de stare a automatului este un triplet (q, w, ) Q x T* x Z* unde :

q - reprezint starea curent a unitii de control;
w - reprezint partea din irul de intrare care nu a fost nc citit. Dac w = nseamn c s-a ajuns la
sfritul irului de intrare;
- reprezint coninutul stivei.

O tranziie a automatului este reprezentat prin relaia |- asupra mulimii configuraiilor automatului,
este definit n modul urmtor :

(q, aw, z) |- (q', w, )

unde (q', ) m(q, a, z), q Q, a T {}, w T*, z Z, Z*.
Dac a nseamn c, dac unitatea de control este n starea q, capul de citire este pe simbolul a iar
simbolul din vrful stivei este z atunci automatul poate s i schimbe configuraia n modul urmtor :
starea unitii de control devine q', capul de citire se deplaseaz cu o poziie la dreapta iar simbolul din
vrful stivei se nlocuiete cu .
Irina Athanasiu 3/1/2002 Limbaje formale i automate

50
Dac a = nseamn c avem o -tranziie pentru care simbolul aflat n dreptul capului de citire pe
banda de intrare nu conteaz (capul de citire nu se va deplasa), ns starea unitii de control i coninutul
memoriei se pot modifica. O astfel de tranziie poate s aib loc i dup ce s-a parcurs ntregul ir de
intrare.
Dac se ajunge ntr-o configuraie pentru care stiva este goal nu se mai pot executa tranziii. Relaia
|- se poate generaliza la |-
i
, |-
+
, |-
*
, ntr-o manier similar relaiei de derivare pentru forme propoziionale.
O configuraie iniial pentru un automat cu stiv este o configuraie de forma (q0, w, z0) unde w
T*. O configuraie final este o configuraie de forma (q, , ) cu q F, Z*.
Aa cum a fost definit automatul cu stiv este nedeterminist, adic pentru o configuraie dat n cazul
general pot s urmeze mai multe configuraii urmtoare.
Un automat cu stiv este determinist dac pentru orice configuraie exist cel mult o singur tranziie
urmtoare. Mai precis un automat cu stiv PD = (Q, T, Z, m, q0, z0, F) este determinist dac pentru orice
(q, a, z) x (T {}) x Z sunt ndeplinite urmtoarele condiii:

1. |m(q, a, z)| 1,
2. dac m(q, , z) atunci m(q, a, z) = pentru a T

Spunem c un ir w este acceptat de un automat cu stiv prin stri finale dac este posibil o evoluie
ca (q0, w, z0) |-* (q, , ) pentru q F i Z*. Limbajul acceptat de un automat cu stiv P n acest
mod se noteaz cu L(P). Se observ c pentru un automat cu stiv nedeterminist pentru un ir dat sunt
posibile mai mute evoluii.
S considerm de exemplu automatul cu stiv care accept limbajul L = {0
n
1
n
| n > 0}.

P = ({q0, q1 ,q2}, {0,1}, {z, 0}, m, q0, z,{q0}) unde

m(q0,0,z) = {(q1,0z)}
m(q1,0,0) = {(q1,00)}
m(q1,1,0) = {(q2,)}
m(q2,1,0) = {(q2,)}
m(q2,,z) = {(q0,z)}

Pentru toate celelalte elemente (s, a, z) Q x (T {}) x Z care nu sunt descrise de regulile de mai
sus, m(s, a, z) = . Se observ c automatul copiaz toate zerourile de pe banda de intrare n stiv i apoi
descarc stiva pentru fiecare simbol 1 ntlnit la intrare. De exemplu pentru irul 0011, automatul va
executa urmtoarea secven de tranziii :

(q0,0011,z) |- (q1,011,0z)
|- (q1,11,00z)
|- (q2,1,0z)
|- (q2,,z)
|- (q0,,z)

Pentru irul de intrare 011 care nu aparine limbajului evoluia va fi :

(q0,011,z) |- (q1,11,0z)
|- (q2,1,z)
|- (q2,1,z)
|- (q0,1,z)

Irina Athanasiu 3/1/2002 Limbaje formale i automate

51
Se observ c dei s-a ajuns ntr-o stare final nu s-a ajuns la sfritul irului de intrare deci irul nu a
fost acceptat. Pentru irul de intrare 001, evoluia este :

(q0,001,z) |- (q1,01,0z)
|- (q1,1,00z)
|- (q2,,0z)

n acest caz s-a ajuns la sfritul irului dar starea n care se gsete automatul nu este final deci nici
acest ir nu este acceptat.
Pentru a demonstra c L(P) = {0
n
1
n
} trebuie s artm c {0
n
1
n
} L(P) i L(P) {0
n
1
n
}. Se pot face
urmtoarele observaii :

(q0,0,z) |- (q1,,0z)
(q1,0
i
,0z) |-i (q1,,0
i+1
z)
(q1,1,0
i+1
z) |- (q2,,0
i
z)
(q2,1
i
,0
i
z) |-i (q2,,z)
(q2,,z) |- (q0,,z)

Rezult c pentru irul 0
n
1
n
, n > 1 se obine :

(q0,0
n
1
n
,z) |-
2n+1
(q0, , z), n > 1
(q0,,z) |-
0
(q0,,z)

Deci {0
n
1
n
} L(P). Trebuie s artm c i L(P) {0
n
1
n
} . Se observ c pentru a accepta un ir din
{0
n
1
n
} pentru care n > 0, P trece n mod obligatoriu prin succesiunea de stri q0, q1, q2, q0.

Dac (q0, w, z) |-
i
(q1, , ), i > 1 nseamn ca w = 0
i
i = 0
i
z.
Dac (q2, w, ) |-
i
(q2, , ) nseamn c w = 1
i
i a = 0
i
.
Dac (q1, w, ) |- (q2, , ) nseamn c w = 1 i a = 0
Dac (q2, w ,z) |-
*
(q0, , z) nseamn c w = .

Deci dac (q0, w, z) |-
i
(q0, , z) atunci fie w = i i = 0 fie w = 0
n
1
n
, i = 2 n + 1. Deci L(P) {0
n
1
n
} .
S considerm i automatul care accept limbajul L = {wcw
R
| w {a,b}
+
}, P = ({q0, q1, q2}, {a, b},
{z, a, b}, m,q0, z, {q2}) unde :

m(q0,x,y) = {(q0,xy)}, x {a, b}, y {z, a, b}
m(q0,c,x) = {(q1,x)}, x {z, a, b}
m(q1,x,x) = {(q1,)}, x {a, b}
m(q1,,z) = {(q2,)}

Funcionarea automatului parcurge trei etape. nti se copiaz n stiv irul w, apoi se identific
simbolul c care marcheaz mijlocul irului, dup care se descarc stiva conform w
R
.
S considerm i automatul care accept limbajul L = {ww
R
| w {a,b}
+
}, P = ({q0, q1, q2}, {a, b},
{z, a, b}, m,q0, z, {q2}) unde :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

52
m(q0,x,z) = {(q0,xz)}, x {a, b}
m(q0,x,x) = {(q0,xx),(q1,)}, x {a, b}
m(q0,a,b) = {(q0,ab)}
m(q0,b,a) = {(q0,ba)}
m(q1,x,x) = {(q1,)}, x {a, b}
m(q1,b,b) = {(q1,)}

De data aceasta nu se tie unde se gsete mijlocul irului, astfel nct ori de cte ori simbolul din
vrful stivei este acelai cu cel de la intrare s-ar putea s se fi gsit mijlocul irului. Se observ c cel de al
doilea automat nu este determinist i c nici nu se poate construi un automat determinist care s accepte
limbajul L = {ww
R
| w {a,b}
+
}.
S considerm de exemplu secvena de micri pentru irul abba.

(q0,abba,z) |- (q0,bba,az)
|- (q0,ba,baz)
|- (q0,a,bbaz)
|- (q0,,abbaz)

Se observ c pentru aceast secven de tranziii nu se ajunge ntr-o stare final. Automatul fiind
nedeterminist trebuie s cercetm ns toate secvenele de tranziii posibile. O alt secven este:

(q0,abba,z) |- (q0,bba,az)
|- (q0,ba,baz)
|- (q1,a,az)
|- (q1,,z)
|- (q2,,)

Rezult ca automatul ajunge n starea q2 deci accept irul abba.

2.3.2.1 Automate cu stiv cu acceptare prin stiv goal
Fie P = (Q, T, Z, m, q0, z0, F) un automat cu stiv. Spunem c un ir w T
*
este acceptat de P prin
stiva goal dac exist o evoluie pentru care (q0, w, z0) |-
+
(q, , ) pentru q Q.
Fie Le(P) mulimea irurilor acceptate de P prin stiva goal. Se poate demonstra urmtorul rezultat.
Dac L(P) este limbajul acceptat de automatul P prin stri finale atunci se poate construi un automat cu
stiv P' astfel nct L(P) = Le(P').
Automatul P' va simula funcionarea automatului P. Ori de cte ori P intr ntr-o stare final, P' poate
continua simularea sau intr ntr-o stare speciala qe n care golete stiva (qe Q). Se poate ns observa c
P poate s execute o secven de micri pentru un ir de intrare w care s permit golirea stivei fr ca
irul s fie acceptat de ctre automatul P (pentru P nu conteaz dect ajungerea ntr-o stare final). Pentru
a evita astfel de situaii se consider un simbol special pentru iniializarea stivei, simbol care nu poate s
fie scos din stiva dect n starea qe. Fie P' = (Q {qe, q'}, T, Z {z'}, m', q', z', ) unde funcia m' este
definit n modul urmtor :

1. dac (r, t) m(q, a, z) atunci (r, t) m'(q, a, z), pentru r, q Q, t Z
*
, a T {}, z Z.
2. m'(q', , z') = {(q0, z0z')}. P' i iniializeaz stiva cu z0z' (z' reprezint simbolul de iniializare al
stivei pentru P').
3. pentru q F i z Z, (qe, ) m'(q, , z);
4. pentru z Z {z'}, m'(qe, , z) = {(qe, )}

Irina Athanasiu 3/1/2002 Limbaje formale i automate

53
Se observ c :

(q',w,z') |- (q0,w,z0z') |-
n
(q, , y
1
y
2
... y
r
)
|- (qe, , y
2
... y
r
)
|-
r-1
(qe, , )

cu y
r
= z' dac i numai dac (q0, w, z0) |-
n
(q, , y
1
y
2
... y
r-1
) pentru q F i y
1
y
2
... y
r-1
Z*. Deci
Le(P') = L(P).
Se poate demonstra i rezultatul invers, adic dndu-se un automat cu stiv i limbajul acceptat de
acesta prin stiva goal se poate construi un automat cu stiv care accept acelai limbaj prin stri finale.
2.3.2.2 Relaia ntre automate cu stiv i limbajele independente de context
Limbajele acceptate de automatele cu stiv sunt limbajele care pot s fie descrise de gramatici
independente de context. Dndu-se o gramatic independent de context s construim automatul care
accept limbajul generat de aceasta gramatica. Fie G = (N, T, P, S), se obine automatul cu stiv R = ({q},
T, N T, m, q, S, ) unde m este construit conform urmtoarelor reguli :

1. dac A P atunci (q, ) m(q, , A)
2. m(q, a, a) = {(q, )} pentru orice a T.

Se observ c automatul astfel construit va accepta limbajul prin stiv goal. Se poate arata c A
k

w dac i numai dac (q,w,A) |-
n
(q, , ) k, n > 1. Altfel spus exist o derivare S
+
w dac i numai dac
(q, w, S) |-
+
(q, , ). Rezult deci c L(G) = L(R). S construim de exemplu automatul care accept
limbajul expresiilor aritmetice G = ({, T, F}, {a, +, (, )}, P, ) unde P = { + T | T, T T * F | F, F
() | a}. Aplicnd construcia propus rezult R = ({q}, {a, +, *, (, )},{, T, F, a, +, *, (, )}, m, q, , )
unde m este definit n modul urmtor :

m(q, , ) = {(q, + T),(q, T)}
m(q, , T) = {(q, T * F),(q, F)}
m(q, , F) = {(q, ()),(q, a)}
m(q, b, b) = {(q, )} cu b {a,+,*,(,)}.

S considerm de exemplu o succesiune de configuraii pentru a + a * a.

(q, a + a * a, ) |- (q, a + a * a, + T)
|- (q, a + a * a, T + T)
|- (q, a + a * a, F + T)
|- (q, a + a * a, a + T)
|- (q, + a * a, + T)
|- (q, a * a, T)
|- (q, a * a, T * F)
|- (q, a * a, F * F)
|- (q, a * a, a * F)
|- (q, * a, * F)
|- (q, a, F)
|- (q, a, a)
|- (q, , ).

n reprezentarea tranziiilor vrful stivei a fost reprezentat n stnga. Se observ c secvena de tranziii
considerat, simuleaz urmtoarea secven de derivri de forme propoziionale :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

54
+ T T + T F + T a + T a + T * F a + F * F a + a * F a + a * a

Se observ ca n aceasta secven s-a nlocuit ntotdeauna cel mai din stnga neterminal. Din acest
motiv se spune c am utilizat o derivare stnga. Secvena de derivri anterioare poate s fie reprezentat de
urmtorul arbore de derivare.


/|\
/ | \
+ T
| /|\
| / | \
T T * F
| | |
| | |
F F a
| |
a a

Acest gen de construire de secvene de derivare i deci automatele cu stiv care accept limbaje prin
stiv goal sunt utilizate n analiza sintactic descendent.
Un tip special de automat cu stiv l reprezint automatul cu stiv extins = (Q, T, Z, m, q0, z0, F)
pentru care m : Q x (T {}) x Z
*
P(Q x Z
*
). Se observ c n acest caz din stiv se consider nu
numai simbolul din vrful stivei ci un ir de simboli plasat n vrful stivei. Considerm pentru acest tip de
automat c acceptarea se face prin stri finale ( i n acest caz se poate construi un automat echivalent care
s fac acceptarea prin stiv goal). S considerm de exemplu automatul care accept limbajul L = {ww
R

| w {a,b}
*
}. Fie P = ({q, p}, {a, b}, {a,b,S,z}, m, q, z, {p}) unde funcia m este definit n modul
urmtor:

m(q,a,) = {(q,a)}
m(q,b,) = {(q,b)}
m(q,,) = {(q,S)}
m(q,,aSa) = {(q,S)}
m(q,,bSb) = {(q,S)}
m(q,,Sz) = {(p,)}

De exemplu pentru secvena de intrare aabbaa este posibil urmtoarea secven de tranziii :

(q, aabbaa, z) |- (q, abbaa, az)
|- (q, bbaa, aaz)
|- (q, baa, baaz)
|- (q, baa, Sbaaz)
|- (q, aa, bSbaaz)
|- (q, aa, Saaz)
|- (q, a, aSaaz)
|- (q, a, Saz)
|- (q, , aSaz)
|- (q, , Sz)
|- (p, , )

Se observ ca datorit tranziiei m(q, , ) = {(q, S)} automatul este nedeterminist.
Irina Athanasiu 3/1/2002 Limbaje formale i automate

55
Se poate demonstra c pentru orice automat cu stiv extins , exist un automat cu stiv P astfel nct
L() = L(P).
S revenim la problema acceptrii limbajelor independente de context de ctre automate cu stiv i s
considerm din nou exemplul expresiilor aritmetice. Pentru generarea irului a + a * a putem s
considerm i urmtoarea secven de derivri :

+ T + T * F + T * a + F * a + a * a T + a * a
F + a * a a + a * a

Se observ ca n aceast secven s-a nlocuit ntotdeauna cel mai din dreapta neterminal. Din acest
motiv se spune ca s-a construit o derivare dreapta. Considernd acest tip de derivri i parcurgndu-le n
ordine invers (de la sfrit) se poate introduce noiunea de reducere stnga. Fie gramatica G = (N,T,P,S) o
gramatic independent de context s presupunem c S
*
aAw aw
*
xw. Dac n fiecare derivare a
fost nlocuit de fiecare dat neterminalul cel mai din dreapta atunci se spune c aw se reduce stnga la
aAw dac A P. Dac este cel mai din stnga astfel de ir atunci spunem ca este nceputul irului
aw. Un nceput (handle) pentru o derivare dreapta este orice ir care este partea dreapta a unei producii
i poate s fie nlocuit de neterminalul corespunztor ntr-o form propoziional care a aprut dintr-o
derivare dreapta obinndu-se forma propoziional anterioar din derivarea dreapta.
S considerm de exemplu gramatica: G = ({S, A, B},{a, b, c, d}, {S Ac | Bd, A aAb | ab, B
aBbb | abb}, S). Aceast gramatic genereaz limbajul {a
n
b
n
c | n > 1} {a
n
b
2n
d | n > 1}. S considerm
urmtoarea secven de derivri S Bd aBbbd aabbbbd. Pentru irul obinut abb este nceput
deoarece aBbbd este forma propoziional anterioar din derivarea dreapta, n timp ce ab nu este deoarece
aAbbbd nu este o forma propoziional care poate s apar ntr-o derivare dreapta.
Relund din nou gramatica pentru expresii aritmetice i secvena de derivri dreapta :

+ T + T * F + T * a + F * a + a * a T + a * a
F + a * a a + a * a

Rezult arborele de derivare :


/| \
/ | \
+ T
| /| \
| / | \
T T * F
| | |
| | |
F F a
| |
| |
a a

Dac analizm acest arbore se vede c a (care reprezint frunza celui mai din stnga subarbore) este
un nceput, dac se face o reducere se obine arborele :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

56

/|\
/ | \
+ T
| /|\
| / | \
T T * F
| | |
| | |
F F a
|
|
a
Continund se ajunge la :


/|\
/ | \
+ T
/|\
/ | \
T * F
| |
F a
|
a

Urmtorul nceput este a, etc.
Se observ c pentru a identifica un nceput pentru o form propoziional obinut printr-o derivare
dreapta se consider secvena frunzelor celui mai din stnga subarbore de adncime 1 (toate nodurile
acestuia sunt fie frunze fie noduri din care se deriveaz frunze). De exemplu :

| | |
a sau F sau T sau T
/|\
/ | \
T * F

pentru care a, F, T respectiv T * F reprezint pri dreapta ale unor producii. Aceasta metoda de
reducere a arborilor de derivare se numete reducerea capetelor ("handle pruning").
Dndu-se o gramatic independent de context G = (N, T, P, S) se poate construi un automat cu stiv
extins care s opereze conform metodei reducerii capetelor n modul urmtor :

R = ({q, r},T,N T {$}, m, q, $, {r}) unde:

1. dac A P atunci (q, A) m(q, , )
2. m(q, a, ) = {(q, a)} pentru orice a T. Se observ c terminalele sunt copiate n stiva;
3. m(q, , $S) = {(r, )}.

S construim utiliznd aceast tehnic automatul cu stiv extins care accept limbajul expresiilor
aritmetice :

R = ({q, r},{a, +, *, (, )},{a, +, *, (, ), T, F, , $}, m, q, $,{r}) unde

Irina Athanasiu 3/1/2002 Limbaje formale i automate

57
m(q, b, ) = {(q, b)}, pentru b {a, +, *, (, )}
m(q, , + T) = {(q, )}
m(q, , T) = {(q, )}
m(q, , T * F) = {(q, T)}
m(q, , F) = {(q, T)}
m(q, , ()) = {(q, F)}
m(q, , a) = {(q, F)}
m(q, , $) = {(r, )}

Fiind vorba de o derivare dreapta, vrful stivei a fost figurat n dreapta. Se observ c aceast secven
de tranziii este unica secven ce duce la acceptarea irului de intrare. Pentru irul a + a * a, automatul R
va executa urmtoarele tranziii :

(q, a + a * a, $) |- (q, + a * a, $a)
|- (q, + a * a, $F)
|- (q, + a * a, $T)
|- (q, + a * a, $)
|- (q, a * a, $ +)
|- (q, * a, $ + a)
|- (q, * a, $ + F)
|- (q, * a, $ + T)
|- (q, a, $ + T *)
|- (q, , $ + T * a)
|- (q, , $ + T * F)
|- (q, , $ + T)
|- (q, , $)
|- (q, , ?)

Automatele cu stiv construite dup modelul prezentat anterior vor fi utilizate n analiza sintactic de
tip ascendent.

Avnd n vedere echivalena dintre un automat cu stiv i limbajele independente de context, vom
spune c un limbaj independent de context este determinist dac este acceptat de un automat cu stiv
determinist. Vom modifica puin condiia de acceptare, considernd c un limbaj independent de context
este determinist dac exist un automat cu stiv determinist care accept limbajul L$. Simbolul $ este un
simbol care nu apare n alfabetul peste care este definit limbajul L. Se observ c utilizarea acestui simbol
care apare concatenat cu fiecare ir din L indic de fapt posibilitatea automatului cu stiv de a recunoate
sfritul irului. n acest mod se extinde puin clasa limbajelor independente de context deterministe.
Se pune ntrebarea dac orice limbaj independent de context este determinist. S considerm de
exemplu limbajul :
L = {ww
R
| w {a, b, c}

Dup cum s-a mai discutat un automat cu stiv care accept acest limbaj trebuie s ghiceasc unde este
mijlocul irului pentru ca s nceap descrcarea stivei. Intuitiv, o astfel de operaie nu se poate realiza cu
un dispozitiv determinist.
Propoziie. Exist limbaje independente de context care sunt acceptate de automate cu stiv
nedeterministe i nu sunt acceptate de automate cu stiv deterministe.
2.3.3 Maina Turing

Irina Athanasiu 3/1/2002 Limbaje formale i automate

58
O main Turing este un acceptor care "tie" s scrie pe banda de intrare. n acest mod banda de
intrare devine memorie auxiliar. Maina Turing a fost definit de ctre matematicianul englez Alan
Turing (1912 - 1954) n anul 1930. Cnd a inventat maina care i poart numele, Turing era interesat nu
de calculatoare ci de posibilitatea specificri i rezolvri problemelor matematice utiliznd mijloace
automate. Adic, poate s fie rezolvat orice problema matematic utiliznd nite reguli elementare de
prelucrare a irurilor ?.
Structura unei maini Turing este:


+----------------------------
| banda de intrare
+----------------------------


| cap de citire / scriere
|
+---------+
| unitate |
| de |
| control |
+---------+

Unitatea de control comand execuia micrilor. O micare este format din :

stabilirea strii urmtoare pentru unitatea de control;
scrierea unui simbol pe banda de intrare sau execuia unei deplasri cu o poziie spre stnga sau spre
dreapta.

Banda de intrare este mrginit la stnga i infinit la dreapta. Dup poziia ocupat de irul de intrare
pe banda aceasta conine blancuri. n cele ce urmeaz vom indica simbolul blanc cu ajutorul caracterului #
(presupunnd c acest simbol nu face parte din alfabetul limbajului pentru care se construiete maina). De
asemenea vom utiliza caracterele L i respectiv R pentru a indica o deplasare la stnga respectiv la
dreapta. Maina Turing poate s scrie pe banda de intrare, deci poate s scrie att informaii intermediare
ct i un rspuns nainte de a se oprii. Maina Turing are o stare special numit stare de oprire (de halt)
pe care o vom nota n continuare cu h. S considerm o definiie formal a noiunii de main Turing.
Se numete main Turing obiectul matematic :

MT = (Q, T, m, q
0
)

unde

Q este o mulime finit a strilor mainii Turing, h Q;
T este alfabetul finit de intrare care conine simbolul # dar nu conine simbolii L i R;
m este funcia de tranziie

m : Q x T (Q {h}) x (T {L, R}).

q
0
Q este starea iniial a mainii Turing;

Dac q Q, a T i m(q, a) = (p, b) nseamn c fiind n starea q, avnd simbolul a sub capul de
citire maina trece n starea p. Dac b T atunci simbolul a va fi nlocuit cu b, altfel capul se va deplasa
cu o poziie la stnga sau la dreapta n funcie de valoarea simbolului b {L, R}. Se observ c maina
Turing a fost definit ca un acceptor determinist.
Irina Athanasiu 3/1/2002 Limbaje formale i automate

59
ncetarea funcionrii mainii Turing se face dac se ajunge n starea h (cnd maina se oprete) sau
dac se ncearc deplasarea la stnga dincolo de captul din stnga al benzii. n acest ultim caz se spune ca
maina s-a agat (a ajuns ntr-o stare de agare - hanging state).
Definiia anterioar corespunde mainii Turing standard. Fa de aceast definiie exist diferite
variante, care permit ca n aceeai micare s se fac i o scriere i o deplasare sau care consider c banda
este infinit la ambele capete. Se va arta c toate aceste variante conduc la acceptoare echivalente ca
putere.
S considerm un exemplu de main Turing MT = ({q0, q1}, {a, #}, m, q0), unde:

m(q0, a) = (q1, #)
m(q0, #) = (h, #)
m(q1, a) = (q0, a)
m(q1, #) = (q0, R)

S considerm c pe banda de intrare se gsete irul aaa i c poziia capului este pe primul caracter
din ir. Se observ c pentru aceast stare iniial, primul simbol a este nlocuit cu #, noua stare fiind q1.
Pentru q1, dac sub capul de citire se gsete un caracter # atunci se va face o deplasare la dreapta starea
devenind q0. Se continu evoluia ntr-o manier similar pn cnd n starea q0 capul de citire se gsete
pe un caracter #. n acest moment se trece n starea h i maina se oprete. Rezult ca evoluia mainii
duce la tergerea unui ir de a-uri nscris pe banda de intrare.
S considerm i urmtorul exemplu MT = ({q0}, {a, #}, m, q0), unde

m(q0, a) = (q0, L)
m(q0, #) = (h, #)

n acest caz maina caut primul simbol # la stnga poziiei din care pleac capul de citire / scriere. La
gsirea acestui simbol se trece n starea h. Dac nu exist un astfel de simbol maina nceteaz s
funcioneze cnd ajunge la captul din stnga al benzii, dar nu se oprete (este n stare de agare).
O configuraie pentru o main Turing este un element din mulimea :

(Q {h}) x T
*
x T x (T
*
(T - {#}) {})

Elementele unei configuraii sunt:
starea curent q (Q {h})
irul aflat pe banda de intrare la stnga capului de citire / scriere (a T
*
)
simbolul aflat sub capul de citire / scriere ( i T)
irul aflat la dreapta capului de citire / scriere ( (T* (T - {#}) {})).
Se observ c, deoarece irul de intrare este finit, n timp ce banda de intrare este infinit la dreapta
putem s considerm ntotdeauna c irul se termin cu un caracter care nu este # (oricum n continuare pe
band apar numai caractere #). Deci o configuraie este de forma (q, a, i, ). Pentru simplificare, o
configuraie se poate reprezenta i sub forma (q, ai), subliniind simbolul pe care se gsete capul de citire
/ scriere.
Asupra configuraiilor se poate defini o relaie de tranziie |- n modul urmtor. Fie (q1, w1, a1, u1) i
(q2, w2, a2, u2) dou configuraii. Atunci:

(q1,w1,a1,u1) |- (q2,w2,a2,u2)

# w1 a1 u1# # w1a1 u1 # # w1 a1 u1 #
# w2 a2 u2# # w2 a2 u2 # # w2 a2 u2 #

Irina Athanasiu 3/1/2002 Limbaje formale i automate

60
dac i numai dac exist b T {L, R} astfel nct m(q1, a1) = (q2, b) i este ndeplinit una dintre
urmtoarele condiii:

1. b T, w1 = w2, u1 = u2, a2 = b;

2. b = L, w1 = w2a2
dac a1 # sau u1
u2 = a1 u1
altfel u2 = // capul de citire / scriere este poziionat dup irul de intrare
3. b = R, w2 = w1a1
dac u1 =
u2 =
a2 = #
altfel u1 = a2 u2

n cazul 1 se face nlocuirea simbolului curent de pe banda de intrare (a) cu b. n al doilea caz este
descris o micare la stnga, respectiv n cazul 3 se descrie o micare la dreapta.
Dac b = L i w1 = atunci (q1, w1, a1, u1) nu are o configuraie urmtoare, n acest caz se spune c
(q1, w1, a1, u1) este o configuraie de agare, maina fiind ntr-o stare de agare (hanging state).
Pentru relaia |- se poate considera nchiderea reflexiv i tranzitiv notat cu |-*.

2.3.3.1 Calcule realizate de Maina Turing
Un calcul efectuat de o maina Turing este o secven de configuraii c0, c1, ..., cn astfel nct n 0 i
c0 |- c1 |- ... |- cn. Se spune despre calcul c are loc n n pai.
Termenul de calcul nu a fost utilizat ntmpltor. Se poate considera c o main Turing tie s
evalueze funcii definite pe iruri de simboli cu valori n iruri de simboli. Dac T1 i T2 sunt doua
mulimi alfabet care nu conin simbolul #, s considerm funcia f : T1* T2*. Spunem ca MT = (Q, T,
m, s) calculeaz f dac T1, T2 T i pentru orice ir w T1* dac u = f(w), u T2*, atunci (s, #w#) |-*
(h, #u#). Se observ c s-a considerat c capul este poziionat dup sfritul irului de intrare att la
nceputul execuiei ct i la sfritul acesteia.
Dac pentru o funcie f dat exist o maina Turing care o calculeaz spunem c funcia f este Turing
calculabil.
S considerm de exemplu maina Turing MT = ({q0, q1, q2}, {a, b, #}, m ,q0) unde funcia m este
definit n modul urmtor:

m(q0, a) = (q1, L)
m(q0, b) = (q1, L)
m(q0, #) = (q1, L)
m(q1, a) = (q0, b)
m(q1, b) = (q0, a)
m(q1, #) = (q2, R)
m(q2, a) = (q2, R)
m(q2, b) = (q2, R)
m(q2, #) = (h, #)

S considerm evoluia pentru irul de intrare aab.

Irina Athanasiu 3/1/2002 Limbaje formale i automate

61
(q0, #aab#) |- (q1, #aab#)
|- (q0, #aaa#)
|- (q1, #aaa#)
|- (q0, #aba#)
|- (q1, #aba#)
|- (q0, #bba#)
|- (q1, #bba#)
|- (q2, #bba#)
|- (q2, #bba#)
|- (q2, #bba#)
|- (q2, #bba#)
|- (h, #bba#)

Pentru irul vid evoluia este :

(q0, ##) |- (q1, ##) |- (q2, ##) |- (h, ##)

Funcia calculat de aceast main Turing este funcia de interschimbare a caracterelor a i b.
Din domeniul irurilor putem s trecem n domeniul numerelor naturale considernd reprezentarea
unar a numerelor naturale. Adic utiliznd un alfabet I care conine un singur simbol, I diferit de #,
reprezentarea unui numr natural n este data de irul = I
n
. Se observ c numrul 0 este reprezentat de
irul vid. n acest caz o funcie f : N N este calculat de o main Turing, dac aceasta calculeaz f' : I
*

I
*
unde f'() = cu I
n
i I
f(n)
pentru orice numr natural.
De la un singur argument funcia f se poate extinde la mai multe argumente - f : N
k
N pentru care
corespunde f' : (I {,})
*
I
*
cu f'() = pentru un ir de forma i
1
, i
2
, ..., i
k
,... i
j
I
nj
, 1 j k, i
I
f(n1,...,nk)
.
S considerm de exemplu funcia succesor f(n) = n + 1, n numr natural. MT = ({q0}, {i, #}, m, q0)
cu

m(q0, I) = (h, R)
m(q0, #) = (q0, I)

De exemplu (q0, #II#) |- (q0, #III#) |- (h, #III#). n general :

(q0, #I
n
#) |- (q0, #I
n
I#) |- (h, #I
n+1
#)

O main Turing poate s fie utilizat i ca acceptor de limbaj. i anume s considerm un limbaj L
definit asupra alfabetului T care nu conine simbolii #, D i N. Fie dL : T* {D, N} o funcie definit n
modul urmtor - pentru w T*

D dac w L
/
dL(w) =
\
N dac w L

Se spune ca limbajul L este decidabil n sens Turing (Turing decidable) dac i numai dac funcia dL
este calculabil Turing. Dac dL este calculat de o maina Turing MT spunem ca MT decide L.
S considerm de exemplu limbajul L = {w T* | |w| mod 2 = 0, T = {a}} (limbajul irurilor peste
alfabetul T = {a} care au lungimea un numr par). Funcia dL corespunztoare poate s fie calculat de
urmtoarea main Turing :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

62
MT = ({q0, q1, q2, q3, q4, q5, q6}, {a, D, N, #}, m , q0)

unde m este o funcie parial definit n modul urmtor :

m(q0, #) = (q1, L) pornim spre stnga
m(q1, a) = (q2, #) se terge un a
m(q1, #) = (q4, R) s-au ters un numr par de a
m(q2, #) = (q3, L) s-a ters un a se continu spre stnga
m(q3, a) = (q0, #) s-au ters doi de a, suntem ca la nceput
m(q3, #) = (q6, R) s-a ajuns la stnga cu un numr imapar de a
m(q4, #) = (q5, D) s-au ters zero sau un numr par de a
m(q5, D) = (h, R) rspuns D i oprire
m(q5, N) = (h, R) rspuns N i oprire
m(q6, #) = (q5, N) au fost un numr impar de a

S considerm evoluia mainii pentru un ir corect :

(q0, #aa#) |- (q1, #aa#) |- (q2, #a#) |- (q3, #a#)
|- (q0, ##) |- (q1, ##) |- (q4, ##)
|- (q5, #D#) |- (h, #D#)

Pentru un ir incorect se obine :

(q0, #aaa#) |- (q1, #aaa#) |- (q2, #aa#) |- (q3, #aa#)
|- (q0, #a#) |- (q1, #a#) |- (q2, ##)
|- (q3, ##) |- (q6, ##) |- (q5, #N#)
|- (h, #N#)

Noiunea de acceptare este mai larg dect noiunea de decidabilitate n legatura cu limbajele. i
anume dac L este un limbaj asupra alfabetului T, spunem ca limbajul L este Turing acceptabil dac exist
o maina Turing care se oprete dac i numai dac w L.
Limbajele Turing decidabile sunt i Turing acceptabile. Reciproca nu este ns adevarat.

Fie limbajul :

L = {w {a, b}* | w conine cel puin un simbol a}

considernd maina Turing MT = ({q0}, {a, b, #}, m, q0) cu

m(q0, a) = (h, a)
m(q0, b) = (q0, L)
m(q0, #) = (q0, L)

Se poate constata ca dac pe banda de intrare se gsete un ir din limbaj atunci pornind din
configuraia iniial se va face cutarea unui simbol a prin deplasare spre stnga. Dac un astfel de caracter
este gsit maina se oprete (deci accept irul). Dac ns pe banda de intrare se gsete un ir care nu
aparine limbajului atunci maina va intra n starea de agare dup ce a ajuns la captul din stnga al
benzii.

Irina Athanasiu 3/1/2002 Limbaje formale i automate

63
2.3.3.2 Compunerea mainilor Turing

Pentru a evidenia "puterea" de calcul a mainilor Turing vom prezenta mecanismul prin care o
main Turing se poate construi pe baza unor maini Turing mai simple.

Propoziie Fie MT o maina Turing i fie (q
i
, w
i
a
i
u
i
), (i = 1, 2, 3) configuraii ale acestei maini. Dac
sunt posibile evoluiile :

(q
1
, w
1
a
1
u
1
) |-* (q
2
, ww
2
a
2
u
2
) i
(q
2
, w
2
a
2
u
2
) |-* (q
3
, w
3
a
3
u
3
)

atunci este posibila i evoluia :

(q
1
, w
1
a
1
u
1
) |-* (q
3
, ww
3
a
3
u
3
)

Justificare. n evoluia din (q
2
, ww
2
a
2
u
2
) n (q
3
, w
3
a
3
u
3
) maina nu poate s ajung pe banda de intrare
pe un simbol aflat la stnga irului w2 (ntr-o astfel de situaie s-ar ajunge la marginea din stnga a benzii,
deci s-ar intra n starea de agare i deci nu s-ar mai ajunge n configuraia urmtoare). Deoarece maina
are o funcionare determinist va rezult aceeai evoluie i dac irul w
2
a
2
u
2
nu este la nceputul benzii de
intrare. Rezult c este posibil i evoluia (q
2
, ww
2
a
2
u
2
) |-* (q
3
, ww
3
a
3
u
3
).
Pe baza propoziiei anterioare putem s realizm compunerea mainilor Turing ntr-o manier similar
utilizrii subprogramelor. S considerm de exemplu o maina Turing M1 care "tie" s funcioneze
primind un ir pe banda de intrare pornind cu capul de citire / scriere poziionat dup ir. S presupunem
c M1 nu poate s ntre ntr-o stare de agare. La oprire, capul va fi plasat de asemenea dup irul care a
rezultat pe banda de intrare. Dac M1 este utilizat n cadrul unei alte maini Turing care printre alte aciuni
pregtete i un ir de intrare pentru M1, atunci dup ce M1 primete controlul nu va depi limita stnga
a irului su de intrare, deci nu va modifica un ir care eventual a fost memorat nainte pe banda de intrare.
n cele ce urmeaz considerm ca mainile Turing care se combin nu pot s ntre n starea de agare
i c fiecare are strile sale proprii diferite de strile tuturor celorlalte maini Turing. Ca maini de baza
pornind de la care vom construi noi maini Turing vom considera cteva cu funcionare elementar.
Aceste maini au un un alfabet de intrare T comun.

1. exist |T| maini care scriu fiecare cte un simbol din T n poziia curent a capului. O astfel de main
este definit ca fiind Wa = ({q}, T, m, q), a T, m(q, b) = (h, a), b T. Pentru a simplifica notaiile
Wa va fi reprezentat de simbolul a.

1. exist dou maini care execut deplasri elementare. i anume VL = ({q}, T, m, q) cu m(q, a) = (h,
L) i VR = ({q}, T, m, q) cu m(q, a) = (h, R), a T. Vom nota aceste maini cu L i respectiv R.

Reprezentarea compunerii mainilor Turing se face ntr-o manier asemntoare unei structuri de
automat finit pentru care o stare este reprezentat de o maina Turing. Intrarea ntr-o stare a automatului
corespunde cu iniierea funcionrii unei maini Turing. La oprirea unei maini Turing (intrarea acesteia n
starea h) n funcie de simbolul aflat sub capul de citire se va trece ntr-o alt stare, adic se va iniia
funcionarea unei alte maini Turing.
O schem de main Turing este tripletul = (M, , M0) unde
M este o mulime finit de maini Turing care au toate un alfabet comun T i mulimi de stri
distincte;
M0 M este maina iniial;
este o funcie parial , : M x T M.

Irina Athanasiu 3/1/2002 Limbaje formale i automate

64
O schem de main Turing reprezint o maina Turing compus din mainile care formeaz
mulimea M. Funcionarea acesteia ncepe cu funcionarea mainii M0. Dac M0 se oprete atunci poate
continua eventual funcionarea conform altei maini din M. Dac M0 se oprete cu capul de citire / scriere
pe caracterul a atunci exist urmtoarele situaii :

(M0, a) este nedefinit, n acest caz se oprete;
(M0, a) = M', n acest caz funcionarea continu cu starea iniial a mainii M'.

Acelai mod de nlnuire va avea loc i la oprirea (dac intervine) mainii M'. n mod formal acest
gen de compunere de maini Turing poate s fie descris n modul urmtor. Fie M = {M0, .., Mk}, k 0
astfel nct M
i
= (Q
i
, T, m
i,
s
i
), 0 i k. Fie q0, ..., qk stri care nu apar n mulimile Q
i
, 0 i k. Dac
(M, , M0) este o schem de main Turing , ea va reprezenta maina MT = (Q, T, m, s) unde

Q = Q
0
... Q
k
{q
0
, ..., q
k
}
s = s
0

m este definit n modul urmtor:
a. dac q Q
i
, 0 i k, a T i m
i
(q,a) = (p, b), p h atunci m(q, a) = m
i
(q, a) = (p, b);
b. dac q Q
i
, 0 i k, a T i m
i
(q, a) = (h, b) atunci m(q, a) = (qi, b);
c. dac (Mi, a) (0 i k, a T) este nedefinit atunci m(qi, a) = (h,a);
d. dac (Mi, a) = Mj (0 i k, a T) i mj(sj, a) = (p, b) atunci

(p,b) p h
/
m(qi, a) =
\
(qj, b) p = h

Se observ c strile noi q0, ..., qk au fost introduse ca puncte de trecere de la o main la alta. Din
definiie rezult c fiecare main funcioneaz "normal" pn cnd se oprete. Dac o main se oprete i
este definit maina urmtoare se va trece n starea care face legatura cu maina urmtoare. Dac nu este
definit maina urmtoare, MT se va opri. Dintr-o stare de legatur se intra n funcionarea mainii
urmtoare pe baza simbolului curent de pe banda de intrare.
S considerm de exemplu mulimea M = {M0} cu M0 = R = ({q}, T, m, q). Definim funcia n
modul urmtor :

(M0, a) = M0 dac a #
(M0, #) este nedefinit

n acest caz (M, , M0) reprezint o main notat cu R#, R# = ({q, q0}, T, m, q) unde
m(q, a) = (q0, R), a T
m(q0, a) = (q0, R), a #
m(q0, #) = (h, a)

Se observ c maina se deplaseaz la dreapta pn la primul simbol #. Dac T = {a, b. c} putem s
reprezentm maina R# sub forma:

Irina Athanasiu 3/1/2002 Limbaje formale i automate

65
a
----
\ / /|
\/ / |
> R < | b
/\ \ |
/ \ \|
----
c

n cele ce urmeaz vom reprezenta grafic compunerea mainilor Turing utiliznd o serie de reguli :

fiecare main Mi M apare o singur dat;
maina iniial (M0) este indicat prin semnul >;
dac a T i (Mi, a) este definit i de exemplu M' = (Mi,a) atunci va exist un arc de la Mi la
M' etichetat cu a.

Se poate ntmpla ca n M s apar mai multe copii ale aceleiai maini (fiecare cu strile ei proprii
diferite de strile celorlalte). n acest caz fiecare dintre exemplare reprezint o alt main Turing deci
va fi desenat separat.
n reprezentrile grafice urmtoare vom utiliza o serie de simplificri. De exemplu schema :
a
----------
/ b \
> R ----------> R peste alfabetul T = {a, b, c, #}
\ c / poate s fie reprezentata
| ---------- |
\ # /
------------

a,b,c,#
> R --------- R sau > R -- R sau RR sau R
2


indicnd faptul c se fac dou deplasri la dreapta indiferent de coninutul benzii de intrare.
Dac a T, a reprezint orice simbol din T diferit de a. Deci maina care caut simbolul # la
dreapta poate s fie reprezentat ca :

/| /|
/ | / |
> R < | a # sau > R < | #
\ | \ |
\| \|

Urmtoarea schem:


Irina Athanasiu 3/1/2002 Limbaje formale i automate

66
/|
/ |
> R < | #
| \ |
| \|
|
| a #
La

caut mergnd la dreapta un simbol diferit de #, cnd l gsete l copiaz la stnga poziiei pe care l-
a gsit. Se observ c din notaia a # rezult c simbolul gsit, i care este diferit de #, este notat
generic cu a i poate s fie utilizat n continuare.
n cele ce urmeaz utilizm urmtoarele notaii :

R
#
, este maina care caut primul simbol # la dreapta
L
#
, este maina care caut primul simbol # la stnga
R
#
, este maina care caut primul simbol diferit de # la dreapta
L
#
, este maina care caut primul simbol diferit de # la stnga

Utiliznd aceste maini "simple" s construim o maina de copiere C care funcioneaz n modul
urmtor. S presupunem c pe banda de intrare se gsete un ir w care nu conine simboli #
(eventual irul poate s fie i vid). Presupunem ca la stnga irului de intrare se gsete un singur
simbol #; pe banda de intrare nu se mai gsesc simboli diferii de # care s nu fac parte din w. Capul
este poziionat pe simbolul # care marcheaz sfritul irului w. Evoluia mainii trebuie s fie (s, #w#) |-
* (h, #w#w#). Se spune ca maina transform irul #w# n #w#w#. Reprezentarea grafic pentru aceasta
main este :

+-------------------------+
| x # |
>L
#
-->R --------#R
#
2
x L
#
2
x ---+
# |
R
#


S urmrim evoluia mainii pentru coninutul benzii #abc#

Irina Athanasiu 3/1/2002 Limbaje formale i automate

67
(q, #abc#) |-* (q, #abc#) |- (q, #abc#) |- (q, ##bc#)
L
#
R #
|- (q,##bc#) |- (q,##bc##)
R
#
R
#
|- (q, ##bc#a#) |- (q, ##bc#a#) |- (q, ##bc#a#)
x L
#
L
#
|- (q, #abc#a#) |- (q, #abc#a#) |- (q, #a#c#a#)
x R #
|- (q, #a#c#a#) |- (q, #a#c#a#)
R
#
R
#

|- (q, #a#c#ab#) |- (q, #a#c#ab#)
x L
#

|- (q, #a#c#ab#) |- (q, #abc#ab#)
L
#
x
|- (q, #abc#ab#) |- (q, #ab##ab#)
R #
|- (q, #ab##ab#) |- (q, #ab##abc#)
R
#
R
#
x
|- (q, #ab##abc#) |- (q,#abc#abc#)
L
#
L
#
x
|- (q, #abc#abc#) |- (q,#abc#abc#)
R R
#

|- (h,#abc#abc#)

n evoluia prezentat anterior starea nu conteaz aa c a fost notat cu un simbol generic q. Se
observ c dac C ncepe s funcioneze cu un coninut al benzii de forma #u#v#w# la sfritul
execuiei se obine pe banda #u#v#w#w#. C nu funcioneaz corect dac la pornire la dreapta
capului de citire se gsete un simbol diferit de #.
Maina SL :

+----------------+
| x # |
>L ->R ----> LxR ----+
# | #
L
#

transform irul #w# n w#. Similar se poate construi o maina SR care transform irul #w# n
##ww#.
Fie T0 = T - {#} cu f : T0* T0* astfel nct f(w) =ww
R
, f poate s fie calculat de urmtoarea
main:

+--------------------+
| x # |
>L ----> #R
#
xL
#
x ----+
| #
R
#



Pe parcursul funcionrii maina transform iruri de forma #x1 ... xn# n #x1 ... xi ... xnxnxn-1 ...
xi+1#, i = n-1, ..., 0. Pentru i = 0 se ajunge la #x1 ... xnxn ... x1#.
2.3.3.3 Extensii pentru maina Turing

Avnd n vedere simplitatea deosebit a funcionrii unei maini Turing standard, se pune
problema dac aceasta nu poate s fie fcut mai "puternic": prin adugarea unor extensii care s
Irina Athanasiu 3/1/2002 Limbaje formale i automate

68
o apropie eventual de un calculator real. Se poate demonstra c adugarea unor faciliti ca de
exemplu :

banda de intrare infinit la ambele capete;
mai multe capete de citire / scriere;
mai multe benzi de intrare;
o banda de intrare organizat n dou sau mai multe dimensiuni (eventual o memorie aa cum
apare la calculatoare);

nu crete puterea de calcul oferit. Adic, nu se schimb nici clasa funciilor care pot s fie calculate
i nici a limbajelor acceptate sau decise.
Demonstraiile de echivalen sunt constructive realizndu-se pentru fiecare extensie construirea
unei maini Turing standard capabil s simuleze funcionarea unei maini Turing avnd extensia
considerat. S considerm de exemplu o maina Turing care are o band infinit la ambele capete.
Schimbarea definiiei formale pentru acest model de maina Turing intervine n modul n care se definete
noiunea de configuraie i relaia |- asupra configuraiilor. n acest caz o configuraie este de forma (q, w,
a, u) i w nu ncepe cu un simbol # iar u nu se termina cu un
simbol #. Nu mai exist limitri referitoare la deplasarea la stnga i deci dispar noiunile de
stare i respectiv de configuraie de agare.

Propoziie. Fie M1 = (Q1, T1, m1, q1) o main Turing cu banda de intrare infinit la ambele
capete. Exist o main Turing standard M2 = (Q2, T2, m2, q2) astfel nct, pentru orice w (T1 -
{#})* sunt ndeplinite urmtoarele condiii :

dac M1 se oprete pentru w, adic:

(q1, w#) |-* (h, uav), u, v T1*, a T1

atunci i M2 se oprete pentru w, adic:

(q2, #w#) |-* (h, #uav), u, v T1*, a T1

dac M1 nu se oprete pentru w atunci nici M2 nu se oprete pentru w.

Demonstraie. Banda de intrare pentru M2 se obine prin ndoirea benzii de intrare a mainii M1.
Adic, dac considerm c banda de intrare M1 are un "mijloc" ales arbitrar :

----------------------------------------
| -3 | -2 | -1 | 0 | 1 | 2 | 3 |
----------------------------------------

atunci banda de intrare pentru M2 va avea forma:

+---------------------------
| | 0 | 1 | 2 | 3 |
| $ |----+----+----+----|
| | -1 | -2 | -3 | -4 |
+---------------------------

Irina Athanasiu 3/1/2002 Limbaje formale i automate

69
n simulare se va consider deci c funcionarea maini M1 n partea dreapta a benzii de intrare
corespunde funcionrii maini M2 pe pista superioar a benzii sale de intrare, respectiv funcionarea
maini M1 n partea stng corespunde funcionrii maini M2 pe pista inferioar a benzii sale de intrare.
Rezult deci c pentru M2 se va utiliza un alfabet care conine perechi de simboli din alfabetul
T1. O astfel de pereche (a, b) va indica faptul c a este coninut de pista superioar iar b este coninut de
pista inferioar. Vom nota cu T o mulime definit n modul urmtor :

T = {a | a T1}

n acest caz T2 = {$} T1 (T1 x T1) (T1 x T) (T x T1). M2 simuleaza M1 n modul
urmtor :

1. se mparte banda de intrare n dou piste i se copiaz irul de intrare pe pista superioar;
2. se simuleaz funcionarea M1 pe banda obinut;
3. cnd i dac M1 se oprete, se reface forma iniial a benzii.

Pentru a realiza prima etapa trebuie s se realizeze o prelucrare de iruri. Adic, dintr-o banda de
intrare de forma :

----------------------------------------
| # | a1 | a2 | ...| an | # | # |
----------------------------------------



trebuie s se ajung la un coninut al benzii de forma :

+------------------------------------
| | a1 | a2 | ...| an | # | |
| $ |----+----+----+----+----| # |
| | # | # | ...| # | # | |
+------------------------------------


unde a1, ..., an (T1 - {#})*. Se observ c prelucrrile necesare nu sunt deosebit de dificile.
Etapa a doua poate s fie realizat de ctre o maina M1' care are n mulimea sa de stri pentru
fiecare q Q1 o pereche de stri notate <q, 1> i <q, 2>. Dac M1' este ntr-o stare <q, 1> nseamn c
M1' acioneaz asupra pistei superioare a benzii de intrare. Dac M1' este n starea <q, 2> atunci nseamn
c M1' acioneaz asupra pistei inferioare. De asemenea exist strile <h, 1> i <h, 2> care reprezint
oprirea n situaia n care M1' lucra pe pista superioar respectiv inferioar.
Funcia de tranziie m' pentru M1' este definit n modul urmtor :

a) dac q Q1, (a1, a2) T1 x T1 i m1(q, a1) = (p,b)
atunci

/ (<p, 1>, L) dac b = L
m1'(<q,1>,(a1,a2) = (<p, 1>, R) dac b = R
\ (<p, 1>, (b, a2)) dac b T1

b) dac q Q1, (a1, a2) T1 x T1 i m1(q, a2) = (p, b)
atunci

Irina Athanasiu 3/1/2002 Limbaje formale i automate

70
/ (<p, 2>, R) dac b = L
m1'(<q,2>,(a1,a2) = (<p, 2>, L) dac b = R
\ (<p, 2>, (a1, b)) dac b T1

c) dac q Q1 {h} atunci

m1'(<q, 1>, $) = (<q, 2>, R)
m1'(<q, 2>, $) = (<q, 1>, R)

d) dac q Q1 {h} atunci

m1'(<q, 1>, #) = (<q, 1>, (#, #))
m1'(<q, 2>, #) = (<q, 2>, (#, #))

e) dac a1, a2 T1 atunci

m1'(<h, 1>, (a1, a2)) = (h, (a', a2))
m1'(<h, 2>, (a1, a2)) = (h, (a1, a'))

f) pentru situaiile care nu se ncadreaz n nici unul dintre cazurile anterioare m1' se
definete arbitrar.

Se observ c n cazurile a i b este descris funcionarea mainii M1 la dreapta i respectiv la stnga
"mijlocului" ales. Cazul c. trateaz comutarea ntre piste care trebuie realizat atunci cnd se ajunge la
limita din stnga a benzii. Cazul d. indic modul n care se face extinderea celor doua piste la dreapta.
Cazul e trateaz intrarea n starea de oprire (h) a maini simulate M1. Se observ c la intrarea n aceasta
stare se va produce intrarea n starea h i a mainii M1' cu nregistrarea pistei pe care s-a fcut oprirea
mainii simulate.
Dac banda de intrare a maini M1 conine irul w (T1 - {#})* i aceasta se oprete cu un coninut
de forma :

-----------------------------------------------
| # | b1 | b2 | ...| bi | ...| bn | # | # |
-----------------------------------------------


atunci M1' se va opri cu un coninut de forma :

+-------------------------------------
| | ck+1 | ck+2 | ... | c2k | |
| $ |------+------+-----+-----| # |
| | ck | ck-1 | ... | c1 | |
+-------------------------------------

unde c1c2 ... c2k = # ... # b1b2 ... bi-1 b bi+1 ... bn # ... # cu bi #, 1 i n.
Pentru etapa a treia se face translatarea simbolilor diferii de # de pe pista inferioar pe pista
superioar :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

71
+-------------------------------------------
| | b1 | b2 | ... | bi | ... | bn | |
| $ |----+----+-----+----+-----+----| # |
| | # | # | ... | # | ... | # | |
+-------------------------------------------


Din nou aceasta prelucrare este simpl. n final se reface banda sub forma :

+-------------------------------------------
| # | b1 | b2 | ... | bi | ... | bn | # |
+-------------------------------------------



Rolul alfabetului T utilizat n construirea mainii M1' este de a permite identificarea poziiei capului
la oprirea mainii M1'.
Similar definiiei din cazul mainilor Turing standard putem s considerm i n acest caz definiia
noiunii de calcul. i anume dac T1 i T2 sunt doua mulimi de tip alfabet care nu conin simbolul #
atunci spunem c funcia f : T1* T2* este calculat de maina Turing, M care are banda de intrare
infinit la ambele capete, dac i numai dac pentru orice w T1*, dac f(w) = u atunci (q, w#) |-*
(h,u#). De asemenea noiunile de acceptare respectiv de decidabilitate referitoare la limbaje pot s fie
definite pentru mainile Turing cu banda infinit la ambele capete ntr-o maniera similara celei de la
maina Turing standard.
Orice funcie care este calculat i orice limbaj care este acceptat sau decis de o maina Turing cu
banda infinit la ambele capete este calculat respectiv acceptat sau decis de o main Turing standard.
Construcii i rezultate similare pot fi realizate i pentru celelalte extensii considerate la nceputul
acestui subcapitol. Din acest motiv n tratarea pe care o vom realiza n continuare putem s considerm
pentru a simplifica demonstraiile n loc de maini Turing standard maini care au oricare dintre
extensiile amintite sau chiar combinaii ale acestora.
Extinderea maini Turing se poate face i prin renunarea la caracterul determinist al acestora.
Pentru o main Turing nedeterminist funcia m este definit n modul urmtor :

m : Q x T P((Q {h}) x (T {L, R}))

Dup cum s-a artat pentru orice automat finit nedeterminist se poate construi un automat finit
determinist echivalent. n cazul automatelor cu stiv aceasta echivalen nu exist. Cu alte cuvinte
automatele cu stiv nedeterministe sunt "mai puternice" dect cele deterministe deoarece automatele
cu stiv nedeterministe accepta o clasa mai larga de limbaje.
n cazul mainilor Turing nedeterministe deoarece pentru acelai ir de intrare se pot obine
rezultate diferite, se pune problema cum se alege "calculul util" efectuat de maina Turing. Vom
restringe puin problema considernd numai noiunea de acceptare. n acest caz ceea ce conteaz este
c maina Turing se oprete n una din evoluiile sale posibile. Rezultatul depus pe band nu este n acest
caz neaprat semnificativ. S considerm mai nti un exemplu de main Turing nedeterminist. Fie
limbajul

L = { w { a, b}* | w contine sirul abaab}

Evident, limbajul este de tip regulat i poate s fie acceptat de un automat finit determinist. O
soluie de maina Turing nedeterminista care accepta acest limbaj este :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

72
a, b
--
\/ b a a b a /|
>L -----> L ----> L ----> L ----> L ----> a R | #
| | | | | | \|
# | b,# | b,# | a,# | b,# | # |
-------->------>-------<--------<--------
|
| /|
# |
\|

Configuraia din care se pleac este (q, #w#). Maina Turing pornete spre stnga. La un moment
dat, la ntlnirea unui simbol b, maina Turing "ghicete" ca a gsit sfritul sub irului cutat.
Dac ghicirea este corect atunci maina se va opri, altfel maina nu se oprete. Fiind vorba de o
funcionare nedeterminist tot ce conteaz este c dintre toate soluiile posibile exist una pentru care
maina se oprete. Se poate demonstra urmtoarea propoziie.
Propoziie Pentru orice maina Turing, M1 nedeterminist exist o maina Turing M2 determinist
(standard) astfel nct pentru orice ir w care nu conine simbolul # :

i) dac M1 se oprete pentru w atunci i M2 se va opri pentru w;
i) dac M1 nu se oprete pentru w atunci nici M2 nu se oprete pentru w.

S considerm o schi de demonstraie pentru propoziia anterioar. Fie M1 = (S, T1, m, s). M2
trebuie s ncerce toate evoluiile posibile pentru M1 n cutarea unei evoluii pentru care M1 se oprete.
M1 poate avea ns un numr infinit de evoluii pornind din s i avnd un ir w pe banda de intrare ( s nu
uitm c dac irul nu este acceptat de M1 aceasta nu se va opri). Se pune problema cum trebuie s fac
M2 cutarea ntre aceste evoluii (n ce ordine ?).
Ideea este urmtoarea, dac M1 este n configuraia C atunci exist mai multe configuraii C' astfel
nct C |- C'. Numrul configuraiilor C' este ns finit i depinde numai de definiia funciei m (nu de
configuraia C). Dac starea curenta este q i simbolul curent la intrare este a, atunci m(q, a) P((Q
{h}) x (T {L, R})) este o mulime finit, deoarece |m(q,a)| (|Q| + 1) x (|T| + 2). Fie

r = max (|m(q,a)|)
q Q
a T

Valoarea r rezult din definiia funciei m i reprezint numrul maxim de configuraii urmtoare
posibile pentru o configuraie dat. Deci dac pornim din configuraia iniial C = (q,#w#), M1 poate s
treac n maximum r configuraii urmtoare diferite. Fiecare dintre aceste r configuraii diferite poate s
treac la rndul ei n alte r configuraii diferite. Rezult deci c pentru o evoluie n k pai se poate ajunge
la un numr de maximum r
k
configuraii diferite pornind din configuraia iniial. Pentru fiecare mulime
m(q, a), q Q, a T, considerm cte o ordonare arbitrar a elementelor care o compun.
M2 va analiza n mod sistematic nti toate configuraiile n care se poate ajunge ntr-un pas, apoi n
doi pai, etc. Dac n aceasta cutare se trece printr-o configuraie pentru care M1 se oprete se va opri i
M2. Dac M1 se oprete vreodat atunci ea se oprete ntr-un numr finit de pai. Corespunztor M2 va
descoperi aceasta oprire ntr-un numr finit de pai.
Maina M2 poate s fie construit avnd trei piste. O pist este utilizat ca martor, pe ea se pstreaz
irul iniial. A doua pist este utilizat pentru a simula funcionarea maini M1. Fiecare simulare ncepe cu
o copiere a coninutului primei benzi (partea util) pe a doua band. A treia band pstreaz evidena
ncercrilor fcute. i anume pe aceast band se gsete un ir dintr-un alfabet D = {d1, ..., dr}, unde r
este numrul maxim de configuraii urmtoare posibile pentru orice configuraie a maini M1. Pe aceasta
Irina Athanasiu 3/1/2002 Limbaje formale i automate

73
band se vor genera iruri care codific modul n care se aleg alternativele posibile n fiecare pas al
simulrii. Astfel, un ir de forma d3 d5 d1 indic faptul c se va ncerca un calcul n trei pai. n primul
pas se alege dac exist a treia alternativ din cele maximum r posibile, n al doilea pas se alege a cincea
alternativ iar n al treilea pas se alege prima alternativ posibil. Dac n aceasta alegere nu exist o
alternativ cu numrul celei indicate se abandoneaz calculul.
Generarea irurilor pe a treia band se face n ordine lexicografic. Dupa fiecare ncercare care nu a
dus la oprire se va terge coninutul celei de a doua benzi i se genereaz un nou ir pe a treia band.
Dac ncercarea duce la oprirea maini simulate se oprete i M2.
Se observ c toate prelucrrile descrise anterior sunt prelucrri simple asupra unor iruri de simboli
ce pot s fie realizate de ctre maini Turing standard.
Pe baza propoziiei enunate anterior rezult ca orice limbaj acceptat de o main Turing
nedeterminist va fi acceptat i de o maina Turing determinist.
2.3.3.4 Automate liniar mrginite
Un automat liniar mrginit este un caz particular de main Turing nedeterminist. Definiia unui astfel de
automat este:

ALM = (Q, T, m, s, F)

unde:
Q este o mulime finit de stri
T este alfabetul benzii de intrare, #, L, R T
m este funcia de tranziie
m : Q x T P(Q x (T {L, R})).
s Q este starea iniial pentru automatul liniar mrginit.
F Q este mulimea strilor finale

Dac q Q este o stare, a T este un simbol de pe banda de intrare i (p, b) m(q, a) nseamn c
din starea curent q pentru simbolul de intrare a se poate trece n starea p, nlocund sibmbolul de pe banda
de intrare sau efectund o micare la stnga sau la dreapta. Definiia este a unui acceptor nedeterminist.
Funcionarea automatului pornete cu o configuraie avnd pe banda de intrare un ir cuprins ntre doi
simboli # (dou blancuri). Deoarece funcia de tranziie nu este definit pentru simbolul #, nseamn c
spaiul de micare al capului de citire/scriere pe banda d intrare este limitat la lungimea iniial a irului de
intrare. Cu alte cuvinte dac printr-o deplasare la stnga sau la dreapta capul de citire/scriere ajunge n
afara spaiului ocupat iniial de ctre irul analizat automatul se oprete. Conform definiiei, pentru
automatele liniat mrginite se consider o acceptare prin stri finale. Dac la oprirea automatului capul de
citire se gsete la captul din dreapta al irului i starea automatului face parte din F nseamn c evoluia
automatului a dus la acceptare.
Se poate demonstra c pentru orice gramatic dependent de context exist o gramatic echivalent
liniar mrginit. Produciile unei gramatici n liniar mrginit au n partea dreapt cel mult doi simboli.
Dac exist o producie S AB (unde S este simbolul de start al gramaticii) atunci A = S. Pentru orice
gramatic dependent de context liniar mrginit se poate construi un automat liniar mrginit care accept
acelai limbaj. De asemenea pentru orice automat liniar mrginit este posibil s se construiasc o
gramatic dependent de context care genereaz acelai limbaj. Adic, clasa limbajelor acceptate de
automate liniar mrginite este clasa limbajelor dependente de context. Intuitiv, relaia de echivalen dintre
gramaticile dependente de context i automatele liniar mrginite este susinut de condiia pe care o
satisfac produciile unei gramatici dependente de context. i anume - dac A este o producie
atunci |A| ||. Adic orice ir din limbajul generat de ctre gramatic este mai lung cel puin egal
cu orice form propoziional obinut n secvena de derivri prn care se obine irul respectiv.
Irina Athanasiu 3/1/2002 Limbaje formale i automate

74
Se poate construi i o definiie de automat liniar mrginit determinist. Automatele liniar mrginite
nedeterministe sunt mai puternice dect cele deterministe, n sensul c existe limbaje acceptate de ctre
automate liniar mrginite nedeterministe dar care nu sunt acceptate de automate liniar mrginite
deterministe. n particular limbajele independente de context sunt acceptate i de automatele liniar
mrginite deterministe (acceptoarele obinuite pentru limbajele independente de context sunt automatele
cu stiv).
2.3.3.5 Relaia ntre maina Turing i gramatici

Propoziie. Fie M = (Q, TM, m, q) o main Turing. Exist o gramatic G = (N, TG, P, S) astfel
nct pentru orice pereche de configuraii (q, uav) i (q', u'a'v') ale maini Turing
*
(q, uav) |- (q', u'a'v')
M

dac i numai dac

*
[uqav] [u'q'a'v']
G

Demonstraie. Se observ c formele propoziionale ce se obin n gramatica G conin iruri care
corespund configurailor maini Turing. Astfel, pentru o configuraie de forma (q,u,a,w) se obine o
form propoziional [uqaw]. Poziia pe care o ocupa simbolul corespunztor strii indic de fapt poziia
capului de citire pe banda de intrare.
Mulimea simbolilor terminali pentru G este TG = TM {[, ]}. Mulimea simbolilor
neterminali N = Q {h, S}. Mulimea produciilor se construiete n modul urmtor :

i) q Q, a TM dac m(q,a) = (p, b) b T atunci qa pb P

i) q Q, a TM dac m(q,a) = (p, R) atunci
qab apb P pentru b TM i qa] ap# P

iii) q Q, a TM dac m(q,a) = (p, L) atunci dac a # sau c ] atunci
bqac pbac P, b TM, c TM {]}
dac a = # atunci
bq#] pb] P, b TM.

Se observ c n construcia anterioara simbolul de start al gramatici nu joac nici un rol.
n toate produciile se observ ca apare cte un singur neterminal att n partea dreapta ct i n
partea stnga. Acest neterminal corespunde unei stri. Poziia sa n cadrul fiecrui ir reprezint de fapt
poziia capului de citire. Simbolul de start al gramaticii nu este utilizat. Se poate demonstra utiliznd
aceast construcie c :

(q, u, a, v) |- (q', u', a', v')

dac i numai dac

[uqav] [u'q'a'v']

Irina Athanasiu 3/1/2002 Limbaje formale i automate

75
Demonstraia se realizeaz considernd toate formele posibile de producii. Mai departe rezultatul se
extinde natural pentru nchiderile acestor relaii.
S considerm de exemplu maina Turing

M = ({q0, q1, q2}, {a, #}, m, q0)

pentru care m este definit n modul urmtor :

m(q0, a) = (q1, R)
m(q0, #) = (q0, a)
m(q1, a) = (q2, R)
m(q1, #) = (q1, a)
m(q2, #) = (h, #)
m(q2, a) = (q2, R)

s considerm pentru aceast main evoluia pentru configuraia (q0, #a#)

(q0, #a#) |- (q0, aa#)
|- (q1, aa#)
|-
+
(h, aa#).

S construim gramatica corespunztoare :

G = ({q0, q1, q2, h, S}, {q, #, [, ]}, P, S)

P va conine urmtoarele producii :

i) n cazul n care se face scriere pe banda

q0# q0 a ( corespunde m(q0, #) = (q0, a) )
q1# q1 a ( corespunde m(q1, #) = (q1, a) )
q2# h # ( corespunde m(q2, #) = (h, #) )

i) n cazul n care se fac deplasri dreapta

q0aa a q1 a ( corespunde m(q0, a) = (q1, R))
q0a# a q1 #
q0a] a q1 #]

q1aa a q2 a (corespunde m(q1, a) = (q2, R))
q1a# a q2 #
q1a] a q2 # ]

q2aa a q2 a (corespunde m(q2, a) = (q2, R))
q2a# a q2 #
q2a] a q2 #]

Un calcul realizat de M poate s fie :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

76
(q0, #) |- (q0, a#) |- (q1, a#) |- (q1, aa# |- (q2, aa#)
|- (h, aa#)

O derivare n G care pornete din irul [q0#] este :

[q0#] [q0a] [aq1#] [aq1a] [aaq2#]
[aah#]

Se observ c n aceasta derivare simbolul de start al gramatici nu a intervenit. Gramatica este n
acest caz utilizat ca mecanism de specificare a unor substituii de iruri i nu ca generator de limbaj.
Aa cum o main Turing a fost tratat ca acceptor de limbaj o gramatica poate s fie privit ca
un dispozitiv capabil s reprezinte (efectueze) calcule.
Fie T1 i T2 dou mulimi de tip alfabet care nu conin simbolul # i fie f : T1* T2*,
spunem c f este calculabil gramatical dac i numai dac exist o gramatica G = (N, T, P, S) astfel
nct T1, T2 T i exist irurile x, y, x', y' (N T)* care ndeplinesc urmtoarea condiie pentru u
T1* i v T2* v = f(u) dac i numai dac xuy * x'vy'. n acest caz se spune c G calculeaz
funcia f. De la iruri definiia se poate extinde la numere naturale ntr-o manier similar celei
utilizate la maina Turing.
S considerm de exemplu T1 = {a, b} i f : T1* T1*, f(w) = w
R
. Funcia f este calculabil de
ctre gramatica G = (N, T, P, S} unde N = {A, B, S}, T = {a, b, *, [, ]} iar P conine urmtoarele
producii :

1. [a [A,[b [B
2. Aa aA, Ab bA, Ba aB, Bb bB
3. A* *a, B* *b

irurile x, y, x' i y' sunt [, *], [* i respectiv ]. G transform un ir de forma [w*] cu w {a, b}*
n modul urmtor. Se transform nti primul simbol (a sau b) cu care ncepe irul n A sau B utiliznd
una dintre produciile [a [A sau [b [B. n continuare neterminalul astfel obinut migreaz spre
limita din dreapta a irului. La ntlnirea simbolului * se aplic una dintre produciile A* *a sau B*
*b. De exemplu pentru irul abb se obine :

[abb*] [Abb*] [bAb*] [BAb*] [BbA*]
[Bb*a] [bB*a] [b*ba] [B*ba]
[*bba]

Se observ c nu este semnificativ ordinea n care se aplic produciile.

Propoziie Orice funcie calculabil n sens Turing este calculabil i gramatical.
Demonstraia acestei propoziii este constructiv, adic pornind de la o maina Turing se
construiete o gramatic care realizeaz acelai calcul.
Din rezultatele prezentate putem trage concluzia echivalenei ntre gramaticile de tip 0
(fr restricii) i mainile Turing din punctul de vedere al limbajelor acceptate (generate) i al puterii
de calcul.
Considernd echivalena dintre gramatici i mainile Turing se pune ntrebarea cum se poate
construi o main Turing care s accepte limbajul generat de o gramatica G = (N, T, P, S). Avnd n
vedere ca operaia de derivare presupune de fapt prelucrri simple de iruri de simboli, se poate construi
o main Turing care s execute operaia de derivare. O astfel de main se poate obine de exemplu
utiliznd cte o main Turing pentru fiecare producie. Avnd n vedere modul n care se obine un ir
Irina Athanasiu 3/1/2002 Limbaje formale i automate

77
care face parte din L(G) se poate construi o main Turing eventual nedeterminist care s realizeze
aceleai operaii.

2.3.3.6 Elemente de calculabilitate

Discuia coninut n acest subcapitol depete cadrul limbajelor formale dar este important
pentru a realiza legtura dintre modelele de calcul considerate i lumea real a calculatoarelor, mai
ales pentru a oferi o caracterizare a posibilitilor oferite de acestea.
n momentul n care s-a dat definiia limbajelor s-a precizat faptul c numai o anumit parte a
acestora poate s fie descris ntr-o form finit. Gramaticile, automatele finite, automatele push down,
maina Turing sunt astfel de reprezentri finite. Se pune problema dac odat cu maina Turing s-a atins
ntr-adevr limita de reprezentare finit a limbajelor. De asemenea, avnd n vedere c o
gramatica poate s fie interpretat i ca un dispozitiv capabil s efectueze calcule, se pune ntrebarea
dac nu exist mecanisme mai puternice de reprezentare dect gramaticile i maina Turing (avnd n
vedere faptul c un calculator real pare mult mai puternic dect o maina Turing).
2.3.3.6.1 Maina Turing Universal

Spre deosebire de o maina Turing standard, modelul Von Neumann de calculator presupune
noiunea de program memorat. Ar apare aici o diferen important ntre o main Turing i un
calculator real. i anume o main Turing standard este dedicat rezolvrii unei anumite probleme
(calculului unei anumite funcii) n timp ce un calculator este un dispozitiv universal, capabil s treac
la calculul unei noi funcii prin schimbarea programului, deci a ceva coninut n memorie, fr a schimba
ns modul de funcionare a unitii de control. Se pune ntrebarea dac nu se poate construi o maina
Turing care s funcioneze ntr-o manier similar adic, s primeasc la intrare att irul care se
transform ct i o descriere a transformrii. O astfel de main Turing se numete maina Turing
universal. Pentru a construi o main Turing universal este necesar s obinem nti un mod de
descriere al unei maini Turing sub forma de ir astfel nct aceast descriere s poat s fie utilizat
ca intrare pentru o alta main Turing .
Fiecare main Turing este definit utiliznd patru elemente MT = (Q, T, m,s). Deoarece Q i T
sunt mulimi finite descrierea unei maini Turing poate s fie fcut sub forma unui ir utiliznd
simboli din Q, T, paranteze, virgule i alte semne de punctuaie. O asemenea reprezentare sub forma de
ir, nu este recomandabil deoarece avem nevoie pentru maina pe care o construim de un alfabet
finit pe care s l utilizm n definiia acesteia, alfabet care s permit reprezentarea oricrui alfabet
posibil pentru o main Turing. Vom consider ca exist mulimile infinit numrabile :

Q
inf
= {q1, q2, ...} i T
inf
= {a1, a2, ...}.

astfel nct pentru orice main Turing, mulimea strilor i respectiv alfabetul de intrare sunt
submulimi finite din Q
inf
i respectiv T
inf
. Se consider urmtoarea codificare pentru elementele care
aparin unei definiii de main Turing utiliznd un alfabet ce conine un singur simbol {I}:


Irina Athanasiu 3/1/2002 Limbaje formale i automate

78
element | cod(element)
---------+--------------
q
i
| I
i+1

---------+--------------
h | I
---------+--------------
L | I
---------+--------------
R | II
---------+--------------
a
i
| I
i+2
------------------------

Se observ c fiecare stare q Q {h} are un cod unic, acelai lucru este valabil i pentru fiecare
simbol din alfabetul de intrare. Fie c un simbol c I. Pentru construirea irului care descrie o main
Turing se utilizeaz numai simbolii c i I. Fie MT = (Q, T, m, s) o main Turing cu Q S
inf
i T T
inf.

Deci Q = {q
i1
, q
i2
, ..., q
ik
}, i1 < i2 < ... < ik, iar T = {a
j1
, a
j2
, ... a
jl
}. Construim kl iruri notate cu S
pr
, unde
1 p k i 1 r l. Fiecare ir S
pr
codific valoarea funciei de tranziie pentru o pereche (q
ip
, a
jr
).
Fie de exemplu m(q
ip
, a
jr
) = (q', b), q' Q {h} i b T {L, R} atunci S
pr
= cw1cw2cw3cw4c
unde :

w1 = cod(q
ip
)
w2 = cod(a
jr
)
w3 = cod(q')
w4 = cod(b).

Notm cu codif(M) irul cS
0
cS
11
S
12
... S
1l
S
21
... S
2l
... S
k1
S
k2
... S
kl
c. S0 este codificarea strii iniiale,
S
0
= cod(s). Se observ c irul astfel obinut reprezint o codificare unic pentru o maina Turing. De
asemenea pe baza unui astfel de ir se poate reconstrui descrierea "clasica" a mainii.
S considerm de exemplu MT = (Q, T, m,s) cu Q = {q2}, T = {a1, a3, a6}, s = q2 i m(q2, a3) =
m(q2, a6) = (q2, R) i m(q2, a1) = (h,a3). Utiliznd notaiile anterioare, rezult k = 1, i1 =
2, l = 3 i j1 = 1, j2 = 3, j3 = 6. Se obine :


S11 | m(q2, a1) = (h, a3) | cIIIcIIIcIcIIIIIc
-----+---------------------+-----------------------
S12 | m(q2, a3) = (q2,R) | cIIIcIIIIIcIIIcIIc
-----+---------------------+-----------------------
S13 | m(q2, a6) = (q2, R) | cIIIcIIIIIIIIcIIIcIIc

Rezult

codif(M) = cI
3
c|cI
3
cI
3
cIcI
5
c|cI
3
cI
5
cI
3
cI
2
c|cI
3
cI
8
cI
3
cI
2
c|c

O main Turing universal U primete pe banda de intrare un ir de tip codif(M) i un ir w pe care
trebuie s funcioneze M. irul w trebuie s fie i el codificat utiliznd alfabetul {c, I}. Codificarea se
face n modul urmtor. Dac w = b1 ... bn, cu bi T
inf
atunci:

codif(w) = c cod(b1) c cod(b2) c ... c cod(bn) c.

Se observ c irul obinut codif(w) nu poate s conin simboli #, chiar dac w conine simboli #. U =
(Qu, {I, c, #}, mu, qu) trebuie s satisfac urmtoarele condiii - pentru orice main Turing , M = (Q, T,
m, s) :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

79

1. dac (h, uaw) este o configuraie de oprire pentru M astfel nct (s, #w#) |-
*M
(h, uav) atunci, (qu,
#codif(M) codif(w) #) |-
*U
(h, #codif(uav)#)
2. dac (qu, #codif(M)codif(w)#) |-
*U
(h,u'a'v') pentru o configuraie de oprire (h, u'a'v') pentru U atunci
a' = #, v' = , u' = #codif(uav) pentru u, a, v astfel nct (h, uav) este o configuraie de oprire pentru M
i (s, #w#) |-
*M
(h, uav).

Adic dac M se oprete pentru w atunci i U se oprete pentru un ir obinut prin concatenarea
irurilor codif(M) i codif(w). Mai mult, pentru o astfel de oprire coninutul benzii U reprezint o
codificare a rspunsului maini Turing, M pentru w. De asemenea dac U se oprete pentru un ir care
reprezint codif(M)codif(w) atunci i M se va opri pentru w i rezultatul lsat de U reprezint codificarea
rezultatului lsat de M.
Pentru a simplifica discuia vom consider o variant U' a maini U, variant care utilizeaz trei benzi.
Conform celor menionate anterior pentru aceasta variant se poate construi o main Turing echivalent
cu o singur band. Prima band va conine iniial codif(M)codif(w), a doua band conine n timpul
simulrii codif(M) iar a treia band va conine codificarea strii curente a maini M care se simuleaz.
Funcionarea ncepe cu prima band coninnd codif(M)codif(w), celelalte benzi find goale. U' va copia
irul codif(M) pe a doua band i va modifica coninutul primei benzi la forma #c codif(#w#). Se observ
c localizarea nceputului irului codif(w) n irul iniial se face uor pentru c aici exist trei simboli c
consecutivi. Din codif(M) se identific S
0
(codul pentru starea iniial) i se copiaz pe cea de a treia
band. n continuare U' ncepe s simuleze funcionarea maini Turing M. ntre paii de simulare cele trei
capete de citire / scriere utilizate (exist trei benzi de intrare) sunt poziionate n modul urmtor :

pentru prima band pe ultimul c care indic sfritul codului pentru simbolul curent parcurs de M;
pentru a doua i a treia band la marginea stnga a benzilor respective.

n acest mod cnd M pornete s trateze ultimul simbol # din irul de intrare #w#, U' va ncepe
simularea deplasndu-i capul pe ultimul simbol c de pe banda. U' va cuta pe a doua band un subir de
forma ccI
i
cI
j
cI
k
cI
l
cc unde I
i
este irul coninut n a treia banda, iar I
j
este irul curent de pe prima banda. La
identificarea unui astfel de subsir U' se va mica corespunztor. Dac I
l
este codif(L) sau codif(R) atunci se
realizeaz deplasarea pe prima banda de intrare la stnga respectiv la dreapta. Dac I
l
este cod(a) pentru a
T
inf
se observ c nlocuirea simbolului curent poate s presupun deplasarea coninutului primei benzi
pentru ca spaiul ocupat de codul pentru a poate s fie diferit de cel ocupat de simbolul nlocuit. n cadrul
aceleiai micri U' nlocuiete irul nscris n a treia band cu I
k
. Dac acum coninutul acestei benzi este
cod(h) U' va deplasa capul de pe prima banda pe primul simbol # aflat la dreapta poziiei curente dup
care se oprete. Dac pe banda a treia nu se gsete cod(h) atunci se continu simularea.
Rezult deci c o main Turing este suficient de puternic pentru a fi comparata cu un calculator
real. De fapt o main Turing este echivalent cu noiunea intuitiv de algoritm. Mai
mult conform ipotezei Church (Church's Thesis) nici o procedur de calcul nu este un algoritm dac
nu poate s fie executat de o maina Turing. Acest rezultat care este acceptat, n prezent constituie numai
o ipotez pentru c nu constituie un rezultat matematic, ci indic numai faptul c un anumit obiect
matematic (maina Turing) este echivalent cu un concept informal.
Revenind la problema reprezentri finite a limbajelor se pune problema cum arat limbajele care nu
sunt Turing decidabile. Cu alte cuvinte putem s dm o reprezentare finit pentru un astfel de limbaj ?.
Dac aa ceva este posibil nseamn c putem s construim un algoritm care s decid dac un ir face
parte din limbajul respectiv. Conform ipotezei Church ns noiunea de algoritm i cel de maina Turing
sunt echivalente, Rezult deci c ar exist o maina Turing care s verifice dac irul face parte din limbaj,
adic limbajul ar fii Turing decidabil ceea ce contrazice ipoteza.
S discutm puin i relaia dintre limbajele Turing acceptabile i limbajele Turing decidabile. Se
poate demonstra urmtorul rezultat:
Irina Athanasiu 3/1/2002 Limbaje formale i automate

80
Propoziie. Orice limbaj L Turing decidabil este i Turing acceptabil.
Demonstraie. Fie M o main Turing care decide L. Atunci se poate construi M' care s accepte L.

N /|
> M L ----- N |
\|

Se observ c M' simuleaz M dup care studiaz rspunsul obinut pe band. Dac rspunsul este N,
M' va intra ntr-un ciclu infinit.
Se pune ntrebarea care este raportul invers ntre limbajele acceptabile i cele decidabile Turing.
Dac ar fi posibil ca pentru orice maina Turing i orice ir de intrare w, s prevedem dac maina
Turing se va opri pentru w, atunci orice limbaj Turing acceptabil ar fi i Turing decidabil, deoarece dac
M1 este maina Turing care accept L putem s construim M2 care decide L n modul urmtor. M2 va
executa calculele necesare pentru o prevedea dac M1 se oprete pentru w. Corespunztor M2 se va opri
cu un simbol D sau N pe banda de intrare dup cum M1 accept sau nu irul w.
Rezult c cele doua probleme:

este orice limbaj Turing acceptabil i Turing decidabil ?
se poate construi o main Turing care s prevad pentru orice main Turing, M, dac aceasta se
oprete sau nu pentru un ir, w ?

sunt echivalente.
Am artat c dac se poate construi o main Turing care s prevad pentru orice main Turing dac
aceasta se oprete sau nu pentru orice ir atunci orice limbaj acceptabil este i decidabil. S presupunem
acum c orice limbaj acceptabil este i decidabil. n acest caz limbajul:

L
0
= { codif(M)codif(w) | M accepta w}

care este acceptat de maina Turing universal, este un limbaj decidabil. Fie M
+
maina Turing care
decide acest limbaj. n acest caz M
+
poate s prevad pentru orice main Turing dac aceasta se oprete
sau nu pentru orice ir w.
Vom arta n continuare c L
0
nu este decidabil. n mod corespunztor rspunsul la cele doua
probleme enunate anterior este : NU.
Dac L
0
este Turing decidabil atunci limbajul :

L
1
= { codif(M) | M accepta codif(M) }

este Turing decidabil. Dac M
0
este maina care decide L
0
atunci se poate construi maina M
1
care s
decid L
1
. Funcionarea M
1
const din transformarea intrrii din #w# n #wcodif(w)# pe care va funciona
apoi M
0
. Deci M
1
va calcula acelai rezultat asupra irului #w# ca i M
0
asupra irului #wcodif(w)#.
Conform definiiei limbajului L
0
, M
0
va scrie D pe banda dac i numai dac :

a. w este codif(M) pentru o main Turing
b. maina Turing M, accept irul w, adic irul de intrare codif(M).

Dar asta este exact definiia limbajului L
1
. Rezult c este suficient s artm c L1 nu este Turing
decidabil. S presupunem c L
1
este Turing decidabil n acest caz i limbajul

Irina Athanasiu 3/1/2002 Limbaje formale i automate

81
L
1
= { w {I,c}* | w nu este codif(M) pentru nici o main Turing
sau w = codif(M) pentru o maina Turing, M,
care nu accept sirul codif(M) }

este decidabil. O main Turing care decide L
1
se obine din maina Turing care decide L
1
inversnd
la oprirea mainii rspunsurile D i N.
Limbajul L
1
nu este ns Turing acceptabil. S presupunem c exist o maina Turing M* care
accepta L
1
. Din definiia limbajului L
1
rezult c:

M, codif(M) L
1
M nu accept codif(M) (1)

dar, M* a fost construit pentru a accept L
1
, adic:

codif(M*) L
1
=> M* accept codif(M*) (2)

Din (1) i (2) rezult

M* nu accept codif(M*) M* accept codif(M*)

adica M* nu poate s existe, adic L
1
, L
1
i deci L
0
nu sunt Turing decidabile.
Deoarece L
0
nu este Turing decidabil nu exist un algoritm care s stabileasc dac o main Turing
oarecare se oprete pentru un ir oarecare. Se observ c am gsit o problema pentru care nu avem o
soluie sub form de algoritm. Astfel de probleme se numesc nedecidabile (nerezolvabile). De fapt L
0

descrie cea mai cunoscut problema nedecidabila i anume problema opriri maini Turing. Enunul acestei
probleme este : "s se determine pentru o main Turing M, arbitrar dac se oprete pentru un ir de
intrare dat ".
Alte probleme nedecidabile echivalente de fapt cu aceast problem sunt :

dndu-se o main Turing, M, se oprete M pentru irul vid ?
dndu-se o maina Turing , M, exist un ir pentru care M se oprete ?
dndu-se o main Turing, M, se oprete M pentru orice ir de intrare ?
dndu-se dou maini Turing, M1 i M2 se opresc ele pentru acelai ir de intrare ?
dndu-se o main Turing, M este limbajul acceptat de M regulat, independent de context, Turing
decidabil ?
dndu-se dou gramatici G1 i G2 arbitrare L(G1) = L(G2) ?
dndu-se o gramatic G arbitrar este L(G) = ?
dndu-se o gramatic G independent de context este G ambigu ?
2.3.3.7 . Maina Turing cu limit de timp

Chiar dac o problem poate s fie rezolvat cu ajutorul unei maini Turing dac timpul de
rezolvare este mult prea mare nseamn c practic problema nu poate s fie rezolvabil cu ajutorul unei
maini Turing. Unul dintre exemplele clasice pentru o astfel de enun este problema comis-voiajorului.
Ideea este c un comis-voiajor trebuie s viziteze 10 orae. Se cunosc distanele dintre orae i se cere s
se construiasc un intinerariu de lungime minim care s permit comis-voiajorului s viziteze toate
oraele. Evident, problema este rezolvabil. Numrul de drumuri posibile este finit (9!) i deci o
parcurgere a tuturor va produce o soluie. S considerm c 9! este nc o valoare siportabil, dar dac am
vorbi de 30 de orae. n acest caz numrul de posibiliti este mai mare dect 10
30
. Timpul pentru a a
analiza toate aceste soluii reprezint mai multe miliarde de viei omeneti. Rezult deci, c din punct de
vedere practic definiia de problem rezolvabil/nerezolvabil trebuie s fie redefinit. n continuare vom
Irina Athanasiu 3/1/2002 Limbaje formale i automate

82
lucra cu maini Turing cu mai multe benzi. Se poate demonstra c timpul de decizie pentru un limbaj nu
depinde de numrul de benzi utilizate.
Fie t o funcie pe numere naturale. Fie L T0
*
un limbaj i M = (Q, T, m, s) o main Turing cu k
piste avnd T0 T. Vom spune c M decide L n timp t dac pentru orice w L

(s, #w#, #, ..., #) |-
x
(h, #D#, #, ..., #) pentru x t(|w|);

iar pentru w L

(s, #w#, #, ..., #) |-
x
(h, #N#, #, ..., #) pentru x t(|w|).

Vom spune c L este decidabil n timp t dac exist un k > 0 i o main Turing cu k piste astfel
nct s decid L n timp t. Clasa limbajelor decidabile n timp t este reprezentat de TIME(t).
Rezult c numrul de pai executai de o main Turing pentru un ir dat depinde de lungimea sa.
Deoarece maina Turing trebuie cel puin s tearg irul de intrare, i s scrie un simbol (D sau N) i s
i poziioneze capul dup acest simbol nseamn c sunt necesare cel puin |w| + 1 operaii de scriere i
|w| + 3 operaii de deplasare. Rezult c pentru funcia t utilizat ca limit de timp t(n) > 2n + 4. S
considerm de exemplu maina care decide limbajul:

L = {w {a,b}
*
| w nu contine sirul aa}

#\ ----+b
\ / |--/
\b/ / #
>L --#L ----->#L/
a a
# #
R D R R N R

n timp ce maina parcurge irul de intrare de la stnga la dreapta l i terge. M va executa numrul
minim de pai, adic M decide L n timp t, cu t(n) = 2n + 4 adic L TIME(t). Acelai lucru se poate
scrie sub forma - L TIME(2n + 4).
Obiectivul unui studiu de complexitate pentru rezolvarea unei probleme const n construirea unei
maini Turing care s asigure c decizia limbajului respectiv se va face n maximum t pai, cu t propus
sau dac asta nu este posibil s se construiasc o demonstraie riguroas c o astfel de main nu se poate
construi.
Se poate demonstra c dndu-se un limbaj L TIME(t) atunci L TIME(t') unde t'(n) = 2n + 18
+ _ x t(n) _ unde x este o valoare real orct de mic (_ r _ reprezint cel mai mic numr ntreg m
astfel nct m r). Ceea ce exprim rezultatul anterior este faptul c ceea ce conteaz este viteza de
cretere i nu factorii constani sau termenii de ordin mai mic.
Fie f i g dou funcii pe numere naturale. Vom nota cu f = O(g) dac i numai dac exist o
constant c > 0 i un numr ntreg n0 astfel nct:

f(n) c g(n) pentru n n0.



d
Dac f(n) = a
j
n
j
atunci f = O(n
d
). Adic viteza de cretere polinomial este reprezentat de
Irina Athanasiu 3/1/2002 Limbaje formale i automate

83
j = 0

rangul polinomului. n afar de polinoame mai exist i alte funcii care dei nu sunt polinomiale sunt
mrginite de polinoame. De exemplu n |_log
2
(n+1)_ = O(n
2
). Evident creterile polinomiale sunt de
preferat celor exponeniale (de forma r
n
) pentru c se poate demonstra c orice funcie exponenial crete
strict mai repede dect una polinomial.
Clasa P ( limbajelor decidabile n timp polinomial) este definit ca:

P = {TIME(n
d
) | d > 0}

Adic este clasa tuturor limbajelor care pot s fie decise de o main Turing ntr-un timp care este
mrginit de o funcie polinomial.
Fie t o funcie pe numere naturale. Fie L T0
*

i fie M = (Q, T, m, s) o main Turing
nedeterminist. Spunem c M accept limbajul L n timp t nedeterminist dac pentru w T0
*,


w L daca si numai daca (s, #w#) |-
x
(h, vau)

pentru v, u T
*
, a T i x t(|w|). Vom spune c limbajul L este acceptabil ntr-un timp t
nedeterminist dac exist o main M care accept L n timp t nedeterminist. Clasa limbajelor acceptabile
n timp t nedeterminist este notat cu NTIME(t). Vom definii

NP = {NTIME(n
d
) | d > 0}

Mai puin formal, P este clasa tuturor mulimilor pentru care apartenena unui element poate s fie
testat eficient. Acelai lucru nu este adevrat pentru NP. Clasa NP conine probleme pentru care
apartenena la P nu a fost demonstrat.
Fie L1 T1* i L2 T2*. O funcie g : T1* T2* este calculabil n timp polinomial dac
exist o main Turing M care calculeaz f n timp t polinomial. O funcie g : T1* T2* calculabil n
timp polinomial. este o transformare polinomial din L1 n L2 dac i numai dac pentru orice w T1*,
w L1 dac i numai dac g(w) L2. Cu alte cuvinte irurile din L1 pot s fie transformate n iruri din
L2 ntr-un timp polinomial.
Se spune c un limbaj L este NP-complet dac i numai dac

(a) L NP;
(b) pentru L' NP, exist o transformare n timp polinomial din L' n L.

Se poate demonstra c dac L este NP-complet atunci P = NP dac i numai dac L P. Deocamdat
nu s-a demonstrat c P NP sau P = NP. Exist numeroase probleme "clasice" care sunt NP-complete.
Pentru aceste probleme de fapt nu se tie dac exist algoritmi de rezolvare n timp polinomiali. Se
consider c este mai probabil c P NP i deci c astfel de algoritmi nu exist. De obicei dac pentru o
problem "nou" se dorete s se cerceteze apartenena la clasa P sau NP se ncearc construirea unei
transformri polinomiale la una dintre problemele cunoscute (de exemplu problema comis voiajorului este
o problem NP-complet).
3 2. Analiza lexical

Rolul analizei lexicale este de a traduce textul programului ntr-o secven de atomi lexicali. n
acest mod se obine un "text" mai uor de prelucrat de ctre celelalte componente ale compilatorului,
Irina Athanasiu 3/1/2002 Limbaje formale i automate

84
deoarece se realizeaz o abstractizare a unei infiniti de iruri de intrare n atomi de tip - identificatori,
constante, etc. De asemenea prin eliminarea blancurilor i a altor separatori irelevani (ca de exemplu
comentarii), textul prelucrat se poate reduce drastic. De cele mai multe ori analiza lexical realizeaz i
alte activitati auxiliare ca de exemplu pstrarea evidenei numrului de linii citite. O astfel de
informaie este foarte util pentru construirea mesajelor de eroare.
Cnd se proiecteaz un analizor lexical se pune n general problema care este nivelul de
complexitate al atomilor lexicali considerai. De exemplu n cazul n care un limbaj utilizeaz numere
complexe, se pune problema dac analizorul lexical va fi cel care va recunoate o constant de forma:

(<real>, <real>)

producnd un atom lexical corespunztor sau recunoaterea unei astfel de constante ramne n
sarcina nivelului analizei sintactice.
n general un analizor lexical este specificat sub forma :

p
1
{actiune 1}
p
2
{actiune 2}
...
p
n
{actiune n}

unde p
i
este o expresie regulata, iar actiune i este o secven de operaii care se execut pentru fiecare
subir care corespunde modelului oferit de p
i
.
S considerm de exemplu irurile de caractere 99.E10 i 99.EQ.10, care pot s apara ntr-un
program FORTRAN. n primul caz este vorba de numrul 99 x 10
10
, n al doilea caz de o expresie
relaional. Dac analiza se oprete dupa identificarea punctului zecimal cu concluzia c s-a identificat
un numr real se observa c n primul caz oprirea se face prea devreme iar n al doilea caz prea trziu.
O soluie const din identificarea acestor situaii realizndu-se aa numita cutare nainte. Astfel,
pentru cazul considerat, dup recunoaterea irului 99. se mai cerceteaz cel puin un caracter pentru a
se hotar dac analiza trebuie s se incheie la 99 sau trebuie s continue pn la 99.E10 . O abordare mai
bun consta din cutarea sistematic a celui mai lung subir care satisface unul din modelele p
1
,...,p
n
. Dac
exist mai multe modele de aceai lungime care sunt satisfcute se va alege o convenie de alegere :
de exemplu n ordinea p
1
,...,p
n
.
Un analizor lexical este de fapt implementarea unui automat finit. Ceea ce se schimb de la un
analizor lexical la altul este numai specificarea modelelor cutate i a aciunilor asociate.
Irina Athanasiu 3/1/2002 Limbaje formale i automate

85

inceput subsir
--------------------------------
| buffer de intrare
--------------------------------
\ cap de citire
\
+-----------+
| simulator |--------------+
| automat | |
+-----------+ |
| |
+-----------+ +-----------+
| tabela | | tabela |
| de | | proceduri |
| tranzitii | | tratare |
+-----------+ | actiuni |
+-----------+

S discutm nti cum se construiete un automat finit nedeterminist pornind de la
specificaiile analizorului lexical. Se observ c trebuie s se construiasca un AFN care s
recunoasca o expresie regulata de forma p1 | p2 | ... | pn. n general automatul care rezult este :

-------------------------
| +---+ +-----+ |
| | | N(p1) |+---+| |
---------> | |-- -->|| || |
/ | | | |+---+| |
/ | +---+ +-----+ |
+---+ / | |
| |/ -------------------------
| |\ -------------------------
->| s0| \ | |
| |\ \ | +---+ +-----+ |
| | \ \ | | | N(p2) |+---+| |
+---+ \ ---------->| |-- -->|| || |
\ | | | |+---+| |
| | +---+ +-----+ |
| | |
| -------------------------
| ...
|
| -------------------------
| | +---+ +-----+ |
| | | | N(pn) |+---+| |
+--------->| |-- -->|| || |
| | | |+---+| |
| +---+ +-----+ |
| |
-------------------------

Pentru a simula acest automat se utilizeaz o modificare a algoritmului de simulare a AFN
pentru a asigura recunoaterea celui mai lung prefix care se potrivete unui model. n acest scop se
realizeaz simularea continua pn cnd se obine o mulime de stari pentru care nu mai exist nici o
tranziie posibil pentru simbolul curent. Se presupune c limbajul este astfel nct bufferul de intrare
nu poate fi mai scurt dect o lexema (irul de caractere corespunztor unui atom lexical recunoscut).
Irina Athanasiu 3/1/2002 Limbaje formale i automate

86
De exemplu orice compilator are o limit (eventual foarte mare) pentru numrul de caractere dintr-un
identificator.
Ori de cte ori ntr-o mulime de stri se adaug o stare final se va memora att poziia n irul
de intrare ct i modelul p
i
corespunztor. Dac n mulimea respectiv exist deja o stare final atunci
se va memora numai unul dintre modele (conform conveniei stabilite). Cnd se ajunge n situaia de
terminare se revine la ultima poziie n irul de intrare la care s-a facut o recunoatere a unui model.
S considerm de exemplu un analizor lexical specificat n modul urmtor :

a
abb
a*b+

Pentru acest analizor nu s-au specificat aciunile corespunztoare unitilor lexicale. Automatul finit
nedeterminist corespunztor este:

+---+ +-----+
| | a |+---+|
---------> | 1 |----->|| 2 ||
/ | | |+---+|
/ +---+ +-----+
+---+ / +---+ +---+ +---+ +-----+
| |/ | | a | | b | | b |+---+|
| 0 |-------------> |3 |------>| 4 |----->| 5 |----->|| 6 ||
| |\ | | | | | | |+---+|
+---+ \ +---+ +---+ +---+ +-----+
\ +---+ +-----+
\ | | b |+---+|
--------->| 7 |----->|| 8 ||
| | |+---+|
+---+ +-----+
/ \ / \
--- ----
a b

S considerm comportarea acestui automat pentru irul de intrare aaba :

a a b a
{0,1,3,7} - {2,4,7} - {7} - {8} -

Se observ c prima stare de acceptare este 2 n care se ajunge dup primul simbol a, apoi va fi
gsit starea 8 la care se revine dup ce se ajunge la terminare dupa simbolul a de la sfritul irului.
S considerm i varianta care utilizeaz un automat determinist. Pentru exemplul anterior
se obine automatul determinist echivalent descris de urmtoarea tabela de tranziii:

Irina Athanasiu 3/1/2002 Limbaje formale i automate

87
stare | intrare | model recunoscut
| a b |
---------------+----------------+---------------------
{0,1,3,7} | {2,4,7} {8} | -
---------------+----------------+---------------------
{2,4,7} | {7} {5,8} | a (pentru 2)
---------------+----------------+---------------------
{8} | - {8} | a*b+
---------------+----------------+---------------------
{7} | {7} {8} | -
---------------+----------------+---------------------
{5,8} | - {6,8} | a*b+
---------------+----------------+---------------------
{6,8} | - {8} | abb
------------------------------------------------------

Se observ c starea {6,8} conine dou stri finale deci recunoate att modelul a
*
b
+
ct i
abb. Considerm prin convenie c model recunoscut n acest caz trebuie s fie abb. De exemplu pentru
irul abba evoluia va fi :
a b b a
{0,1,3,7} - {2,4,7} - {5,8} - {6,8} -
3.1 Interfaa analizorului lexical

Dupa cum se tie analizorul lexical funcionez ca un modul n cadrul unui compilator sau a
oricrui program care realizeaz prelucrri ce necesit identificarea unor iruri ce pot fi descrise de o
gramatic regulat. n funcionarea sa analizorul lexical interacioneaz cu celelalte componente
ale compilatorului prin intermediul unei interfee specifice :

+---------------+ insert_s +-------------------+
| | +---------> | |
| Program sursa | | | tabela de simboli |
| | | +------| |
+---------------+ | | +-------------------+
| /|\ | |
| |revenire | \|/ lookup_s
| | +------------------+
| +-------| |
| | Analizor lexical |<------+
+----------->| | | lookup_c
avans_intrare() +------------------+ |
anlex | | | insert_c |
+--------------------+ | | | +---------------------+
| | | | | | |
| Analizor sintactic |<--+ | +--->| tabela de constante |
| | | | |
+--------------------+ | +---------------------+
\|/ eroare
+---------------+
| |
| Tratare erori |
| |
+---------------+

Irina Athanasiu 3/1/2002 Limbaje formale i automate

88
Interaciunea cu fiierul surs se face prin intermediul a dou subprograme : avans_intrare (care
preia caracterul urmtor din programul sursa) i revenire (care realizeza revenirea napoi n textul surs,
dac ntotdeauna revenirea se face cu un singur caracter se poate utiliza o funcie de tip ungetc).
Tabela de simboli este o structur de date al carui rol este de a memora informaii referitoare la
atomii lexicali de tip identificator recunoscui de ctre analizorul lexical. Informaiile referitoare
la acesti simboli sunt utilizate att n cadrul analizei sintactice ct i n faza de generare de cod.
Introducerea simbolilor n tabela de simboli se face de ctre analizorul lexical, completarea
informaiilor realizndu-se de ctre analizorul sintactic care va aduga informaii ca de exemplu tipul
simbolului (procedura, variabila, eticheta, etc) i modul de utilizare. Legatura cu tabela de simboli se face
prin intermediul a doua proceduri : insert_s i lookup_s. Procedura insert_s are ca argumente un ir de
caractere i codul atomului lexical reprezentat de ir. Rezultatul procedurii este adresa n tabela de
simboli la care s-a facut memorarea simbolului. Procedura lookup_s are ca argument un ir iar ca
rezultat adresa n tabela de simboli la care se gsete simbolul reprezentat de irul respectiv. Dac n
tabela nu exist irul cutat rezultatul este 0.
Pentru cuvintele cheie de obicei se face o tratare speciala, de exemplu se poate initializa tabela de
simboli cu intrari corespunztoare tuturor cuvintelor cheie din limbajul respectiv executnd apeluri de
forma :

insert_s("if", cod_if);
insert_s("else", cod_else);

etc. nainte de a se ncepe execuia efectiv a compilatorului. n acest caz recunoaterea cuvintelor
cheie se va face apoi ntr-un mod similar cu a oricarui alt identificator. Se observ deci de ce n
majoritatea limbajelor de programare cuvintele cheie nu pot s fie utilizate ca nume cu alt
semnificaie. O astfel de tratare are avantajul ca n cazul n care se face o declaraie de tip de forma:

typedef int intreg;

dup introducerea n tabela de simboli a cuvintului intreg de ctre analizorul lexical, analizorul
sintactic va putea s completeze apoi intrarea n tabela de simboli cu informaiile corespunztoare
numelui unui tip. n acest mod n urmtoarele ntlniri ale acestui cuvnt analizorul lexical va putea
s transmit ca ieire atomul lexical corespunztor unui nume de tip.
n cazul constantelor analizorul lexical realizeaz recunoaterea acestora i memoreaz
valorile corespunztoare n tabela de constante pentru a permite utilizarea ulterioar n cadrul generrii
de cod.
Analizorul sintactic apeleaz de obicei analizorul lexical ca pe o funcie care are ca valoare
codul atomului lexical recunoscut de ctre analizorul lexical. n general ntre analizorul lexical i
analizorul sintactic trebuie s se mai transfere i alte informaii ca de exemplu adresa n tabela de
simboli sau n tabela de constante a unui identificator, cuvntul cheie respectiv constanta identificata de
ctre analizorul lexical. Aceste informaii reprezint atributele atomului lexical.
Un compilator recunoate erori n toate fazele sale: analiza lexical, sintactic i n generarea
de cod. Dac se intlnete o eroare, se pune problema localizrii sale ct mai precise i apoi a
modului n care se continua analiza astfel nct n continuare s se semnaleze ct mai puine erori care
decurg din aceasta.
Un aspect important al interfetei analizorului lexical o constituie interfaa cu sistemul de
operare corespunztoare citirii textului programului surs. n general este bine ca interfaa cu sistemul de
operare s fie ct mai bine separat de restul compilatorului pentru a se obine un cod portabil prin
pstrarea aspectelor dependente de main n cadrul funciilor care formeaz aceasta interfa.
Din timpul consumat de ctre procesul de compilare o parte foarte important se consum n
cadrul analizei lexicale. La rndul sau partea cea mai consumatoare de timp este de obicei partea
legat de operaiile de citire. n mod standard obinerea unui caracter n execuia unui program
Irina Athanasiu 3/1/2002 Limbaje formale i automate

89
presupune copierea acestuia n mai multe etape - de pe disc n zona tampon a sistemului de operare, din
aceast zon n zona prevazut n program, de unde apoi se face copierea n variabila care memoreaz
caracterul curent.
Chiar i n cazul unui analizor lexical foarte simplu care ar trebui s recunoasc irurile : xxyy, xx
i y dac n irul de intrare se ntlneste irul xxy trebuie s se mai citeasc nc un caracter pentru a se
putea stabili dac este vorba de atomul lexical xxyy sau de atomii lexicali xx i y. Se observ ca n
acest caz utilizarea unei proceduri de tip ungetc() nu este suficient.
n general o colecie de funcii care asigur citirea textului surs pentru analizorul lexical
trebuie s satisfac urmtoarele condiii:

funciile trebuie s fie ct mai rapide, realiznd un numr minim de copieri pentru caracterele
parcurse;
existena unui mecanism care s permit examinarea unor caractere n avans i revenirea pe irul de
intrare;
s admit atomi lexicali suficient de lungi;

Pentru a obine o utilizare eficient a operaiilor legate de accesul la disc este necesar ca
dimensiunea bufferuluis fie adaptat modului de alocare a spatiului pe disc. Astfel, pentru sistemul de
operare MS-DOS utilizarea unui buffer mai mic dect 512 octei nu are nici o justificare (o operaie de
citire va citii cel puin un sector de pe disc). De preferat este ca bufferul s fie un multiplu al unitii
de alocare a spatiului pe disc.
3.2 Un exemplu elementar de analizor lexical

S considerm analizorul lexical corespunztor unui translator pentru limbajul descris de
urmatoarea gramatic :

S lista eof
lista expresie; lista |
expresie expresie + termen | expresie - termen |
termen
termen termen * factor | termen / factor |
termen div factor | termen mod factor |
factor
factor (expresie) | identificator | numr
identificator litera rest_id
rest_id litera rest_id | cifra rest_id |
numr cifra numr | cifra
litera A | B | ... z
cifra 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Se observ ca nivelul analizei lexicale printr-o transformare corespunztoare presupune
recunoaterea urmtorilor atomi lexicali :


Irina Athanasiu 3/1/2002 Limbaje formale i automate

90
atom lexical actiune

numr calcul valoare
identificator introduce n tabela de simboli
div
mod
(
)
*
/
+
-
;
eof

n afar de recunoaterea acestor atomi analizorul lexical realizeaz i o eliminare a blancurilor
i a unor caractere speciale de tip '\n' sau '\t'. Avnd n vedere tipul atomilor lexicali ce trebuie s fie
recunoscui nu este necesar utilizarea unei interfee sofisticate cu sistemul de operare.
Tabela de simboli trebuie s memoreze pentru fiecare identificator (cuvnt cheie) - irul de
caractere respectiv, codul asociat (prin intermediul cruia va fi tratat de ctre analizorul lexical) i
eventual alte atribute semnificative pe care le poate aduga analiza sintactic. Deoarece lungimea
irurilor care formeaz identificatorii poate s fie foarte diferit pentru a se asigura o bun utilizare a
memoriei se va utiliza o tabel de simboli format dintr-un vector n care se nregistreaz irurile
corespunztoare cuvintelor cheie i identificatorilor recunoscui n textul surs i o tabel cu dou sau
mai multe colane. n tabel, fiecare intrare este asociat unui simbol, i conine adresa n vectorul care
memoreaz irurile i codul asociat simbolului respectiv.

sir simboli tabela de simboli
lexptr atom_lexical

| | |
+-----------------------------------| | DIV |
| |----+---------------|
| +-------------------| | MOD |
| | |----+---------------|
| | +---| | IDENTIFICATOR |
| | | | | |
\|/ \|/ \|/
+---------------------------------------------------+
| d | i | v |EOS| m | o | d |EOS| a | l | f | a |EOS|
+---------------------------------------------------+

Analizorul lexical poate s fie descris de urmtorul graf :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

91
blanc,\n,\t /A7 cifra,
-- litera / A3
\/ --
+-------+ \/ +-----+
| | litera / A2 +---+ litera / A4 |+---+|
| |------------>| 1 | --------------> || ||
| | +---+ cifra |+---+|
| | cifra / A3 +-----+
| | --
| | \/ +-----+
| | cifra / A2 +---+ cifra / A5 |+---+|
| 0 |------------->| 2 |-------------- > || ||
| | +---+ |+---+|
| | +-----+
| | +-----+
| | */A1,//A1,+/A1,-/A1,(/A1,)/A1,;/A1 |+---+|
| |---------------------------------> || ||
| | EOF/A6 || ||
| |----------------------------------> |+---+|
+-------+ +-----+

n graf au fost evideniate caracterele i aciunile corespunztoare acestora.
Interfaa cu analizorul sintactic se realizeaz prin intermediul rezultatului apelului analizorului
lexical (valoarea funciei anlex()) i prin variabila tokenval. Valoarea ntoars de funcia anlex() este
codul atomului lexical recunoscut. Variabila tokenval primete o valoare care depinde de tipul
atomului lexical recunoscut. Astfel pentru un numr aceast variabil va conine valoarea
numrului iar pentru un identificator adresa n tabela de simboli (la care a fost introdus sau regsit
identificatorul respectiv).
Atomii lexicali care presupun asignarea unor coduri distincte sunt : NUMR(256),
DIV(257), MOD(258), IDENTIFICATOR(259), GATA(260).
Pentru ceilali atomi lexicali codul, corespunde codului ASCII al caracterului ce reprezint
atomul lexical respectiv.
Fiecare identificator este asamblat ntr-o zon tampon auxiliar buffer_intrare. n momentul n care
se ncheie construirea unui identificator (se identific sfritul irului) se poate face cutarea acestuia n
tabela de simboli, eventual se va introduce simbolul respectiv n tabela de simboli.
n legatura cu tabela de simboli programul conine trei proceduri :

init() - realizeaz introducerea n tabela de simboli a uvintelor cheie
lookup(s) - caut n tabela de simboli irul de caractere transmis ca argument. Rezultatul intors de
aceast procedur este adresa relativ n tabela de simboli.
insert(s,t) - introduce un simbol nou la sfritul tabelei de simboli. Al doilea argument de apel este
codul atomului lexical reprezentat de irul respectiv.

Aciunile ce trebuie s fie executate n legatur cu execuia analizorului lexical sunt urmtoarele:

A1 : tokenval = NIMIC;
return caracter;

A2 : b = 0 ;


Irina Athanasiu 3/1/2002 Limbaje formale i automate

92
A3 : buffer_intrare[b++] = caracter;
caracter = getchar();
if (b >= BSIZE)
eroare("sir prea lung");

A4 : buffer_intrare[b] = EOS;
if (caracter != EOF)
ungetc(caracter, stdin);
p = lookup(buffer_intrare);
if (p == 0)
p = insert(buffer_intrare, IDENTIFICATOR);
tokenval = p;
return tabela_simboli [p].atom_lexical;

A5 : buffer_intrare[b] = EOS;
if (caracter != EOF)
ungetc(caracter, stdin);
tokenval = atoi(buffer_intrare);
return NUMR;

A6 : tokenval = NIMIC;
return GATA;

A7 : if (caracter == ' '|| caracter == '\t')
;
else if (caracter == '\n')
lineno++;

Corespunztor va rezulta urmtorul program care citete i afieaz codurile atomilor lexicali
intilnii.
Irina Athanasiu 3/1/2002 Limbaje formale i automate

93

#include "stdlib.h"
#include "stdio.h"
#include "ctype.h"
#include "string.h"

#define BSIZE 128
#define NIMIC -1
#define EOS '\0'

#define NUMAR 256
#define DIV 257
#define MOD 258
#define IDENTIFICATOR 259
#define GATA 260

#define MAXSIR 999
#define MAXSIM 100

/*
variabile globale
*/

static int ultimul_caracter = -1; /* ultimul caracter citit */
static int ultima_intrare = 0;
static int tokenval = NIMIC; /* cod atom lexical */
static int lineno = 1; /* numar linie cod */
static char buffer_intrare[BSIZE];
static int caracter, p, b;

/*
tabela de simboli
*/

static char sir_simboli [MAXSIR]; /* sir de nume identificatori */
struct intrare { char *lexptr;
int atom_lexical;
};
static struct intrare tabela_simboli [MAXSIM];

static struct intrare cuvinte_cheie[] = {
"div", DIV,
"mod", MOD,
0, 0
};

/*
prototipuri functii
*/

static int lookup(char s[]);
static int insert(char s[],int tok);
static void init(void);
static void a3(void);
static void eroare (char *m);
static int lexan(void);

/*
cauta n tabela de simboli
*/
Irina Athanasiu 3/1/2002 Limbaje formale i automate

94

static int lookup(char s[])
{
int p;
for (p = ultima_intrare; p > 0; p--)
if (strcmp(tabela_simboli[p].lexptr, s) == 0)
return p;
return 0;
}

/*
introducere n tabela de simboli
*/

static int insert(char s[], int tok)
{
int len;
len = strlen(s);
if (ultima_intrare + 1 >= MAXSIM)
eroare("s-a depasit dimensiunea tabelei de simboli");
if (ultimul_caracter + len + 1 >= MAXSIR)
eroare("s-a depasit dimensiunea tabelei de simboli");
tabela_simboli[++ultima_intrare].atom_lexical = tok;
tabela_simboli[ultima_intrare].lexptr =
&sir_simboli[ultimul_caracter + 1];
ultimul_caracter = ultimul_caracter+len +1;
strcpy(tabela_simboli[ultima_intrare].lexptr,s);
return ultima_intrare;
}

/*
initializarea tabelei de simboli
*/

static void init()
{
struct intrare *p;
for (p = cuvinte_cheie; p -> atom_lexical;p++)
insert(p->lexptr, p->atom_lexical);
}

/*
tratarea erorilor
*/

static void eroare (char *m)
{
printf("line %d: %s\n", lineno, m);
exit(1);
}

/*
analizorul lexical
*/
static void a3()

{ buffer_intrare[b++] = caracter;
caracter = getchar();
if (b >= BSIZE)
eroare("ir prea lung");
Irina Athanasiu 3/1/2002 Limbaje formale i automate

95
}

static int lexan()
{ while(1)
{ caracter = getchar();
/* A7 */
if (caracter == ' '|| caracter == '\t')
; /* eliminare blancuri si tab-uri */
else if (caracter == '\n')
lineno++;
else if (isdigit(caracter)) /* caracter este cifra */
{ /* A2 */
b = 0;
while (isdigit(caracter))
/* A3 */
a3();
/* A5 */
buffer_intrare[b] = EOS;
if (caracter != EOF)
ungetc(caracter, stdin);
tokenval = atoi(buffer_intrare);
return NUMR;
}
else if (isalpha(caracter)) /* caracter este litera */
{ /* A2 */
b = 0;
while (isalnum(caracter)) /* litera sau cifra */
/* A3 */
a3();
/* A4 */
buffer_intrare[b] = EOS;
if (caracter != EOF)
ungetc(caracter, stdin);
p = lookup(buffer_intrare);
if (p == 0)
p = insert(buffer_intrare, IDENTIFICATOR);
tokenval = p;
return tabela_simboli [p].atom_lexical;
}
else if (caracter == EOF)
{ /* A6 */
tokenval = NIMIC;
return GATA;
}
else
{ /* A1 */
tokenval = NIMIC;
return caracter;
}
}
}
void main()
{ int simbol_curent;
init();
simbol_curent = lexan();
while (simbol_curent != GATA)
{ printf(" %d\n",simbol_curent);
simbol_curent = lexan();
}
}
Irina Athanasiu 3/1/2002 Limbaje formale i automate

96

De fapt orice analizor lexical are aceai form general, i construirea unui analizor lexical parcurge
ntotdeauna aceleai etape:

1. construirea expresiilor regulate care descriu atomii lexicali care urmeaz s fie recunoscui de ctre
analizorul lexical (nu se poate automatiza)
2. construirea automatului finit nedeterminist care accept expresiile regulate (se poate face n mod
automat)
3. construirea automatului finit determinist echivalent cu cel nedeterminist construit n pasul anterior (se
poate face n mod automat)
4. implementarea unui simulator pentru un automat finit determinist. Acest simulator poate s fie general
(adic s poat s fie utilizat pentru orice automat finit determinist), sau poate s fie construit special
pentru automatul respectiv.

De fapt n pasul trei se construiete tabela de tranziie a automatului. Dac simulatorul este general
(adic este capabil s simuleze orice automat specificat prin tabela de tranziii) se observ c ncepnd din
pasul al doilea, toate operaiile se pot face n mod automat adic se poate construi un program care
pornind de la expresiile regulate i aciunile asociate s genereze un analizor lexical. Cel mai cunoscut
program de acest tip este lex. Iniial acest program a fost utilizat numai sub UNIX. n prezent exist
variante i pentru MS-DOS.
Specificaiile lex pentru analizorul lexical simplu considerat anterior sunt:

Irina Athanasiu 3/1/2002 Limbaje formale i automate

97
%{
#define NOTHING -1
#define NMBER 256
#define DIV 257
#define MOD 258
#define IDENTIFIER 259
#define FINISH 260

#define MAXSIR 999
#define MAXSYM 100

/*
global variables
*/

int last_character = -1; /* last character */
int last_entry = 0;
int tokenval = NOTHING; /* current token */
int lineno = 1;
int p;

/*
symbol table

*/
char string_array [MAXSIR]; /* string of names */
struct entry { char *lexptr;
int token;
};
struct entry symbol_table [MAXSYM];

struct entry reserved_words [] = {
"div", DIV,
"mod", MOD,
0, 0
};

void error (char *m)
{ printf("line %d: %s\n", lineno, m);
exit(1);
}

/*
lookup in symbol table
*/

int lookup(char s[])
{ int p;
for (p = last_entry; p > 0; p--)
if (strcmp(symbol_table[p].lexptr, s) == 0)
return p;
return 0;
}

/*
inserting in symbol table
*/

int insert(char s[], int tok)
{ int len;
Irina Athanasiu 3/1/2002 Limbaje formale i automate

98
len = strlen(s);
if (last_entry + 1 >= MAXSYM)
error("too many symbols");
if (last_character + len + 1 >= MAXSIR)
error("too many or too long strings");
symbol_table[++last_entry].token = tok;
symbol_table[last_entry].lexptr =
&string_array[last_character + 1];
last_character = last_character+len +1;
strcpy(symbol_table[last_entry].lexptr,s);
return last_entry;
}

/*
initialization for symbol table
*/

void init()
{
struct entry *p;
for (p = reserved_words; p-> token;p++)
insert(p->lexptr, p->token);
}

%}

/*
the scanner
*/

delim [ \t]
nl [\n]
ws {delim}+
letter [A-Za-z]
digit [0-9]
letgit [A-Za-z0-9]

%%
div return DIV;
mod return MOD;
{letter}{letgit}* { p = lookup(yytext);
if (p == 0)
p = insert(yytext, IDENTIFIER);
tokenval = p;
return symbol_table [p].token;
}

{digit}+ { tokenval = atoi(yytext);
return NMBER;
}

{nl} lineno++; return NOTHING;
{delim}+ return NOTHING;
<<EOF>> return FINISH;
. return yytext[0];

%%
void main()
{ int symbol_current;
yyin = stdin;
Irina Athanasiu 3/1/2002 Limbaje formale i automate

99
init();
tokenval = NOTHING;
symbol_current = yylex();
while (symbol_current != FINISH)
{ if (symbol_current != NOTHING)
printf(" symbol = %i, tokenval = %i\n",
symbol_current, tokenval);
tokenval = NOTHING;
symbol_current = yylex();
}
}
4 Analiza sintactic

Rolul fazei de analiza sintactica este de a construi arborii de derivare corespunztori propoziiilor
din limbajul respectiv verificnd buna structurare a acestora. Termenul utilizat n literatura de
specialitate pentru aceasta aciune este "parsing".
Considernd gramatica expresiilor aritmetice :

(1) + T
(2) T
(3) T T * F
(4) T F
(5) F ()
(6) F a

i irul de intrare a * (a + a) s construim o derivare stnga :

2 3 4 6 5 1
T T * F F * F a * F a * ()
2 4 6
a * ( + T) a * (T + T) a * (F + T)
4 6
a * (a + T) a * (a + F) a * (a + a)

Lista produciilor aplicate este 23465124646. Pentru derivarea dreapta se obine:

2 3 5 1 4
T T * F T * () T * ( + T)
6 2 4
T * ( + F) T * ( + a) T * (T + a)
6 4 6
T * (F + a) T * (a + a) F * (a + a)

a * (a + a)

n acest caz lista produciilor care trebuie s fie aplicate pentru sintetizarea neterminalului de start al
gramaticii este 64642641532. Ambele liste de producii descriu acelai arbore de derivare.
Irina Athanasiu 3/1/2002 Limbaje formale i automate

100

| 2
T
/ | \ 3
T * F
4 | /|\ 5
F ( )
6 | / | \ 1
a + T
| 2 | 4
T F
| 4 | 6
F a
| 6
a

Se observ c pentru derivarea stnga este vorba de o parcurgere RSD, iar pentru derivarea drapta
parcurgerea arborelui este SDR. Evident dndu-se o parcurgere i produciile gramaticii se poate
reconstrui arborele de derivare.
n general pentru o gramatic independent de context se poate construi un automat de tip push
down care s produc pentru un ir de intrare dat lista de producii care duce la acceptarea irului
respectiv. n acest scop se defineste notiunea de translator push down. Un astfel de translator se
construiete adaugnd o ieire unui automat push down. La fiecare micare a automatului push down,
translatorul va emite un ir finit de simboli. Deci definiia este:

PDT = (Q, T, Z, X, m, q0, z0, F)

unde X este un alfabet finit de ieire, iar funcia m este definit ca m : Q x (T {}) x Z P(Q
x Z* x X*). n acest caz o configuraie a automatului are patru componente : (q, , , ), q Q,
T*, Z*, X*, unde reprezint irul de simboli generat pn la momentul curent de ctre
automat. Se spune c automatul realizeaz traducerea irului T* n irul X* dac este
indeplinit condiia :

(q0, , z0, ) |-
*
(q, , w, ) q F, w Z*

n general traducerile realizate de ctre translator sunt :

{ (, ) | (q0, , z0, ) |-
*
(q, , , ) q F, Z*,
T*, X*}

Similar definitiilor referitoare la automatele push down exist noiunile de translatare prin stiv
goal i translator push down extins. Pentru o gramatic independent de context putem s construim
un translator push down care produce lista produciiilor corespunztoare derivrilor stnga i
dreapta.
S considerm din nou gramatica expresilor aritmetice. Rezult translatorul care produce
lista produciilor corespunztoare derivrilor stnga :

({q},{a,+,*,(,)},{, T, F,a,+,*,(,)}, {1, 2, ..., 6}, m, q, , )

cu
Irina Athanasiu 3/1/2002 Limbaje formale i automate

101
m(q, , ) = {(q, + T, 1), (q, T, 2)}
m(q, , T) = {(q, T * F, 3), (q, F, 4)}
m(q, , F) = {(q, (), 5), (q,a,6)}
m(q, x, x) = {(q, , )} x T

De exemplu pentru irul a * (a + a) se obine evoluia :

(q, a * (a + a), , ) |- (q, a * (a + a), T, 2)
|- (q, a * (a + a), T * F, 23)
|- (q, a * (a + a), F * F, 234)
|- (q, a * (a + a), a * F, 2346)
|- (q, * (a + a), * F, 2346)
|- (q, (a + a), F, 2346)
|- (q, (a + a), (), 23465)
|-+ (q, , , 23465124646)

n cazul derivrii dreapta se obine translatorul push down:

({q}, {a,+,*,(,)}, {,T,F,a,+,*,(,),$}, {1,2,...,6}, m, q, $, )

cu

m(q, , + T) = {(q, , 1)}
m(q, , T) = {(q, , 2)}
m(q, , T * F) = {(q, T, 3)}
m(q, , F) = {(q, T, 4)}
m(q, , ()) = {(q, F, 5)}
m(q, , a) = {(q, F, 6)}
m(q, x, ) = {(q, x, )} x T
m(q, , $)} = {(q, , )}

Pentru acelai ir se obine secvena de micri:

Irina Athanasiu 3/1/2002 Limbaje formale i automate

102
(q, a * (a + a), $, ) |- (q, * (a + a), $a, )
|- (q, * (a + a), $F, 6)
|- (q, * (a + a), $T, 64)
|- (q, (a + a), $T *, 64)
|- (q, a + a), $T * (, 64)
|- (q, + a), $T * (a, 64)
|- (q, + a), $T * (F, 646)
|- (q, + a), $T * (T, 6464)
|- (q, + a), $T * (, 64642)
|- (q, a), $T * ( +, 64642)
|- (q, ), $T * ( + a, 64642)
|- (q, ), $T * ( + F, 646426)
|- (q, ), $T * ( + T, 6464264)
|- (q, ), $T * (, 64642641)
|- (q, , $T * (), 64642641)
|- (q, , $T * F, 646426415)
|- (q, , $T, 6464264153)
|- (q, , $, 64642641532)
|- (q, , , 64642641532)

Se observ c cele dou translatoare construite sunt nedeterministe. Se pune problema dac
ntotdeauna un astfel de translator poate s fie simulat determinist deoarece ceea ce ne intereseaz este
s obinem analizoare sintactice respectiv compilatoare ct mai eficiente i cu o comportare
determinist.
Exist gramatici pentru care aceasta condiie nu poate s fie ndeplinit. De exemplu, pentru o
gramatic recursiv stnga nu se poate construi un translator care s produc irul produciilor
dintr-o derivare stnga i s poata s fie simulat determinist.
Pentru fiecare tip de analizor sintactic(ascendent sau descendent) exist cte o clasa de
gramatici pentru care se poate construi un translator determinist dac translatorul are acces la urmtorii
k simboli de pe irul de intrare. Cele doua clase se numesc LL(k) respectiv LR(k). n denumire prima
liter (L) reprezint tipul de parcurgere al irului - de la stnga (Left) la dreapta. A doua litera (L sau R)
specific tipul derivarii - stnga (Left) sau dreapta (Right). Micrile translatorului se fac innd seama
de starea curent (starea unitii de control i coninut stiv) i de urmtorii k simboli de pe irul de intrare.
S considerm de exemplu urmtoarea gramatic:

(1) S BAb
(2) S CAc
(3) A BA
(4) A a
(5) B a
(6) C a

Se observ c L(G) = aa
+
b + aa
+
c. Gramatica nu este nici LR(k) i nici LL(k) deoarece nu se tie dac
primul a dintr-un ir din L(G) este generat utiliznd produciile 1 i 5 sau 2 i 6. Aceasta informaie
este aflat abia cnd se ajunge la sfritul irului i se citete ultimul simbol. Se observ c de fapt
problema este c nu se tie cte caractere trebuie s fie cercetate n avans pentru a lua o decizie
corect.
Se poate arta c dac o gramatic este LL(k) ea este i LR(k) dar exist gramatici LR(k) care
nu sunt LL(k). Cu alte cuvinte gramaticile LL(k) sunt un subset al gramaticilor LR(k).
Irina Athanasiu 3/1/2002 Limbaje formale i automate

103
4.1 Analiza sintactica top - down

Analiza sintactic top-down poate s fie interpretat ca operaia de construire a arborilor de
derivare pornind de la rdcin i adaugnd subarbori de derivare ntr-o ordine prestabilit.
S considerm de exemplu gramatica S cAd, A ab | a i irul de intrare cad. Construirea
arborelui de derivare pentru acest ir pornete de la simbolul de start al gramaticii S cu capul de citire pe
irul de intrare poziionat pe caracterul c. Pentru S se utilizeaz producia S cAd i se obine
arborele de derivare :

S
/|\
/ | \
c A d

n acest moment se observ c frunza cea mai din stnga corespunde cu primul caracter din irul
de intrare. n acest caz se avanseaz cu o poziie pe irul de intrare i n arborele de derivare. Frunza
curent din arborele de derivare este acum A i se poate aplica una dintre produciile
corespunztoare acestui neterminal :

S
/|\
/ | \
c A d
/ \
/ \
a b

Se poate avansa pe irul de intrare i n arbore deoarece avem din nou coincidena simboliilor
terminali. n acest moment se ajunge la compararea simbolului d din irul de intrare cu simbolul b
din arbore, corespunztor trebuie s se revin cautndu-se o nou variant pentru A. Rezult c capul de
citire trebuie s fie readus n poziia simbolului a. Dac acum se utilizeaz producia A a se obine
arborele :

S
/|\
/ | \
c A d
|
|
a

n continuare se va ajunge la acceptarea irului de intrare.
Din cele prezentate anterior rezult dou observaii :

n general implementarea presupune utilizarea unor tehnici cu revenire (backtracking);
dac gramatica este recursiv stnga algoritmul poate conduce la apariia unui ciclu infinit.
Irina Athanasiu 3/1/2002 Limbaje formale i automate

104
4.1.1 Analiza sintactica predictiva (descendent recursiva)

Dezavantajul abordrii anterioare const n necesitatea revenirilor pe irul de intrare ceea ce
conduce la complicarea deosebit a algoritmilor i mai ales a structurilor de date implicate deoarece
automatul cu stiv corespunztor cazului general trebuie s fie nedeterminist. Exist ns gramatici pentru
care dac se utilizeaza transformri, prin eliminarea recursivitatii stnga i prin factorizare se obin
gramatici care pot s fie utilizate pentru analiza top-down fr reveniri. n acest caz dndu-se un simbol
de intrare curent i un neterminal exist o singur alternativ de producie prin care din neterminalul
respectiv s se deriveze un ir care ncepe cu simbolul de intrare care urmeaz.
Pentru proiectarea analizoarelor predictive se utilizeaz diagrame de tranziie. O diagram de
tranziie este un graf care prezint produciile corespunztoare unui neterminal. Etichetele arcelor
reprezint atomi lexicali sau simboli neterminali. Fiecare arc etichetat cu un atom lexical indic
tranziia care urmeaz s se execute dac se recunoate la intrare atomul lexical respectiv. Pentru arcele
corespunztoare neterminalelor se vor activa procedurile corespunztoare neterminalelor respective.
Pentru a construi o diagrama de tranziie pentru un neterminal A ntr-o gramatica n care nu
exist recursivitate stnga i n care s-a fcut factorizare stnga se procedeaz n modul urmtor :

1. se creaz dou stri: iniial i final;
2. pentru fiecare producie A X1 X2 ... Xn se va crea o cale format din arce ntre starea iniial i
starea final cu etichetele X1 X2 ... Xn.

Analizorul predictiv care lucreaz asupra diagramei de tranziii funcioneaz n modul urmtor.
Starea iniial din care se ncepe analiza este starea corespunztoare simbolului de start al gramaticii.
Dac la un moment dat analizorul se gsete ntr-o stare s din care exist un arc etichetat cu a spre o
stare t i simbolul curent de pe irul de intrare este a T atunci analizorul se va deplasa pe irul de
intrare cu o poziie la dreapta i va trece n starea t. Dac din starea s exist un arc etichetat cu un
neterminal A spre starea t atunci analizorul trece n starea iniial corespunztoare neterminalului
A fr s avanseze pe irul de intrare. Dac se reuete s se ajung la starea final pentru A se va trece
n starea t ( se observ c n acest caz se consider c s-a "citit" A din irul de intrare). Dac din starea s
exist o -tranziie spre starea t atunci analizorul poate trece direct n stare t fr s se faca nici o
deplasare pe irul de intrare.
Ideea analizei sintactice predictive const din identificarea a simbolului curent de pe banda de
intrare cu nceputul unei producii pentru simbolul neterminal curent. Acest tip de abordare
funcionez dac diagrama care reprezint produciile gramaticii este determinist.
S considerm de exemplu gramatica pentru expresii aritmetice fr recursivitate stnga :
TE', ' +TE' | , T FT', T' *FT' | , F () | a.
Diagramele de tranziie corespunztoare sunt :

:
+---+ +---+ +-----+
| | T | | ' |+---+|
| 0 |-----| 1 |----|| 2 ||
| | | | |+---+|
+---+ +---+ +-----+


':
Irina Athanasiu 3/1/2002 Limbaje formale i automate

105
+---+ +---+ +---+ +-----+
| | + | | T | | '|+---+|
| 3 |-----| 4 |----| 5 |---|| 6 ||
| | | | | | |+---+|
+---+ +---+ +---+ +-----+
|


+---------------------------+
T:
+---+ +---+ +-----+
| | F | | T' |+---+|
| 7 |-----| 8 |----|| 9 ||
| | | | |+---+|
+---+ +---+ +-----+
T':
+----+ +----+ +----+ +------+
| | * | | F | | T'|+----+|
| 10 |-----| 11 |----| 12 |---|| 13 ||
| | | | | | |+----+|
+----+ +----+ +----+ +------+
|


+-------------------------------+
F:

+----+ +----+ +----+ +------+
| | ( | | | | ) |+----+|
| 14 |-----| 15 |----| 16 |---|| 17 ||
| | | | | | |+----+|
+----+ +----+ +----+ +------+
| a
+-------------------------------+

Acest grup de diagrame de tranziie prezint aparent dezavantajul existenei - tranziiilor care pare
s confere un caracter nedeterminist analizorului sintactic predictiv corespunztor acestor diagrame, dar
acest aspect poate s fie rezolvat simplu. De exemplu pentru ' se va alege n implementare o -
tranziie dac i numai dac simbolul care urmeaz la intrare nu este +, etc.
Diagramele de tranziie obinute direct din gramatica pot s fie n continuare simplificate prin
cteva transformri simple. De exemplu observnd ca n diagrama de tranziie pentru ' apare un arc
etichetat cu ' se pot face urmtoarele transformri :

':
+------------------------+
| |
V |
+---+ +---+ +---+ |
| | + | | T | | |
| 3 |-----| 4 |----| 5 |---+
| | | | | |
+---+ +---+ +---+ +-----+
| |+---+|
+--------------------- || 6 ||
|+---+|
+-----+
i apoi

Irina Athanasiu 3/1/2002 Limbaje formale i automate

106
':
+---------------+
| |
V |
+---+ +---+ |
| | + | | T |
| 3 |-----| 4 |---+
| | | |
+---+ +---+ +-----+
| |+---+|
+--------------------- || 6 ||
|+---+|
+-----+
Din
:
+---+ +---+ +-----+
| | T | | ' |+---+|
| 0 |-----| 1 |----|| 2 ||
| | | | |+---+|
+---+ +---+ +-----+
se obine :

: T
+---------------+
| |
V |
+---+ +---+ +---+ |
| | T | | + | | |
| 0 |-----| 3 |-----| 4 |---+
| | | | | |
+---+ +---+ +---+ +-----+
| |+---+|
+--------------------- || 6 ||
|+---+|
+-----+

i apoi pentru c strile 0 i 4 sunt echivalente se obine :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

107
: +
+---------------+ T + | T
| |
V |
+---+ +---+ |
| | T | | |
| 0 |-----| 3 |---+
| | | |
+---+ +---+ +-----+
| |+---+|
+----------- || 6 ||
|+---+|
+-----+

T : *
+---------------+ T F * T | F
| |
V |
+---+ +---+ |
| | F | | |
| 7 |-----| 8 |---+
| | | |
+---+ +---+ +------+
| |+----+|
+----------- || 13 ||
|+----+|
+------+
F:
F () | a
+----+ +----+ +----+ +------+
| | ( | | | | ) |+----+|
| 14 |-----| 15 |----| 16 |---|| 17 ||
| | | | | | |+----+|
+----+ +----+ +----+ +------+
| a


+-------------------------------+

Analizorul sintactic corespunztor acestor diagrame de tranziie este :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

108
#include "stdio.h"
#include "ctype.h"

int caracter_curent;

/*
prototipuri functii
*/

static void gasit(int t);
static void expr(void);
static void termen(void);
static void factor(void);


static void gasit(int t)
{
if (caracter_curent == t)
{ putchar(caracter_curent);
caracter_curent = getchar();
}
else
{ printf("\neroare \n");
exit(1);
}
}



/*
TE', ' +TE' | , + T | T
*/

static void expr()
{
termen();
while (1)
if (caracter_curent == '+')
{ gasit('+');
termen();
}
else break;
}

/*
T FT', T' *FT' | , T -> T * F | T
*/

static void termen()
{
factor();
while (1)
if (caracter_curent == '*')
{ gasit('*');
factor();
}
else break;
}

/*
Irina Athanasiu 3/1/2002 Limbaje formale i automate

109
F () | a
*/

static void factor()
{
if (caracter_curent == 'a')
gasit('a');
else
{ gasit('(');
expr();
gasit(')');
}
}


main()

{ caracter_curent = getchar();
expr();
putchar('\n');
}

Programul afieaz n ecou caracterele care sunt identificate drept corecte. n momentul n care se
gasete un caracter care nu mai corespunde se afieaz mesajul de eroare.
Se observ c abordarea anterioar presupune utilizarea unor proceduri recursive. Se poate ns
implementa o abordare nerecursiv prin utilizarea unei stive. Adic, prin simularea explicit a unui
automat cu stiv. Problema fundamental n timpul analizei predictive const din determinarea
produciei care va fi utilizat pentru neterminalul curent.
Dezavantajul analizei predictive const din faptul c prin transformarea gramaticilor i apoi prin
transformarea diagramelor se poate pierde semnificaia producilor ceea ce poate complica pn la
imposibil procesul de generare de cod.
4.1.1.1 Gramatici LL(1)

n cazul analizei LL(1) modelul analizorului este :

---------------------------------
banda de intrare ---------------------------------


| cap de citire
| | |
| | |
| | +-----------+
| | | analizor |
| |<----------| sintactic |---------- iesire
| | +-----------+
| | |
| | +-----------+
| | | tabela |
| | | de |
| | | analiza |
| | +-----------+

stiva

Irina Athanasiu 3/1/2002 Limbaje formale i automate

110
Este vorba de fapt de un automat cu stiv pentru care funcia de transfer m este memorat ntr-o tabel
de analiz. Pentru a favoriza construirea unui automat determinist se consider c pe banda de intrare
irul analizat este urmat de un simbol special care nu aparine gramaticii, pe care l vom nota cu $.
Existnd un mecanism de identificare a sfritului irului se extinde clasa imbajelor care pot s fie
acceptate de ctre automat. Stiva conine iniial simbolii S i $ unde S este simbolul de start al
gramaticii memorat n vrful stivei. n orice moment stiva conine o secven de simboli terminali i
neterminali. Tabela de analiza este o matrice M[A,a] unde A este un neterminal iar a este un terminal
sau simbolul $. Programul care simuleaz funcionarea analizorului sintactic funcionez n modul
urmtor. Fie X simbolul din vrful stivei i a simbolul curent pe banda de intrare. Exist trei posibiliti :

1. dac X = a = $ analiza s-a terminat cu succes;
2. dac X = a $ analizorul extrage simbolul a din vrful stivei i deplaseaz capul de citire pe banda
de intrare cu o poziie la dreapta;
3. dac X este un neterminal, analizorul va cerceta valoarea M[X,a]. Valoarea din intrarea respectiva
este fie o producie pentru neterminalul X fie o informaie de eroare. Dac de exemplu M[X,a] =
{X UVW}, simbolul X din vrful stivei va fi inlocuit cu UVW ( U este noul vrf al stivei).

Ca algoritm funcionarea analizorului poate s fie descris de urmtorul algoritm de simulare a unui
automat push down determinist:

Intrare un ir w i o tabela de analiz M pentru gramatica G.
Iesire dac w L(G), derivarea stng, altfel un mesaj de eroare.

Iniial configuraia automatului este w$ pe banda de intrare i S$ n stiv. Analizorul va afia
produciile aplicate pe masur ce evolueaz. Avnd n vedere c nu este necesar dect o singur stare
pentru unitatea de control a automatului aceasta nu mai este considerat explicit.

Irina Athanasiu 3/1/2002 Limbaje formale i automate

111
initializeaza vrful stivei
intitializeaza pozitie curenta pe banda de intrare
repeta
fie X simbolul din vrful stivei si a caracterul curent de pe banda de
intrare
daca X este un simbol terminal sau $
atunci
daca X = a
atunci
descarca stiva
actualizeaza pozitia curenta pe banda de intrare
altfel
eroare
exit

altfel /* X este un simbol neterminal */
daca M[X,a] contine X Y1 Y2 ... Yk
atunci
inlocuieste X din varful stivei cu Y1 Y2 ... Yk
afiseaza productia X Y1 Y2 ... Yk
altfel
eroare
exit


pana X = $ /* stiva este goala */

S relum exemplul gramaticii expresiilor aritmetice. Tabela de analiz corespunztoare acestei
gramatici este :

neterminal a + * ( ) $
----------+--------+--------+--------+--------+--------+--------|
| -> TE'| | | -> TE'| | |
----------+--------+--------+--------+--------+--------+--------|
' | |'->+TE'| | |' |' |
----------+--------+--------+--------+--------+--------+--------|
T |T -> FT'| | |T->FT' | | |
----------+--------+--------+--------+--------+--------+--------|
T' | |T' |T'->*FT'| |T' |T' |
----------+--------+--------+--------+--------+--------+--------|
F | F a | | |F->() | | |
----------------------------------------------------------------+

Pentru irul a + a * a rezult urmtoarele micri (stiva este reprezentata cu vrful la stnga):


Irina Athanasiu 3/1/2002 Limbaje formale i automate

112
Stiva Intrare Iesire
------------+-----------------------+----------------------
$ | a + a * a $ |
------------+-----------------------+----------------------
TE'$ | a + a * a $ | TE'
------------+-----------------------+----------------------
FT''$ | a + a * a $ | T FT'
------------+-----------------------+----------------------
aT''$ | a + a * a $ | F a
------------+-----------------------+----------------------
T''$ | + a * a $ |
------------+-----------------------+----------------------
'$ | + a * a $ | T'
------------+-----------------------+----------------------
+TE'$ | + a * a $ | ' +TE'
------------+-----------------------+----------------------
TE'$ | a * a $ |
------------+-----------------------+----------------------
FT''$ | a * a $ | T FT'
------------+-----------------------+----------------------
aT''$ | a * a $ | F a
------------+-----------------------+----------------------
T''$ | * a $ |
------------+-----------------------+----------------------
*FT''$| * a $ | T' *FT'
------------+-----------------------+----------------------
FT''$ | a $ |
------------+-----------------------+----------------------
aT''$ | a $ | F a
------------+-----------------------+----------------------
T''$ | $ |
------------+-----------------------+----------------------
'$ | $ | T'
------------+-----------------------+----------------------
$ | $ | '
-----------------------------------------------------------

Construcia tabelei de analiza este realizat cu ajutorul a doua funcii FIRST i FOLLOW.

FIRST : (N T)* P(T {})
FOLLOW : N P(T {$})

Dac w este un ir de simboli w (N T)*, FIRST(w) reprezint setul terminalelor cu care
ncep irurile derivate din w. Dac w * atunci FIRST(w).
Pentru un neterminal A, FOLLOW(A) reprezint mulimea terminalelor a care pot s apar
imediat dupa A ntr-o form propoziional; adica dac exist o derivare S * Aa atunci a
FOLLOW(A).
Pentru a calcula FIRST(X) pentru toi simbolii X din gramatic se aplic urmtoarele reguli
pn cnd nu se mai pot aduga simboli terminali sau pentru nici o mulime FIRST(X).


1. Dac X este un terminal atunci FIRST(X) = {X};
2. Dac exist o producie X atunci FIRST(X) = FIRST(X) {}
Irina Athanasiu 3/1/2002 Limbaje formale i automate

113
3. Dac exist o producie X Y1 Y2 ... Yk i a FIRST(Yi), FIRST(Y1), ...,
FIRST(Yi-1), (Y1 Y2 ... Yi-1 * ) atunci a FIRST(X). Dac FIRST(Yj), 1 j k, atunci
FIRST(X). (orice simbol terminal din FIRST(Y1) este inclus n FIRST(X). Dac Y1 *
atunci i orice simbol terminal din FIRST(Y2) este inclus n FIRST(X), etc.).

Putem s calculm funcia FIRST pentru orice ir X1 X2 ... Xm n modul urmtor. Se adaug la
FIRST(X1 X2 ... Xm) toi simbolii diferiti de din FIRST(X1). Se adaug apoi toi simbolii din
FIRST(X2) diferiti de dac FIRST(X1), etc. n final dac apare n FIRST(Xi), 1 i m, se
adauga la FIRST(X1 X2 ... Xm).
Pentru a calcula FOLLOW(A) pentru A N se aplic urmtoarele reguli n mod repetat
pn cnd nimic nu se mai poate adauga la mulimile FOLLOW:

1. $ face parte din FOLLOW(S) (S este simbolul de start al gramaticii);
2. Dac exist o producie A wB atunci FIRST() \ {} FOLLOW(B);
3. Dac exist o producie de forma A w B sau o producie A wB i FIRST() ( *
) atunci FOLLOW(A) FOLLOW(B) (B poate s apar i n alte contexte).

S considerm de exemplu din nou gramatica fr recursivitate stnga pentru expresii aritmetice:

TE', ' +TE' | , T FT', T' *FT' | ,
F () | a.

FIRST() = FIRST(T) = FIRST(F) = {(,a}
FIRST(E') = {+,}
FIRST(T') = {*,}

FOLLOW() = FOLLOW(') = {),$}
FOLLOW(T) = FOLLOW(T') = {+,),$}
FOLLOW(F) = {+,*,),$}

Pentru construirea tabelei de analiz se utilizeaz urmtoarele reguli:

Dac A w este o producie i a FIRST(w) atunci dac simbolul pe banda de intrare este a
analizorul trebuie s nlocuiasc n stiv pe A cu w.
Dac w * atunci A este nlocuit n stiv cu w numai dac a FOLLOW(A) (n particular
simbolul a poate s fie $).

Rezult urmtorul algoritm pentru construcia tabelei :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

114
initializare matrice M
pentru fiecare p = A w P executa
pentru fiecare a FIRST(w) T executa
M[A,a] = M[A,a] {A w}



daca FIRST(w)
atunci
pentru fiecare b FOLLOW(A) executa /* b T {$} */
M[A,b] = M[A,b] {A w}




Aplicnd acest algoritm asupra gramaticii expresiilor aritmetice va rezulta tabela cu care a fost
ilustrat funcionarea analizei predictive.
S considerm ns i urmtoarea gramatic : S i t S S' | a, S' e S | , b. ( este
vorba de gramatica care descrie instruciunea if). Pentru aceast gramatic rezult urmtoarea tabel de
analiz:

neterminal a b e i t $
----------+--------+--------+--------+---------+--------+--------|
S | S -> a | | |S->iEtSS'| | |
----------+--------+--------+--------+---------+--------+--------|
S' | | |S' -> | | |S' > |
| | |S' -> eS| | | |
----------+--------+--------+--------+---------+--------+--------|
| | > b | | | | |
-----------------------------------------------------------------+

M[S',e] = {S' eS, S' } deoarece FOLLOW(S') = {e, $}. Se tie c n aceast form gramatica
este ambigu i ambiguitatea se manifest prin alegerea ce trebuie s fie fcut cnd se ntlnete
simbolul e (else). Soluia corect este de a alege producia S' eS (aceast alegere corespunde asocierii
cuvintului else cu cel mai recent then). Se observ c alegerea permanent a produciei S' ar
impiedica aducerea terminalului e (else) n vrful stivei ceea ce nu poate conduce la o evoluie corect.
O gramatic pentru care n tabela de analiz nu exist intrri cu mai multe alternative se spune
c este o gramatic LL(1) (primul L se refera la parcurgerea irului de intrare de la stnga (Left) la
dreapta, al doilea L pentru utilizarea derivrii stnga (Left), iar 1 se refer la utilizarea unui terminal
pentru a adopta o decizie de analiza).
Gramaticile LL(1) sunt gramatici neambigue, nerecursive stnga i factorizate. Se poate arta c
o gramatic G este LL(1) dac i numai dac pentru oricare doua producii de forma A , A ,
cu sunt satisfacute urmtoarele condiii :

1. FIRST() FIRST() =
2. dac * atunci FIRST() FOLLOW(A) = iar dac * atunci FIRST() FOLLOW(A)
= .

Gramatica pentru expresii aritmetice (fr recursivitate stnga) este LL(1) n timp ce gramatica
considerat pentru instructiunea if nu este LL(1).
Irina Athanasiu 3/1/2002 Limbaje formale i automate

115
Se pune problema cum se poate realiza o analiz predictiv pentru un limbaj descris de o
gramatic care nu este LL(1). O solutie este de a transforma gramatica astfel nct s devin LL(1). n
anumite cazuri (ca de xemplu n cazul anterior al gramaticii pentru limbajul corespunztor
instruciunilor if) se poate face o "potrivire" a tabelei M, dar nu exist o regul general de transformare a
matricii de analiz astfel nct intrrile multiple s poat s fie nlocuite cu intrri simple.
Transformarea suferit de o gramatic pentru a deveni LL(1) o poate face ns dificil de
recunoscut. De obicei analiza predictiv este utilizat pentru instruciuni (nu pentru expresii).
4.1.1.2 Tratarea erorilor n analiza predictiv

Existena n stiv a terminalelor i neterminalelor pe care analizorul se ateapt s le gseasc pe
banda de intrare simplific mult problema diagnosticrii erorii. O eroare este detectat n timpul
analizei dac n vrful stivei se gsete un terminal care nu coincide cu terminalul curent de pe banda
de intrare, sau dac pentru neterminalul din vrful stivei (fie el A) i terminalul curent de pe banda de
intrare (fie el a) n tabela M nu exist o producie (M[A,a] = ).
Problema cea mai dificil nu este ns identificarea erorii ci stabilirea modului n care analiza
trebuie s continue dup identificarea unei erori. Dac o astfel de continuare nu ar fi posibil atunci la
prima eroare ntlnit compilatorul trebuie s abandoneze analiza. O metod posibil de continuare n caz
de eroare const din ignorarea de pe banda de intrare a simbolilor care urmeaz pn la ntlnirea unui
simbol dintr-o mulime numit mulime de sincronizare. Aceast mulime se alege astfel nct analizorul
s poat s decid ct mai rapid modul de continuare pentru erorile cele mai frecvente. Se utilizeaz n
acest scop cteva reguli cu caracter euristic ca de exemplu :

1. Pentru un neterminal A aflat n vrful stivei mulimea de sincronizare va conine simbolii din
FOLLOW(A). Dac la ntlnirea unui astfel de simbol pe banda de intrare se descarc stiva, exist
o bun ans pentru continuarea analizei, ca i cum s-ar fi reuit identificarea simbolului A;
2. Pentru limbaje de programare care au caracter de terminare a instruciunilor (ca de exemplu ;
pentru limbajul C) acestea vor fi considerate n mulimile de sincronizare pentru neterminalele care
corespund instruciunilor. Pentru orice instruciune cuvintele cheie care nu fac parte din setul
FOLLOW(instruciune) pot s fie introduse n mulimea de sincronizare. n acest caz dac de
exemplu dup o instruciune de atribuire lipsete terminalul care indic terminarea acesteia n
analiza se poate trece la cuvintul cheie care reprezint nceputul instruciunii urmtoare, etc. Pe de
alt parte n general pentru o gramatic care descrie un limbaj de programare exist o ierarhie a
construcilor sintactice. De exemplu expresiile apar n instruciuni care apar n blocuri care apar n
funcii, etc. Rezult ca mulimea de sincronizare corespunztoare unei structuri sintactice va
conine simbolii corespunztori structurilor superioare. Astfel, se vor aduga cuvintele cheie cu care
ncep instruciunile la mulimea de sincronizare pentru neterminalele care genereaz expresii.
3. Dac se adaug simbolii din FIRST(A) la mulimea de sincronizare pentru A, atunci se poate
relua analiza corespunztoare neterminalului A cu recunoaterea unui terminal din FIRST(A) la
intrare. Utiliznd n caz de eroare dac este posibil pentru neterminalul aflat n vrful stivei o -
producie se poate amna diagnosticarea erorii.
4. Dac pentru terminalul din vrful stivei nu exist o coresponden n irul de intrare se poate
afia un mesaj corespunztor renunndu-se n continuare la simbolul respectiv.

Utiliznd funciile FIRST i FOLLOW se poate completa tabela M cu informaiile referitoare la
mulimea simbolilor de sincronizare. De exemplu pentru tabela de analiz corespunztoare gramaticii
expresiilor aritmetice rezult:
Irina Athanasiu 3/1/2002 Limbaje formale i automate

116







| a | + | * | ( | ) | $ | sinc |
----+--------+--------+--------+------+--------+--------+------|
| -> TE'| | |->TE'| sinc | sinc | ) $ |
----+--------+--------+--------+------+--------+--------+------|
' | |'->+TE'| | |' |' | ) $ |
----+--------+--------+--------+------+--------+--------+------|
T |T -> FT'| sinc | |T->FT'| sinc | sinc |+ ) $ |
----+--------+--------+--------+------+--------+--------+------|
T' | |T'-> |T'->*FT'| |T' -> |T' -> |+ ) $ |
----+--------+--------+--------+------+--------+--------+------|
F | F -> a | sinc | sinc |F->()| sinc | sinc |+*)$ |
---------------------------------------------------------------+

Mulimile sinc sunt construite pornind de la funcia FOLLOW. Cu ajutorul unei tabele de acest tip
analiza se va executa n modul urmtor . Dac M[A,a] nu conine nici o valoare atunci se avanseaz
peste simbolul curent (a). Dac M[A,a] = sinc atunci se descarc vrful stivei pentru a continua analiza cu
ce urmeaz dup simbolul din vrful stivei. Dac terminalul din vrful stivei nu se potrivete cu
terminalul de la intrare se descarc terminalul din vrful stivei. De exemplu pentru secven de intrare
: )a * + a se obine :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

117
Stiva Intrare Iesire
------------+-----------------------+----------------------
$ | ) a * + a $ | eroare, ) FIRST()
------------+-----------------------+----------------------
E$ | a * + a $ |
------------+-----------------------+----------------------
TE'$ | a * + a $ | TE'
------------+-----------------------+----------------------
FT''$ | a * + a $ | T FT'
------------+-----------------------+----------------------
aT''$ | a * + a $ | F a
------------+-----------------------+----------------------
T''$ | * + a $ |
------------+-----------------------+----------------------
*FT''$| * + a $ | T' *FT'
------------+-----------------------+----------------------
FT''$ | + a $ | eroare
------------+-----------------------+----------------------
T''$ | + a $ | T'
------------+-----------------------+----------------------
'$ | + a $ | ' +TE'
------------+-----------------------+----------------------
+T''$ | + a $ |
------------+-----------------------+----------------------
T''$ | a $ | T'
------------+-----------------------+----------------------
'$ | $ | '
------------+-----------------------+----------------------
$ | $ |
-----------------------------------------------------------

Se observ c pentru nceput se caut un simbol din FIRST() pentru a ncepe recunoaterea
ignorindu-se astfel terminalul ) i nu se descarc stiva. Pentru M[F,+] = sinc se va descrca stiva.

4.1.2 Analiza sintactica bottom-up
4.1.2.1 Analiza sintactica de tip deplaseaza i reduce

Analiza sintactica de tip bottom-up ncearc s construiasc un arbore de derivare pentru un ir de
intrare dat pornind de la frunze spre rdcina aplicnd metoda "handle pruning". Adic trebuie s se
construiasc n stiv partea dreapt a unei producii. Selecia produciei construite se face pe baza
"nceputurilor" care reprezint nceputuri posibile de iruri derivate conform produciei respective.
4.1.2.2 Implementarea analizei sintactice bottom-up deplaseaz i reduce

Pentru a utiliza aceast metod trebuie s fie rezolvate dou probleme :

1. localizarea nceputului;
2. alegerea produciei (dac exist mai multe producii cu aceeai parte dreapta).

Algoritmul de analiz sintactic de tip deplaseaz i reduce realizeaz simularea unui automat cu
stiv. Din irul de intrare se mut simboli terminali n stiva pn cnd n vrful stivei se obine un
Irina Athanasiu 3/1/2002 Limbaje formale i automate

118
nceput care este redus la partea stnga a uneia dintre produciile corespunztoare gramaticii. Dac
iniial n stiv se gsete numai simbolul $ iar pe banda de intrare se gsete irul w$ n final dac w
aparine limbajului acceptat de analizor, n stiv se va gsi $S (cu S vrful stivei, S - simbolul de start al
gramaticii) iar pe banda de intrare capul de citire este poziionat pe simbolul $. S considerm de
exemplu aciunile necesare pentru recunoaterea irului a + a * a pentru gramatica expresiilor aritmetice :
+ | * | a.

stiva | intrare | actiune
-------------------+------------------+--------------------
$ | a + a * a $ | deplaseaza
-------------------+------------------+--------------------
$a | + a * a $ | reduce a
-------------------+------------------+--------------------
$ | + a * a $ | deplaseaza
-------------------+------------------+--------------------
$ + | a * a $ | deplaseaza
-------------------+------------------+--------------------
$ + a | * a $ | reduce a
-------------------+------------------+--------------------
$ + | * a $ | deplaseaza
-------------------+------------------+--------------------
$ + * | a $ | deplaseaza
-------------------+------------------+--------------------
$ + * a | $ | reduce a
-------------------+------------------+--------------------
$ + * | $ | reduce *
-------------------+------------------+--------------------
$ + | $ | reduce +
-------------------+------------------+--------------------
$ | $ | succes
-----------------------------------------------------------

Au fost utilizate 4 tipuri de operaii :

1. deplasare - presupune mutarea simbolului terminal curent de pe banda de intrare n vrful stivei;
2. reduce - n vrful stivei se gsete un nceput care va fi nlocuit cu partea stnga a produciei
respective;
3. succes - s-a ajuns la sfritul irului i coninutul stivei este $S;
4. eroare.

Avantajul utilizrii stivei const din faptul c un nceput se formeaz ntotdeauna n vrful stivei (i
deci dac nu s-a format n vrful stivei un nceput atunci acesta nu trebuie s fie cutat n alt parte). S
considerm dou situaii care pot s apar n cazul derivrilor dreapta :

1. S * A z * B y z * y z
2. S * B x A z * B x y z * x y z

cu A B , A y, B , x,y,z T*, ,, (T N)+

n primul caz ( S * A z) reducerea inseamna :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

119
stiva intrare

$ yz$ se reduce
$B yz$ se copiaza y
$By z$ se reduce By
$A z$ se copiaza z
$Az $ se reduce aAz
$S

n al doilea caz ( S * a B x A z).

stiva intrare

$ xyz$ se reduce
$B xyz$ se copiaza x
$Bx yz$ se copiaza y
$Bxy z$ se reduce y
$BxA z$ se copiaza z
$BxAz $ se reduce aBxAz
$S

Se observ c ntotdeauna nceputul utilizat pentru reducere este n vrful stivei.
Setul prefixelor derivrilor dreapta ce pot s apara n vrful stivei n analiza unui analizor de tip
deplaseaz reduce se numete setul prefixelor viabile pentru gramatica respectiv.
Exist gramatici independente de context pentru care nu se poate utiliza o analiz de tip
deplaseaz i reduce, deoarece se poate ajunge fie n situaii n care nu se tie dac trebuie s se
efectueze o deplasare sau o reducere (conflict reducere / deplasare) respectiv nu se tie care dintre
variantele de reducere posibile trebuie s fie luat n considerare (conflict reduce / reduce). S
considerm de exemplu din nou gramatica pentru instruciuni, n forma ambigu:

instr if expresie then instr |
if expresie then instr else instr |
alte_instr

Dac se ajunge n configuraia :

stiva intrare

...if expresie then instr else ... $

nu putem s hotrm dac if expresie then instr este un nceput indiferent de ce mai conine stiva.
S observa ca n acest caz avem un conflict deplaseaza / reduce. Aceast gramatic i n general orice
gramatic ambigu nu permite o analiz sintactic ascendent determinist. Pentru acest caz particular
dac hotarm c n situaia unui conflict deplaseaza / reduce are prioritate deplasarea atunci se va
ajunge la o execuie corect a analizei. S considerm i o gramatica care descrie instruciuni de atribuire
i apeluri de funcii. n expresiile care apar n instruciunea de atribuire i n lista de parametri actuali ai
unei proceduri pot s apar variabile simple sau elemente de variabilele indexate pentru care se
utilizeaz paranteze obinuite. S considerm c analizorul lexical produce pentru atomul lexical
identificator simbolul terminal id. Se obine urmtoarea gramatic :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

120
instruciune id(lista_par) | expresie := expresie
lista_par lista_par, id | id
expresie id(lista_expr) | id
lista_expr lista_expr, expresie | expresie

S considerm o instruciune care ncepe cu A(i,j) i deci care este de forma id(id,id). Se observ c
se ajunge n configuraia:

stiva intrare

id ( id , id ) ...

Se observ c nu se tie care este producia cu care se face reducerea pentru c simbolul neterminal
la care se face reducerea depinde de tipul variabilei A (variabila indexata sau funcie). Rezult ca a aprut
un conflict reduce-reduce. Aceasta informaie poate s fie obinut din tabela de simboli. O soluie const
din modificarea analizorului lexical care poate s furnizeze terminale diferite pentru variabile indexate i
nume de funcii. n acest caz alegerea reducerii se va face n funcie de tipul identificatorului care precede
paranteza.


Irina Athanasiu 3/1/2002 Limbaje formale i automate

121
4.1.2.3 Analiza sintactica de tip LR(k)

LR(k) este o metod de analiz ascendent al crui nume are urmtoarea semnificaie : primul L
indic sensul parcurgerii - stnga, dreapta, litera R indic faptul c derivarea este dreapta iar k indic
numrul de atomi lexicali necesari pentru o alegere corecta a unui nceput stiv. Avantajele metodei
LR(k) sunt :

se pot construi analizoare de tip LR pentru toate construciile din limbajele de programare care pot s
fie descrise de gramatici independente de context;
clasa limbajelor care pot s fie analizate descendent n mod determinist este o submulime proprie a
limbajelor care pot s fie analizate prin tehnici LR;
detectarea erorilor sintactice se face foarte aproape de atomul lexical n legtura cu care a aparut
eroarea.

Dezavantajul major al acestei metode - volumul mare de calcul necesar pentru implementarea unui
astfel de analizor fr aportul unui generator automat de analizoare sintactice.
S considerm din nou structura unui automat cu stiv.

---------------------------------
banda de intrare ---------------------------------


| cap de citire
| | |
| | |
| | +-----------+
| | | analizor |
| |<----------| sintactic |---------- iesire
| | +-----------+
| | |
| | +-----------+
| | | tabela |
| | | de |
| | | analiza |
| | +-----------+

Ca i n cazul analizei LL particularizarea limbajului se face prin intermediul tebelei de analiz care
conine funcia m.
nainte de a ncepe discuia referitoare la modul de construire a tabelelor de analiza este bine
s reamintim cteva definiii. i anume se numete nceput al unei forme propoziionale partea dreapt a
unei producii care dac este nlocuit cu partea stnga produce forma propoziional anterioar n
irul formelor propoziionale obinute ntr-o derivare dreapta. Un prefix viabil este un subir cu
care poate ncepe o form propoziional.
Problema central n execuia algoritmului const din identificarea momentului n care n vrful
stivei a fost obinut un nceput. Desigur, o variant posibil este explorarea complet a stivei la
fiecare pas. Evident, o astfel de abordare este ineficient. n cazul analizei de tip LR(k) se utilizeaz
pentru identificarea capetelor un dispozitiv similar cu un automat finit. Rolul acestui automat este de a
controla activitatea de recunoatere a nceputurilor. S considerm de exemplu din nou gramatica
expresiilor aritmetice :


Irina Athanasiu 3/1/2002 Limbaje formale i automate

122
(1) + T
(2) T
(3) T T * F
(4) T F
(5) F ()
(6) F a

Putem s considerm diagrama de tranziii corespunztoare acestor producii:

+------+ +------+ +------+
+----+ | | + | | T |+----+|
| |---| I1 |--- | I6 |--- || I9 ||
| | | | | | |+----+|
| | +------+ +------+ +------+
| | +------+ +------+ +-------+
| | T |+----+| * | | F |+-----+|
| |---|| I2 ||--- | I7 |--- || I10 ||
| | |+----+| | | |+-----+|
| | +------+ +------+ +-------+
| | +------+
| | F |+----+|
| I0 |---|| I3 ||
| | |+----+|
| | +------+
| | +------+ +------+ +-------+
| | ( | | | | ) |+-----+|
| |---| I4 |--- | I8 |--- || I11 ||
| | | | | | |+-----+|
| | +------+ +------+ +-------+
| | +------+
| | a |+----+|
| |---|| I5 ||
| | |+----+|
| | +------+
+----+

S urmrim secvena de stri prin care se trece pentru irul de intrare a * a + a.

Irina Athanasiu 3/1/2002 Limbaje formale i automate

123
+------+ +------+ a fost recunoscuta n starea 0 partea
| | a |+----+| dreapta a productiei F a, cu alte
| I0 |---|| I5 || cuvinte sirul de intrare este de forma
| | |+----+| F * a + a (deplasare pentru a, urmata
+------+ +------+ de reducere cu F a)

+------+ +------+ a fost recunoscuta n starea 0 partea
| | F |+----+| dreapta a productiei T F, cu alte
| I0 |---|| I3 || cuvinte sirul de intrare este de forma
| | |+----+| T * a + a (reducere pentru T F)
+------+ +------+




+------+ +------+ +------+
| | T | | * | |n acest moment la
| I0 |---| I2 |--- | I7 |intrare urmeaz a + a
| | | | | |
+------+ +------+ +------+

+------+ +------+ +------+ +------+
| | T | | * | | a |+----+|a fost recunos-
| I0 |--- | I2 |---| I7 |-- || I5 ||cuta n starea 7
| | | | | | |+----+|partea dreapta a
+------+ +------+ +------+ +------+productiei F a

Cu alte cuvinte n starea 7 urmeaz irul de intrare F + a

+------+ +------+ +------+ +------+
| | T | | * | | F |+----+|
| I0 |--- | I2 |---| I7 |--- || I10||
| | | | | | |+----+|
+------+ +------+ +------+ +------+


A fost recunoscut n starea 0 partea dreapt a produciei T T * F (reducere).

+------+ +------+ a fost recunoscuta n starea 0 partea
| | T |+----+| dreapta a productiei T,
| I0 |---|| I2 || la intrare urmeaz sirul + a.
| | |+----+|
+------+ +------+


+------+ +------+ +------+ +------+
| | | | + | | a |+----+|a fost recunos-
| I0 |--- | I1 |--- | I6 |---|| I5 ||cuta n starea 6
| | | | | | |+----+|partea dreapta a
+------+ +------+ +------+ +------+productiei F a

Evoluia continu pn la obinerea situaiei :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

124
+------+ +------+
| | | |
| I0 |--- | I1 |
| | | |
+------+ +------+

Avnd n vedere aceasta evolutie diagrama de tranziii poate s fie reprezentat i sub forma
urmtoare (n care se evideniaz toate nceputurile posibile) :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

125

+------+ +------+
+----+ | | + +----+ T |+----+| *
| |---| I1 |---- | |----|| I9 ||--- I7
| | | | | | |+----+|
| | +------+ | | +------+
| | | | F
| | | I6 |--- I3
| | | | (
| | | |--- I4
| | | | a
| | | |--- I5
| | +----+
| | +------+ +-------+
| | T |+----+| * +----+ F |+-----+|
| |---|| I2 ||--- | |---- || I10 ||
| | |+----+| | | |+-----+|
| | +------+ | I7 | +-------+
| | | | (
| | | |---- I4
| I0 | | | a
| | | |---- I5
| | +------+ +----+
| | F |+----+|
| |---|| I3 ||
| | |+----+|
| | +------+
| | - (
| | \ / +-------+
| | ( +----+ +----+ ) |+-----+|
| |---| I4 |---- | |---- || I11 ||
| | +----+ | | |+-----+|
| | | \\ | I8 | + +-------+
| | a | \\ T | |--- I6
| | V \\ | |
| | +------+\\ +----+
| | a |+----+| \\- I2
| |---|| I5 || \
| | |+----+| \ F
+----+ +------+ \- I3

Se utilizeaz convenia c la fiecare reducere se revine n starea anterioar lanului de arce
corespunztoare nceputului identificat executndu-se o alt tranziie. Desenul anterior poate s fie
interpretat ca reprezentnd un automat finit care accept nceputuri. S urmrim secven de stri prin
care se poate trece pentru irul de intrare a * a + a :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

126

a
0 --------- 5
\\\ F
\\ ------ 3
\\ T * a
\------ 2 ---- 7 ----- 5
\ \ F
\ ----- 10
\ E + a
--- 1 ---- 6 ----- 5
\\ F
\----- 3
\ T
---- 9

Se observ c pentru primul simbol a se ajunge n starea 5 n care s-a recunoscut partea dreapt a
produciei F a, este ca i cum s-ar fi aplicat la intrare irul F * a + a, similar n acest caz se poate
considera c s-a recunoscut partea dreapt a produciei T F. Dup T se gsete la intrare * apoi a,
ajungndu-se n starea 5 n care se recunoate din nou partea dreapta a produciei F a. n acest
moment n starea 10 s-a citit la intrare irul T * F deci se poate aplica pentru reducere producia T T *
F. Un analizor sintactic LR realizeaz simularea acestor recunoateri de nceputuri memornd n stiv
strile prin care se trece ntr-o recunoatere ca cea fcut anterior.
Coninutul stivei la un moment dat este de forma s0 X1 s1 X2 s2 ... Xn sn, unde vrful stivei este
sn ( de fapt n stiv este suficient s se memoreze numai starile nu i simboli Xi). Simbolii Xi
reprezint simboli din gramatica iar si reprezint stri ale automatului care recunoate capete. Pe baza
informaiei specificate de starea din vrful stivei i a simbolului curent de pe banda de intrare se determin
micarea urmtoare efectuat de ctre analizor.
Tabela de analiza este formata din doua parti : tabela de aciuni i tabela goto. Pentru o
combinatie stare , simbol de intrare : sn, a, actiune[sn,a] poate avea urmtoarele valori :

deplasare n starea s (se copiaz terminalul curent de pe banda de intrare n stiv i se trece n starea
s).
reduce pe baza productiei A , noua stare find determinat din tabela goto.
succes
eroare

Pentru o combintie (si, Xi), Xi N, goto[si, Xi] este starea automatului de recunoatere a
nceputurilor n care se ajunge dac n starea si un nceput a fost redus la Xi.
Configuraia unui analizor LR este dat de coninutul stivei i cel al benzii de intrare. Deoarece
pe tot parcursul analizei automatul cu stiv se gsete n aceai stare, aceasta nu mai este prezentata
explicit. Deci o configuraie este de forma :

(s0 X1 s1 X2 ... Xm sm, ai ai+1 ... an$)

unde X1 X2 ... Xm ai ai+1 ... an reprezint o form propoziional obinuta dintr-o derivare dreapta
dac irul aflat iniial pe banda de intrare face parte din limbaj. Urmtoarea micare a analizorului depinde
de ai i sm i este descris de actiune[sm,ai]. Modificrile posibile pentru configuraia automatului pot s
fie :

dac aciune[sm,ai] = deplasare s, se obine noua configuraie :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

127

(s0 X1 s1 X2 ... Xm sm ai s, ai+1 ... an$)

dac aciune[sm,ai] = reduce pe baza A , se obine configuraia :

(s0 X1 s1 X2 ... Xm-r sm-r A s , ai ai+1 ... an$)

unde s = goto[sm-r,A] iar r este lungimea capatului utilizat pentru reducere. Se observ ca
s-au eliminat 2 * r simboli din stiv, starea nou din vrful stivei fiind sm-r. Se introduce apoi n
stiva neterminalul A (partea stnga a produciei) i starea obinuta pentru sm-r i A din tabela
goto (s = goto[sm-r, A]).

dac aciune[sm,ai] = acc atunci analiza se ncheie.
dac aciune[sm,ai] = eroare nseamn c s-a diagnosticat o eroare.

Algoritmul general de analiza LR este :

Intrare un ir de intrare w i o tabel de analiz LR.
Iesire dac w L(G) este o propoziie derivata n G atunci se va obine lista produciilor aplicate
ntr-o derivare dreapta, altfel se obine un mesaj de eroare corespunztor.

pozitioneaza ip pe inceputul sirului w$ si s0 n stiva.
repeta
fie s simbolul din vrful stivei si a simbolului de
intrare curent
dac actiune[s,a] = deplaseaza s'
atunci
memoreza a si s' n stiva
ip++
altfel
dac actiune[s,a] = reduce A
atunci
extrage 2 * || simboli din stiva
fie s' noul vrf al stivei
memoreaza A n stiva
memoreaza goto[s',A] n stiva
afiseaza producia A
altfel
dac actiune[s,a] = acc
atunci return
altfel eroare



pn false

S considerm de exemplu gramatica expresiilor artimetice :



Irina Athanasiu 3/1/2002 Limbaje formale i automate

128
(1) + T
(2) T
(3) T T * F
(4) T F
(5) F ()
(6) F a

S considerm c vom utiliza tabela de analiz:

| actiune | goto
| |
stare | a | + | * | ( | ) | $ | | T | F |
-------+---+---+---+---+---+---+---+---+---| i - reprezint
0 |s5 | | |s4 | | | 1 | 2 | 3 | deplasare si
-------+---+---+---+---+---+---+---+---+---| starea
1 | |s6 | | | |acc| | | | urmtoare i
-------+---+---+---+---+---+---+---+---+---| rj - reprezint
2 | |r2 |s7 | |r2 |r2 | | | | reducerea cu
-------+---+---+---+---+---+---+---+---+---| producia j
3 | |r4 |r4 | |r4 |r4 | | | | acc - reprezint
-------+---+---+---+---+---+---+---+---+---| succes
4 |s5 | | |s4 | | | 8 | 2 | 3 | blanc - reprezint
-------+---+---+---+---+---+---+---+---+---| eroare
5 | |r6 |r6 | |r6 |r6 | | | |
-------+---+---+---+---+---+---+---+---+---|
6 |s5 | | |s6 | | | | 9 | 3 |
-------+---+---+---+---+---+---+---+---+---|
7 |s5 | | |s4 | | | | | 10|
-------+---+---+---+---+---+---+---+---+---|
8 | |s6 | | |s11| | | | |
-------+---+---+---+---+---+---+---+---+---|
9 | |r1 |s7 | |r1 |r1 | | | |
-------+---+---+---+---+---+---+---+---+---|
10 | |r3 |r3 | |r3 |r3 | | | |
-------+---+---+---+---+---+---+---+---+---|
11 | |r5 |r5 | |r5 |r5 | | | |
-------------------------------------------+

Tabela goto[X,a] este coninuta n tabela actiune[X,a] pentru a T. Fie irul de intrare a * a + a.
Evoluia algoritmului de analiz este:

Irina Athanasiu 3/1/2002 Limbaje formale i automate

129
stiva | intrare | actiune
---------------+------------+-----------------------------------
0 | a * a + a $| deplasare
---------------+------------+-----------------------------------
0 a 5 | * a + a $| reduce cu F a (6), goto[0,F]=3
---------------+------------+-----------------------------------
0 F 3 | * a + a $| reduce cu T F (4), goto[0,T]=2
---------------+------------+-----------------------------------
0 T 2 | * a + a $| deplaseaza
---------------+------------+-----------------------------------
0 T 2 * 7 | a + a $| deplaseaza
---------------+------------+-----------------------------------
0 T 2 * 7 a 5 | + a $| reduce cu F a (6),goto[7,F]=10
---------------+------------+-----------------------------------
0 T 2 * 7 F 10| + a $| reduce cu T T * F (3)
---------------+------------+-----------------------------------
0 T 2 | + a $| reduce cu T (2), goto[0,]=1
---------------+------------+-----------------------------------
0 1 | + a $| deplaseaza
---------------+------------+-----------------------------------
0 1 + 6 | a $| deplaseaza
---------------+------------+-----------------------------------
0 1 + 6 a 5 | $| reduce cu F a (6), goto[6,F]=3
---------------+------------+-----------------------------------
0 1 + 6 F 3 | $| reduce cu T F (3), goto[6,T]=9
---------------+------------+-----------------------------------
0 1 + 6 T 9 | $| reduce cu + T (0)
---------------+------------+-----------------------------------
0 1 | $| succes
----------------------------------------------------------------

Problema cea mai dificil este desigur modul n care se construiesc tabelele de analiz. Se
poate face urmtoarea observaie - evoluia analizorului urmrete recunoaterea nceputului din
vrful stivei automatului. Dar o astfel de recunoatere poate s fie realizat de ctre un automat finit puin
modificat. Simbolii de stare din stiv reprezint de fapt strile unui astfel de automat. Informaia din
vrful stivei codific de fapt tot ce se gsete n stiv din punctul de vedere al nceputului construit. Se
observ c deosebirea fundamental ntre analiza LL i analiza LR este c pentru analiza LL(k) pe baza
a k atomi lexicali trebuie "ghicita" producia care se poate aplica pentru un simbol neterminal dat, pentru
analiza LR(k) este cunoscut partea dreapta a productiei i trebuie "ghicita" producia pe baza
urmtorilor k atomi lexicali care urmeaz.
n cele ce urmeaz prezentam cteva metode de construire a tabelelor de analiza pentru analiza
LR(1).
4.1.2.3.1 Analiza SLR

Cea mai simpl metod de construire a tabelelor de analiza LR este metoda SLR (simple LR).
Un element LR(0) pentru o gramatic G este o producie avnd un punct intercalat ntre
simbolii parii dreapta ai produciei. Astfel din producia A XYZ rezult patru elemente : [A
.XYZ], [A X.YZ], [A XY.Z], [A XYZ.]. Ideea utilizrii acestor elemente este c pentru a se
recunoate nceputul XYZ se vor aduce pe rnd n vrful stivei prefixele X, XY, XYZ. Producia A
produce un singur element [A .]. Un element poate s fie reprezentat de o
pereche de numere. Primul reprezint numrul productiei, al doilea numr este poziia punctului.
Semnificaia unui element este ct s-a recunoscut (vzut) din partea dreapta a unei producii. Ideea
Irina Athanasiu 3/1/2002 Limbaje formale i automate

130
de baza este construirea unui automat finit determinist care s stie s recunoasc elemente LR. Se
grupeaz elementele n mulimi care reprezint strile unui automat finit nedeterminist care recunoate
prefixe viabile. Gruparea acestor elemente se face pe baza unui algoritm de construcie a
subseturilor de tipul celor utilizate pentru construirea automatului finit determinist echivalent unui
automat finit nedeterminist dat.
O colecie a mulimilor de elemente LR(0) numit mulime canonic de elemente LR(0)
reprezint punctul de plecare pentru construcia tabelelor de analiza. Pentru aceasta construcie se
utilizeaz o gramatic modificat G', doua funcii : nchidere i goto i o procedur numit elemente.
Gramatica G' se obine din G prin utilizarea unui alt simbol de start al gramaticii S' i a
unei producii S' S care permite recunoaterea strii de acceptare prin utilizarea n reducere a
acestei producii.
Dac I este o mulime de elemente pentru o gramatica G, atunci inchidere(I) este o mulime de
elemente construite din I utiliznd urmtoarea funcie :

functia inchidere(I) este
C = I
repeta
C' = C
pentru fiecare A a . B B C executa /* B N */
fie B o productie pentru B
C = C { [B .]}

pna C = C'
rezultat C


Dac A . B face parte din inchidere(I) la un moment dat n procesul de analiza, urmeaz s
gasim la intrare un ir derivat din B. Corespunztor dac B este o producie, atunci n irul de
intrare ne ateptm s gsim un ir derivat din . De exemplu pentru gramatica modificat a
expresiilor aritmetice :

'
+ T | T
T T * F | F
F () | a

pornind de la setul I = {[' .]} se obine inchidere(I) :

' ., . + T, .T, T .T * F, T .F
F .(), F .a

n general pentru o mulime T de elemente se poate face mprirea acestora n doua clase :

1. elemente care formeaz nucleul, din care se pot genera alte elemente. n aceasta clasa intr
elementul S' .S i toate celelalte elemente din I care nu au punct pe prima poziie a prtii dreapta;
2. elemente care nu fac parte din nucleu i care au punct pe prima poziie a prii dreapta (cu excepia
elementului S' .S).

Irina Athanasiu 3/1/2002 Limbaje formale i automate

131
Se observ c orice element care nu face parte din nucleu poate s fie generat prin operaia de
nchidere dintr-un element din nucleu. Corespunztor este suficienta memorarea numai a
elementelor din nucleu (celelalte elemente putind s fie generate prin operatia de inchidere).

functia goto(I,X) este
fie J = {[A aX.B] | [A a.XB] I}
rezultat inchidere(J)



Funcia goto(I,X) unde I este o mulime de elemente (deci o stare a automatului finit utilizat n
recunoaterea prefixelor viabile) i X N T, se definete ca fiind nchiderea tuturor elementelor
[A a X. B] pentru care [A a . X B] este n I. Intuitiv, dac I este o mulime de elemente utilizate
pentru prefixe de forma t, atunci goto(I,X) este mulimea de elemente utilizate pentru prefixul tX.
De exemplu dac I = {[' .], [ . + T]} atunci goto(I,+) va conine {[ + .T], [T
.T * F], [T .F], [F .()], [F .a]}. Se calculeaz goto(I,+) examinnd mulimea I pentru
elemente avnd simbolul + dup punct. De exemplu elementul [' .] nu este un astfel de element
n schimb se observ c elementul [ . + T] satisface condiia. Se va muta punctul peste simbolul + i
se va obine elementul [ +. T] i se face nchiderea mulimii care conine acest element.
Se poate construi mulimea canonic a mulimilor de elemente LR(0) pentru o gramatic G'
modificat n modul urmtor :

procedura elemente
C = {inchidere ({[S' .S]})}
repeta
C' = C
pentru fiecare multime I C si fiecare X N T executa
daca goto(I,X) & goto(I,X) C
atunci C = C {goto (I,X)}


pana cand C = C'


Pentru gramatica expresiilor aritmetice s considerm din nou diagrama de tranziii pentru capetele
care pot s apar n stiv:
Irina Athanasiu 3/1/2002 Limbaje formale i automate

132


+----+ +----+ + +----+ T +----+ *
| |--- | I1 |---- | |----| I9 |--- I7
| | +----+ | | +----+
| | | | F
| | | I6 |--- I3
| | | | (
| | | |--- I4
| | | | a
| | | |--- I5
| | +----+
| | T +----+ * +----+ F +-----+
| |--- | I2 |----| |---| I10 |
| | +----+ | | +-----+
| | | I7 | (
| | | |---- I4
| I0 | | | a
| | | |---- I5
| | +----+
| | F +----+
| |---| I3 |
| | +----+
| | - (
| | \ /
| | ( +----+ +----+ ) +-----+
| |---| I4 |---- | |----| I11 |
| | +----+ | | +-----+
| | | \\ T | I8 | +
| | a | \\ | |--- I6
| | V \\ +----+
| | a +----+ \\- I2
| |---| I5 | \
| | +----+ \ F
+----+ \- I3

Dac fiecare stare cu exceptia strii I0 este o stare final se observ c aceast diagram poate
reprezenta automatul finit nedeterminist care accept prefixe viabile. Dac considerm automatul
finit nedeterminist pentru care starile sunt elemente, se observ c va exista o tranziie de la nodul
corespunztor elementului [A a.X ] la nodul corespunztor elementului A a X . . Aceasta
tranziie (arc) va fi etichetat cu X. Exist o tranziie de la nodul corespunztor elementului [A a. B ]
la nodul corespunztor elementului [B .] dac B este o producie. Acest arc va fi etichetat cu .
Operaia de nchidere este de fapt operaia de construire a automatului finit determinist echivalent
unui automat nedeterminist dat. n acest mod funcia goto(I,X) va indica tranziia din starea I pe baza
simbolului X n automatul finit determinist. Rezult urmtoarea colecie canonica pentru G :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

133
I0 : ' . I1 : ' . I5 : F a.
. + T . + T I6 : + .T
.T I2: T. T .T * F
T .T * F T T. * F T .F
T .F I3 : T F. F .()
F .() I4 : F (.) F .a
F .a . + T I7 : T T *. F
I9 : + T. .T F .()
T T. * F T .T * F F .a
I10: T T * F. T .F I8 : F (.)
I11: F (). F .() . + T
F .a

Spunem c elementul [A 1 . 2] este valid pentru un prefix viabil a 1 dac exist o derivare
dreapta S * a A w * a 1 2 w. n general un element este valid pentru mai multe prefixe viabile.
Dac A 1 . 2 este valid pentru a 1 i 2 atunci nu s-a gsit nc un capat deci urmtoarea
operaie trebuie s fie o deplasare. Dac 2 = atunci se poate aplica pentru reducere producia A
1. Problema este c pentru acelai prefix se pot gsi mai multe elemente valide, deci n general
poate s apar un conflict care eventual poate s fie soluionat pe baza urmtorului simbol de la intrare
(LR(1)).
Se poate demonstra c mulimea elementelor valide pentru un prefix viabil este mulimea
elementelor care sunt parcurse pornind din starea iniial de a lungul unei ci etichetate cu n
automatul finit determinist construit din mulimea canonic de mulimi de elemente cu tranziii date de
funcia goto. De fapt aceste elemente valide conin toate informaiile necesare referitoare la
coninutul stivei.
S considerm din nou gramatica expresiilor aritmetice. Se observ c + T * este un prefix viabil.
Automatul se va gasi n starea I7 dupa parcurgerea acestui prefix. Starea I7 conine elementele : [T
T *. F], [F .()], [F .a]. S considerm de exemplu urmatoarele derivari dreapta :

' ' '
+ T + T + T
+ T * F + T * F + T * F
+ T * a + T * () + T * a
+ T * F * a

Pentru prima derivare se va folosi elementul T T *. F, pentru a doua F .() iar pentru ultima F
.a pentru prefixul viabil + T *.
Construirea tabelelor de analiza SLR se face pornind de la automatul finit care accept prefixe
viabile. Algoritmul care va fi prezentat n continuare nu produce n mod necesar tabele cu intrri
coninnd un singur termen pentru orice gramatic care descrie un limbaj de programare dar poate s
fie utilizat cu succes pentru majoritatea construciilor din limbajelor de programare. Dndu-se o gramatica
G se utilizeaz gramatica G' (obinut prin nlocuirea simbolului de start al gramaticii S cu un simbol S' i
adugarea produciei S' S) pentru a construi C, mulimea canonic de mulimi de elemente pentru
G'. Algoritmul care produce tabelele de actiune i goto utilizeaz urmtorul algoritm :

Intrare O gramatica G'
Iesire Tabele de analiza pentru G'

Algoritmul parcurge urmatoarele etape :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

134


1. se construieste C = {I0, I1, ..., In} multimea canonic a multimilor de elemente
LR(0) pentru G'.
2. starea i este corespunzatoare multimii Ii. Intrarile n tabela actiune pentru starea i se
obtin n modul urmator :

a) daca [A . a ] Ii si goto(Ii,a) = Ij
atunci actiune[i,a] = "deplaseaza j" /* a T */

b) daca [A .] Ii & A S'
atunci
pentru fiecare a FOLLOW(A) executa
actiune[i,a] = "reduce A a"


c) daca [S' S.] Ii
atunci actiune [i,$] = "succes"


Dac n construirea tabelei actiune apar conflicte gramatica nu este SLR(1) i trebuie s fie
utilizata o alta metoda.

1. Intrarile n tabela goto pentru starea i se obzin n modul urmator :

daca goto (Ii,A) = Ij /* tranzitia din starea Ii n
starea Ij se face pentru
simbolul A */

atunci goto[i,A] = j


4. Toate intrarile necompletate prin regulile 2 si 3 sunt marcate cu eroare
5. Starea initiala a analizorului este cea care corespunde multimii de
elemente care contine elementul [S' .S].

Tabelele de analiz construite conform regulilor anterioare formeaza tabela SLR(1) pentru G. Un
analizor LR care lucreaza cu tabele SLR(1) este un analizor SLR(1).
S construim de exemplu analizorul SLR(1) pentru gramatica expresiilor aritmetice. S considerm
nti mulimea I0 :

' ., . + T, .T, T .T * F, T .F,
F .(), F .a.

Din elementul F .() se obine actiune[0,(] = "deplasare 4", din F .a se obine actiune[0,a] =
"deplasare 5". Celelalte elemente nu produc aciuni. Pentru I1: ' ., . + T se obine
actiune[1,$] = "succes", actiune[1,+] = "deplasare 6". I2 este format din T., T T. * F.
FOLLOW() = {$,+,)}, rezult actiune[2,$] = actiune[2,+] = actiune[2,)] = "reduce T". Pentru T
T. * F se obine actiune[2,*] = "deplasare 7". Coninnd se obine tabela utilizat pentru a ilustra
funcionarea algoritmului de analiza LR.
Orice gramatica SLR este neambigua. Reciproca nu este adevrat. S considerm de exemplu
gramatica :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

135


(1) S L = R
(2) S R
(3) L *R
(4) L a
(5) R L

Mulimea canonic de mulimi de elemente este :

I0 : S' .S I5: L a.
S .L = R I6: S L = .R
S .R R .L
L .* R L .*R
L .a L .a
R .L I7: L *R.
I1: S' S. I8: R L.
I2: S L. = R I9: S L = R.
R L.
I3: S R.
I4: L *.R
R .L
L .*R
L .a

Diagramele de tranziie pentru prefixele viabile sunt :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

136
+------+
+----+ S |+----+|
| |---|| I1 ||
| | |+----+|
| | +------+
| | L +----+ +----+ a
| |---| I2 |----- | |---- I5
| | +----+ | | R +----+
| | | |-----| I9 |
| | | I6 | +----+
| | | | L +----+
| | | |-----| I8 |
| | | | * +----+
| | | |----- I4
| | +----+
| | +------+
| | R |+----+|
| I0 |---|| I3 ||
| | |+----+|
| | +------+
| | * ___
| | \ /
| | * +----+
| |---| |
| | | | R +----+
| | | |-----| I7 |
| | | I4 | +----+
| | | | L
| | | |----- I2
| | +----+
| | V a
| | a +----+
| |---| I5 |
| | +----+
+----+

S considerm elementul I2 pentru care se obine actiune[2,=] = "deplasare 6". FOLLOW(R)
FOLLOW(L) FOLLOW(R) deci FOLLOW(R) = FOLLOW(L), = FOLLOW(L), deci =
FOLLOW(R) i deci actiune[2,=] = "reduce R L. Se observa c dei gramatica nu este ambigu a
aprut un conflict deoarece metoda folosita nu este suficient de puternica neputnd s memoreze
suficienta informaie pe baza creia pentru terminalul = s se stabileasca ce aciune trebuie s se
execute pentru un ir care poate s fie redus la L.

4.1.2.3.2 Analiza canonica LR

Prezentm n continuare metoda cea mai generala de construire a tabelelor LR(1) pentru o
gramatic dat. Pentru metoda considerata anterior n starea i se face reducere cu producia A
dac mulimea Ii conine elementul [A .] i a FOLLOW(A) urmeaz n irul de intrare. Exist
situatii, n care dac i apare n vrful stivei, prefixul din stiva este astfel nct A nu poate s fie
urmat de a ntr-o derivare dreapta i deci nu se poate face reducerea A . Relund ultimul
exemplu pentru starea I2 i elementul [R L.], cu = pe banda de intrare, s-a obinut = FOLLOW(R)
i deci se pune problema aplicrii reducerii R L (vrful stivei conine L). Dar nu exist nici o
derivare dreapta care s nceapa cu R = .... Deci nu trebuie aplicat reducerea. Se observ c utilizarea
Irina Athanasiu 3/1/2002 Limbaje formale i automate

137
condiiei a FOLLOW(A) este prea slab n cazul general. O soluie este transformarea gramaticii
astfel nct pentru automatul care rezult s fie bine precizat ce simbol de intrare poate s urmeze unui
capt pentru care exist posibilitatea unei reduceri. Alt soluie const din adugarea unei informaii
pentru fiecare element obtinndu-se elementele LR(1). Informaia suplimentar este incorporat n
stare prin redefinirea elementelor astfel nct fiecare element s conin ca a doua component un
simbol terminal. Forma general pentru un element este: [A . , a] cu A o producie i a T
{$}. Un astfel de obiect se numeste element LR(1). 1 se refer la numrul de simboli terminali
luai n considerare pentru a se decide e4fectuarea unei reduceri. Pentru un element de forma [A .,
a] se va face o reducere utiliznd producia A dac i numai dac urmtorul simbol de intrare este a.
Dac un element este de forma [A . , a] i atunci a nu ofer o informaie suplimentara.
Pentru elementele [A ., a] este clar c a FOLLOW(A) dar nu toate elementele din FOLLOW(A)
apar n elementele LR(1) de forma [A .,a]. Se spune ca elementul LR(1) [A . ,a] este valid
pentru un prefix viabil dac
exist o derivare : S * Aw w, unde

1. = i
2. fie a este primul simbol din w, fie w = i a = $.

Se considerm de exemplu gramatica S BB, B aB | b. Fie derivarea S aaBab aaaBab.
Elementul [B a.B,a] este valid pentru prefixul viabil aaa considernd = aa, A = B w = ab, = a,
= B n definiia anterioar. De asemenea s considerm i derivarea S + BaB BaaB. Pentru
aceasta derivare elementul [B a . B, $] este valid pentru prefixul Baa.
Metoda de construire a mulimii de elemente LR(1) valide este aceai cu cea pentru
construirea mulimii canonice de mulimi de elemente LR(0) cu modificri adecvate ale procedurii
inchidere i goto.
S considerm un element de forma [A . B , a], A , B N, , (N T)*, a T. Acest
element este valid pentru un prefix , dac exist o derivare dreapta S Aax Bax cu = .
S presupunem c x by, b T , y T*. Atunci pentru orice producie B , vom avea
derivarile S Bby by. Deci, [B ., b] este valid pentru . Se poate observa c b este
primul simbol terminal derivat din , sau dac , x by i deci b = a. Altfel spus b
FIRST(ax) (FIRST(ax) = FIRST(a), a ). Rezult urmatorul algoritm de construire a elementelor
LR(1) :

Intrare O gramatica G'
Ieire mulimile de elemente LR(1) valide pentru unul sau mai multe prefixe din G'.

Algoritmul utilizeaz urmtoarele proceduri auxiliare :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

138

functia inchidere(I) este
repeta
I' = I
pentru fiecare element [A . B , a] I,
fiecare productie B ,
fiecare b FIRST(a) executa
dac [B .,b] I
atunci
I = I {[B .,b]}


pana I = I'
rezultat I


functie goto(I,X) este
fie J = {[A X.,a] | [A .X,a] I}
rezultat inchidere(J)

procedura elemente(G')
C = {inchidere ( { [S' .S,$]})}.
repeta
C' = C
pentru fiecare I C, fiecare X N T executa
daca goto(I,X) si goto(I,X) C
atunci C = C {goto(I,X)}


pana C' = C

S considerm de exemplu gramatica S' S, S CC, C cC | d. Limbajul generat este c
n
dc
m
d S
calculm nti mulimea ({[S' .S, $]}. S identificam n elementul [S' .S,$] componentele
elementului generic [A .B,a]. Rezult A = S', a = , B = S, = , a = $. Din modul de aciune al
funciei inchidere se observ c se adaug termeni de forma [B ., b] pentru fiecare producie
de forma B i fiecare b FIRST(a). Singura producie care se potriveste este S CC, pentru
care a =$, pe post de b se obine $. Rezult adugarea elementului [S .CC, $] la mulimea
inchidere ([{[S' .S,$]}. S considerm acum produciile care au C n partea stng pentru care
trebuie s se adauge elementele [C .,b] pentru b FIRST(C$). Comparnd din nou elementul [S
.CC,$] cu [A .B,a], de data aceasta A = S, = , B = C, = C, a = $. Deoarece C ,
FIRST(C$) = FIRST(C) = {c, d}. Se vor adauga deci elementele [C .cC, c], [C .cC,d], [C .d,c],
[C .d, d]. Se observ c nu mai exist elemente cu un neterminal la dreapta punctului deci s-a obinut
:

I0 : S' .S,$
S .CC,$
C .cC,c/d
C .d, c/d

S calculm goto(I0,X) pentru diferitele valori posibile pentru X. Dac X = S se va calcula
inchiderea elementului [S' S., $]. Rezult :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

139

I1 : S' S.,$

Dac X = C vom calcula nchiderea pentru S C . C, $:

I2 : S C.C,$
C .cC,$
C .d,$

Dac X = c, se calculeaz nchiderea pentru {[C c.C, c/d]}.

I3 : C c.C, c/d
C .cC, c/d
C .d,c/d

Pentru X = d

I4 : C d., c/d

n acest mod s-a terminat calculul pentru inchidere (I0), urmeaz:

I5: S CC.,$ I7: C d.,$
I6: C c.C,$ I8: C cC., c/d
C .cC,$ I9: C cC.,$
C .d, $

Rezult urmtorul graf al automatului :
Irina Athanasiu 3/1/2002 Limbaje formale i automate

140
+----+ S +----+
| |----| I1 |
| | +----+
| |
| | C +----+ C +----+
| |----| |-----| I5 |
| | | | +----+
| | | | c ___
| | | | \ /
| | | I2 | c +----+ C +----+
| | | |-----| I6 |---| I9 |
| | | | +----+ +----+
| | | | \|/ d
| | | | d +----+
| | | |-----| I7 |
| I0 | +----+ +----+
| | c ___
| | \ /
| | c +----+ C +----+
| |----| I3 |---| I8 |
| | +----+ +----+
| | d |
| | \|/
| | d +----+
| |----| I4 |
| | +----+
+----+

Pe baza descrierii obinute pentru automatul finit, descriere ce s-a construit utiliznd funciile goto
i inchidere, rezult urmatorul algoritm de construire a tabelelor de analiz LR pentru G'.

Intrare o gramatica G'
Iesire Tabelele de analiza actiune i goto pentru G'

Algoritmul parcurge urmatoarele etape :

1. se construieste C = {I0, .., In} multimea de multimi canonice de elemente LR(1) pentru
G'.
2. pentru fiecare stare i reprezentata prin multimea Ii executa
dac [A .a , b] Ii si goto(Ii,a) = Ij /* a T */
atunci actiune[i,a] = "deplaseaza j"

dac [A a., a] Ii, A S'
atunci actiune[i,a] = "reduce A a"

daca [S' S., $] Ii
atunci actiune[i,$] = "succes"



Dac din cele regulile anterioare rezult un conflict atunci nseamn c gramatica nu este LR(1) i
execuia algoritmului se oprete.

Irina Athanasiu 3/1/2002 Limbaje formale i automate

141
3. pentru fiecare Ii C si fiecare A N executa
daca goto(Ii,A) = Ij
atunci goto [i,A] = j


4. Toate intrarile necompletate corespund unor situatii de eroare
5. Starea initiala a analizorului se obtine din multimea care contine elementul [S'
.S,$].

Aplicnd acest algoritm pentru gramatica care are produciile :

(1) S CC
(2) C cC
(3) C d

se obin tabelele de analiza :

stare | actiune | goto |
| c d $ | S C |
-------+---------------+-----------|
0 | s3 s4 | 1 2 |
-------+---------------+-----------|
1 | succes | |
-------+---------------+-----------|
2 | s6 s7 | 5 |
-------+---------------+-----------|
3 | s3 s4 | 8 |
-------+---------------+-----------|
4 | r3 r3 | |
-------+---------------+-----------|
5 | r1 | |
-------+---------------+-----------|
6 | s6 s7 | 9 |
-------+---------------+-----------|
7 | r3 | |
-------+---------------+-----------|
8 | r2 r2 | |
-------+---------------+-----------|
9 | r2 | |
-----------------------------------+

O gramatic SLR(1) este evident o gramatica LR(0), dar tabela de analiz LR(1) pentru aceai
gramatic are mai multe stri dect tabela de analiza SLR.
S relum i exemplul care "nu a funcionat" corect pentru algoritmul SLR:
(1) S L = R
(2) S R
(3) L *R
(4) L a
(5) R L

Mulimea canonic de mulimi de elemente este :

Irina Athanasiu 3/1/2002 Limbaje formale i automate

142
I0 : S' .S, $ I5: L a., =/$
S .L = R, $ I6: S L = .R, $
S .R, $ R .L, $
L .* R, =/$ L .*R, $
L .a, =/$ L .a, $
R .L, $ I7: L *R., =/$
I1: S' S., $ I8: R L., =/$
I2: S L. = R , $ I9: S L = R. , $
R L., $ I10: R L., $
I3: S R., $ I11: L *.R, $
I4: L *.R, =/$ R .L, $
R .L, =/$ L .*R, $
L .*R, =/$ L .a, $
L .a, =/$ I12:L a., $


Se observ c pentru I2 se va face reducere dac urmeaz sfritul irului respectiv se va face
deplasare dac urmeaz =.
4.1.2.3.3 Analiza sintactic LALR

Numele LALR a fost ales pornind de la termenul "lookahead" - LR. Tabelele construite utiliznd
aceasta metoda sunt mai mici (exist mai puine stri) dect tabelele canonice LR i de asemenea
majoritatea construciilor din limbajele de programare pot s fie exprimate convenabil utiliznd gramatici
LALR.
Pentru un limbaj cum este PASCAL-ul tabelele de analiza LALR i SLR au sute de intrari n timp
ce tabelele canonice au cteva mii. S relum din nou gramatica G' : S' S, S CC, C cC | d i s
analizm mulimile canonice I4 i I7 :

I4 : C d., c/d , I7 : C d., $

Pentru I4 decizia de reducere este pentru simbolii terminali c i d, pentru I7 decizia de reducere se
face pentru $. Gramatica pe care am considerat-o genereaz iruri de forma c*dc*d. Deci analizorul va
deplasa iniial irul de c i va intra n starea I4 dup ntlnirea simbolului d, dup care se va face o
reducere C d dac se ntlnete un c sau un d. Reducerea este corect deoarece c sau d pot s nceap
irul c*d care trebuie s urmeze. Dac ns apare $ nseamn c irul s-a terminat prea devreme (de
exemplu este de forma ccd). Dup d se intr n starea 7 dup care trebuie s urmeze $ sau irul de
intrare nu este corect. S considerm ca reunim cele doua stri sub forma unui element [C d., c/d/$].
Trimiterile n I4 pentru d din I0, I2, I3 i I6 vor fi spre I47. Actiunea din I47 va fi de reducere pentru
orice intrare. Deci exist situaii n care n loc de semnalarea unei erori se va face reducerea C d. De
exemplu pentru irurile ccd sau cdcdc. Eroarea se va depista nainte de a se mai considera un alt caracter
de intrare.
n general se cauta mulimi de elemente LR(1) avnd acelai nucleu (aceeai mulime a primelor
componente pentru elemente) i se face o reuniunea acestor mulimi de elemente. Pentru exemplul
considerat mulimile I4 i I7 au ca nucleu mulimea {C d.}, de asemenea mulimile I3 i I6 au ca
nucleu mulimea {C c.C, C .cC, C .d}. n general un nucleu este o mulime de elemente
LR(0). O gramatica LR(1) poate produce mai multe mulimi cu acelai nucleu.
Se observ c miezul mulimii goto(I,X) depinde numai de miezul mulimii I. Corespunztor
se poate face reuniunea mulimilor goto pentru doua mulimi care au acelai nucleu. Valorile din
tabela goto i actiune vor reflecta aceste reuniuni prin modificri corespunztoare. Adic tabela goto va
Irina Athanasiu 3/1/2002 Limbaje formale i automate

143
reflecta noile mulimi ntre care se fac tranziii iar n tabela actiune se nlocuiesc o serie de intrri de
eroare cu intrri de reducere.
S presupunem ca s-a construit o gramatica LR(1) fr conflicte. Dac nlocuim toate
mulimile cu acelai nucleu cu reuniunea lor s-ar putea, dar este puin probabil s apar conflicte. S
presupunem ca exist un conflict datorit unui simbol a T deoarece exist un element [A ., a] care
indic o reducere cu A i exist un alt element [B . , b] care indic o deplasare. Se observ
c n acest caz dintre elementele pentru care s-a facut reuniunea exist i elementele [A ., a] i [B
., b] pentru un anumit b. Inseamn c aceste elemente prezint acelai conflict deplaseaza /
reduce pentru terminalul a i gramatica nu ar mai fi LR(1) asa cum s-a presupus. Deci un conflict
deplaseaza / reduce nu poate s apar prin reuniunea mulimilor de elemente cu acelai nucleu, dac un
astfel de conflict nu a aprut ntr-una din strile iniiale deoarece deplasrile depind numai de nucleu,
nu i de simbolii care urmeaz pe banda de intrare. Dar poate s apar un conflict reduce / reduce. S
considerm de exemplu gramatica : S' S, S aAd | bBd | aBe | bAe, A c, B c. Aceast
gramatic genereaz irurile : acd, ace, bcd, bce. Construind mulimea elementelor LR(1) se va obine
mulimea { [A c.,d], [B c., e]} ale carui elemente sunt valide pentru prefixul ac i mulimea {[A c.,
e], B c.,d]} ale crui elemente sunt valide pentru prefixul bc. Dac se construiete reuniunea acestor
mulimi se obine mulimea {[A c., d/e], [B c., d/e] pentru care se observ c exist un conflict
reduce/reduce.
Acest conflict semnific faptul c gramatica nu este LALR(1). De obicei transformri
asupra gramaticii rezolva problema.

Irina Athanasiu 3/1/2002 Limbaje formale i automate

144
Bibliografie
Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman, Compilers Principles, Techniques, and Tools,
Addison Wesley, 1986
Alfred V. Aho, Jeffrey D. Ullman, The Theory of Parsing, Translation and Compiling, Prentice-
Hall
William M. Waite, Gerhard Goos, Compiler Construction, Springer Verlang
Harry R. Lewis, Christos H. Papadimitriou, Elements of the Theory of Computation, Prentice Hall,
1981
Michael A. Harrison, Introduction to Formal Language Theory

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