Download as pdf or txt
Download as pdf or txt
You are on page 1of 78

Construc]ia compilatoarelor folosind Flex [i Bison

Anthony A. Aaby Walla Walla College cs.wwc.edu aabyan@wwc.edu Popa Dan Universitatea Bac\u www.ub.ro popavdan@yahoo.com, dpopa@ub.ro

Versiunea din 19 septembrie 2005

Copyright 2003 Anthony A. Aaby Walla Walla College 204 S. College Ave. College Place, WA 99324 E-mail: aabyan@wwc.edu LaTeX sources available by request. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at http://www.opencontent.org/openpub This book is distributed in the hope it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. The author encourages wide distribution of this book for personal and commercial use, provided the above copyright notice remains intact and the method adheres to the provisions of the Open Publication Liscense located at http://www.opencontent.org/openpub In summary, you may copy and distribute this book free of charge or for a profit. No explicit permission is required from the author for reproduction of this book in any medium, physical or electronic. Note, derivative works and translations of this document must include the original copyright notice must remain intact. Versiunea `n limba rom=na este tradus [i adaptat de !an "opa # popavdan@yahoo.com, dpopa@ub.ro. $m f cut de asemenea o serie de rectific ri [i corecturi% $m unificat nota]iile pentru codul &enerat [i instruc]i'unile ma[inii (irtuale% )oate fi[ierele surs au fost rescrise la calculator [i toate pro&ramele au fost testate% !atorit adapt rii# o serie de por]iuni din text au fost rescrise iar para&rafe `ntre&i cu explica]ii au fost ad u&ate% *arcarea lor folosind caractere italice ar fi `nc rcat inutil textul dar cititorul interesat poate compara cele dou edi]ii# en&le+ [i rom=n pentru a (edea ce modific ri [i ad u&iri s'au f cut cu oca+ia traducerii [i adapt rii% , parte din anexele (ersiunii `n limba en&le+ nu au fost incluse `n aceast (ersiune% Cop-ri&.t'ul pentru edi]ia `n limba rom=n / !an "opa 020051

Cuprins
2n loc de moti(a]ie 5 1 3ntroducere 4 2 $nali+orul sintactic 0"arser'ul1 15 5 6caner'ul 0$nali+orul lexical1 19 7 Contextul 25 5 ,ptimi+area 55 8 *a[ini Virtuale 54 4 9enerarea Codului 75 : ,ptimi+area de cod dup &enerare 55 9 ;ecturi suplimentare 54 10 <xerci]ii 59 $nexa $/ ;imba=ul 6imple ' 3mplementarea complet %%81 $%1 "arserul/ 6imple%- % % % % % % % % % % % % % % % % % % % % % % % % %%81 $%2 3ndica]ii de lucru % % % % % % % % % % % % % % % % % % % % % % % % % % % 85 $%5 6canerul/ 6imple%lex % % % % % % % % % % % % % % % % % % % % % % % %88 $%7 )abela de simboluri/ 6)%. % % % % % % % % % % % % % % % % % % % %84 $%5 9eneratorul de cod/ C9%. % % % % % % % % % % % % % % % % % % % %8: $%8 *a[ina cu sti( / 6*%. % % % % % % % % % % % % % % % % % % % % % % %89 $%4 >n exemplu de pro&ram/ test?simple % % % % % % % % % % %41 $nexele edi]iei de limb en&le+ neincluse `n aceast edi]ie electronic / B ;ex@Flex B%1 ;ex@Flex <xamples % % % % % % % % % % % % % % % % % % % % % % % % % % B%2 ).e ;ex@Flex 3nput File % % % % % % % % % % % % % % % % % % % % % % % B%5 ).e 9enerated 6canner % % % % % % % % % % % % % % % % % % % % % % B%7 3nterfacin& Ait. Bacc@Bison % % % % % % % % % % % % % % % % % % % % C Bacc@Bison C%1 $n ,(er(ieA % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % C%2 $ Bacc@Bison <xample % % % % % % % % % % % % % % % % % % % % % % C%5 ).e Bacc@Bison 3nput File % % % % % % % % % % % % % % % % % % % % C%7 Bacc@Bison ,utput/ t.e "arser File % % % % % % % % % % % % % C%5 "arser C';an&ua&e 3nterface % % % % % % % % % % % % % % % % % % C%8 !ebu&&in& Bour "arser % % % % % % % % % % % % % % % % % % % % % % C%4 6ta&es in >sin& Bacc@Bison % % % % % % % % % % % % % % % % % % % , anex suplimentar / $nexa !/ 3nstalarea pro&ramelor Flex [i Bison% % % % % % % %42

)itlul ori&inal/ Compiler Construction usin& Flex and Bison Cop-ri&.t C 2005# $nt.on- $%$abCop-ri&.t C 2005# "opa !an# 0 pentru textul re+ultat din traducerea `n limba rom=n [i por]iunile explicati(e inserate1 Contribu]ia autorilor/ $nt.on- $% $ab-/ `ntre&ul (olum cu excep]ia para&rafelor care nu se & sesc `n edi]ia ori&inal # sursele pro&ramelor cu comentarii `n limba en&le+ # sursele din anex "opa !an/ para&rafele explicati(e care lipsesc din edi]ia `n limba en&le+ # sursele pro&ramelor comentate `n limba rom=n # eratele cuprinse `n text# nota]iile unificate# rularea [i (erificarea pro&ramelor# corecturile surselor din anex # corectura final # traducerea [i adaptarea "opa !an "anselelor 10# 6c $# <t 1# $pt 5# Bac u# Dom=nia tel/ 0257 582288 e'mail/ popa(dan@-a.oo%com# dpopa@ub%ro "opa !an E Cartea prin e'mail $cest (olum poate fi solicitat &ratuit# `n format %pdf# la adresa public de e'mail a autorului/ e'mail/ popa(dan@-a.oo%com

!escrierea C3" propus Bibliotecii Fa]ionale a Dom=niei $nt.on- $% $ab-# !an "opa Construc]ia compilatoarelor folosind Flex [i Bison @ $nt.on- $% $ab-# !an "opa ' Bac u/ 2005 # 4: p& Biblio&r% 36BF 945'0'07015'5 3% $ab-#$nt.on- $% 33% "opa# !an

2n loc de moti(a]ie !e ce s scriu o carte despre compilatoare# interpretoare #Flex [i Bison# `n limba rom=n # `n anii primului cincinal al mileniului al doilea G 6unt de actualitate G Folosesc ele cui(a G 6au r m=n un simplu exerci]iu academic ori te.nic# destinat profesorilor de teoria compilatoarelor [i .acHerilor 0ade( ra]ilor .acHeri# acei exper]i autentici `n compilatoare care sunt `n stare s ']i in(ente+e un limba= de pe a+i pe m=ine sau s ']i ascund un (irus `ntr'un compilator astfel ca el s &enere+e pro&rame de lo&in IsparteJ# c.iar dac le compile+i din nou1 G !e ce o asemenea carte este necesar oportun [i cui ar folosi G Ce moti(e sunt pentru scrierea ei G 3at 'le# `ntr'o ordine oarecare# a[a cum mi'au (enit Kla prima stri&areJ/ 11 ;inux'ul se r sp=ndeste rapid# num rul de utili+atori cresc=nd (erti&inos cu cifre `ntre 8L [i 58L pe an 0num rul depinde de cate&oria de utili+atori# utili+atori casnici sau mana&eri de ser(ere1% "entru acei utili+atori de ;inux care# uneori `n ciuda (=rstei# mai au dorin]a de a `n( ]a# de a se bucura ca ni[te copii care descoper 9oo&le'ul# pentru ei# cei care uneori .abar n'au ce ser(icii le pot aduce Flex'ul [i Bisonul# merit s traduc# s scriu# s complete+ aceast carte% $u o [ans `n plus s afle ce mai con]ine distribu]ia lor fa(orit de ;inux% Fu scriu care distribu]ie# deoarece ma=oritatea distribu]i'ilor de ;inux pe care le'am consultat 0DedMat 7%2# 5%2# 8%0# 8%1# 8%2# 4%0# 4%2 # Corel ;inux # *andraHe ;inux :%0# :%1# :%2# 9# 10 [i altele1 includ pac.etele Flex [i Bison% 21 Flex [i Bison nu sunt numai instrumente de scriere a compilatoarelor% Flex'ul e un &enerator de anali+oare lexicale deci o unealt pentru `mp r]it texte `n Icu(inteI 0sau litere sau alte &rup ri de simboluri cu structur specific 1 [i de executat ac]iuni la `nt=lnirea lor% Bisonul este c.iar mai puternic/ poate prelucra date imbricate# a(=nd structuri [i substructuri# specificate printr'o &ramatic % <ste un &enerator de parsere 0anali+oare sintactice1 care pot fi dotate [i cu re&uli semantice# ceea ce `l face un (eritabil &enerator de compilatoare% 51 Flex'ul [i `n mai mic m sur Bison'ul pot fi de folos [i altor cate&orii de personal% 2ntr'un num r din re(ista "C Deport# un alt &enerator de anali+oare lexicale era pre+entat printr'un exemplu care re+ol(a o problem spinoas te.noredactorilor/ con(ersia textelor de la un font la altul sau la standardul >)F% Cei care s'au lo(it de problema diacriticelor limbii rom=ne# problem pentru care exist c=te IbordeieI at=tea Iobiceie de scriereI ' a se citi fonturi sau standarde# [i au primit nu o dat mail'ul unui [ef sup rat c textul nu se (ede cu diacritice pe computerul s u# (or `n]ele&e actualitatea problemei% 71 $]i putea fi de asemenea cititori ai unei asemenea c r]i dac dori]i s manipula]i date structurate ori (re]i s ob]ine]i (ite+ la prelucr ri ale unor anumite ba+e de date reali+ate cu N*; # f r a mai `n( ]a N*; [i `n condi]iile `n care aplica]ia (a fi reali+at cu un 5

compilator de limba= C% 51 $lte probleme banale pe fond dar relati( dificil de abordat cu mi=loace clasice [i totodat adesea `nt=lnite la concursurile pentru posturi de pro&ramatori se re+ol( u[or cu Flex [i Bison% !intre ele amintim crearea unui calculator e(aluator de expresii numerice cu parante+e # 0un asemenea modul softAare ar ferici orice utili+ator de produs de contabilitate# dar admit c poate fi reali+at [i altfel dec=t cu un &enerator de compilatoare1 sau clasica problem de traducere care const `n a &enera pentru un num r `n cifre transcrierea lui `n litere% $ceste probleme au [i alte solu]ii dar dac reali+a]i o aplica]ie contabil cu ba+e de date *-6O; pe platform ;inux poate ('ar interesa [i problemele de mai sus# mai ales dac pro&rama]i `n C sau CPP% 81 <xist o mul]ime de &eneratoare de compilatoare mai sofisticate dec t perec.ea Flex# Bison# unele folosite la $cademie sau `n medii uni(ersitare% <xist [i metode de specificare mai e(oluate 0de exemplu Viena !efinition *et.od1% !in nefericire ori softul este inaccesibil ma=orit ]ii cititorilor# ori are licen] proprietar # ori rulea+ pe cine [tie ce computer 6un 6parc 6tation pe care nu'l a(em la dispo+i]ie noi# utili+atoriui de "C'uri% ,ri pur [i simplu nu putem & si `n Dom=nia softAare'ul ori documenta]ia% Combina]ia ;inux plus Flex plus Bison plus 9CC 0compilatorul 9F># fost 9F> C Compiler1 r m=ne deocamdat &eneratorul de compilatoare cu r sp=ndirea cea mai lar& [i de[i exist (oci care afirm c re+ol( doar :0L din problem # este totu[i `ndr &it de pro&ramatorii care ador s se afirme scriind ei c=t mai mult cod% 41 !ac sunte]i student la un curs de compilatoare sau doctorand la un `ndrum tor care se ocup de construc]ia limba=elor# dac sunte]i frustrat c la finalul cursului n'a]i f cut `nc un compilator# fie [i unul c=t de mic# pentru un limba= oric=t de simplu [i [ti]i s da]i c=te(a comen+i unui sistem ;inux atunci aceast carte e pentru dumnea(oastr cu si&uran] % Fu pot s ( descriu emo]ia scrierii primului pro&r mel care (a rula pe interpretorul dumnea(oastr sau (a fi compilat cu compilatorul dumnea(oastr % Qi mai ales satisfac]i'a care o (e]i sim]i ( +=nd c rulea+ sau se compilea+ [i se execut f r erori% V'o spune un fost absol(ent al primei serii de la o facultate de 3nformatic # serie n scut prin transformarea uneia din cele de la sec]iile Faculta]ii de *atematic % Ca student reu[isem performan]a de a termina facultatea de 3nformatic f r s fac practic nici un compilator RRR *oti( pentru care dedic aceast carte [i fo[tilor cole&i de an [i fo' [tilor mei profesori# `ncep torii de alt dat 0preparatori# asisten]i etc1# speciali[tii de ast +i%

Capitolul 1 3ntroducere >n compilator este `n esen] un pro&ram traduc tor ce transform pro&rame scrise `ntr'un limba= surs `n ec.i(alentele lor scrise `ntr'un limba= obiect% ;imba=ul surs este de obicei un limba= de pro&ramare de ni(el `nalt iar limba=ul obiect este de obicei limba=ul ma[in al computerului% !in punct de (edere pra&matic putem afirma c prin translator 0compilator1 se define[te o anume semantic a limba=ului de pro&ramare% )ranslatorul transform opera]iile date `n mod sintactic `n opera]ii ale modelului de calcul al unei ma[ini (irtuale sau reale% $cest capitol arat cum sunt folosite &ramaticile independente de context la construc]ia translatoarelor 0compilatoarelor1% !eoarece traducerea este &.idat de sintaxa limba=ului surs # traducerea aceasta este numit Is-ntax'directed translationI adic Itraducere ba+at pe sintax I sau# mai bine +is Itraducere diri=at de sintax I% !e ce este ne(oie de tot acest ansamblu de te.nici G V'a]i `ntrebat (reodat de fac compilatoarele anali+ sintactic pe ba+a unei &ramatici G !oar de dra&ul (erific rii sintaxei G Ficidecum R >n limba= de pro&ramare este ec.i(alent cu o mul]ime poten]ial infinit de pro&rame% 6unt pro&ramele care se scriu `n el% !ac am `ncerca s definim direct cum s'ar traduce ele# lu`ndu'le r=nd pe r=nd# nu ne'ar a=un&e (e[nicia% !eci trebuie & site alte te.nici% )otu[i asemenea mul]imi infinite pot fi definite inducti( [i st p=nite cu te.nici similare banalei induc]ii matematice de la liceu% Ce este o defini]ie inducti( G !au un exemplu ar.icunoscut/ numerele naturale nenule se pot defini cu doar dou elemente/ 1 [i functia succesor s0x1 care ni'l d pe succesorul lui x adic pe x plus 1% $tunci numerele naturale nenule sunt/ 1# s011# s0s0111# [amd% V'a]i prins G 6e `ncepe cu ceea ce matematicienii numesc ba+a induc]iei [i se continu dup o re&ul inducti( care define[te ceea ce urmea+ func]ie de ceea ce a(eam definit mai `nainte% $stfel putem st p=ni numerele naturale# `n infinitatea lor# lucr nd cu doar dou elemente # 0 [i func]ia s0x1# cea care `n fapt descrie cum se ob]ine un num r mai complicat din precedentul% !orim s transcriem aceste numere ca sume de unit ]i G !at fiind c numerele naturale nenule sunt definite doar cu a=utorul a dou elemente# acum este simplu% )rebuie s definim cum se transcriu ca sume de unit ]i cele dou elemente / 1 [i s0ceva1 unde ceva la r=ndul s u s'ar putea scrie tot ca o sum de unit ]i% 3at cele dou re&uli/ 1 se transcrie prin 1# IsumaI cu un termen s0x1 se transcrie prin/ 1 plus transcrierea lui x $dic )011 este 1 iar )0s0x11 este 1 plus )0x1 C=t este# de exemplu# )0s0s0111 G <ste 1 plus )0s0111 adic 1plus 1 plus )011 adic 1 plus 1 plus 1% 4

Conclu+ia/ "utem defini o traducere pe o mul]ime infinit de elemente definite structural inducti( dac [tim cum se traduc/ elementele cele mai simple 0la un limba= de pro&ramare structurat printre ele sunt instruc]iunile1 [i cum se traduc structurile compuse% "entru structuri sunt date ni[te re&uli care ne spun de obicei c traducerea structurii compuse se ob]ine imediat din traducerile structurilor componente% $cesta este de altfel celebrul principiu compo+i]ional din semantic % !eci de ce a(em ne(oie de sintaxa limba=ului# de structura lui sintactic sau sc.ema# arborele sintactic al acestuia G 0Care nu'i mai complicat dec t ceea ce se f cea la [coala &eneral # la &ramatic ' acele desene arborescenteR1 !eoarece nu'l putem traduce altfel# fiind infinit mul]imea pro&ramelor posibile% >n mod de a st p=ni infinitatea aceasta este induc]ia matematic # definirea inducti( iar pentru induc]ie a(em ne(oie de ba+a induc]iei 0elemente de limba= despre care [tim direct cum se traduc1 [i re&ulile inducti(e 0structurale1 care spun cum se traduce o structur compus # traduc ndu'i `nt=i componentele% $(=nd traducerea definit astfel# inducti(# pe structuri [i substructuri# e clar c primul pas al compil rii e s & sesc# aceste structuri% <xact a[a ce(a face anali+a sintactic R 3ar proiectantul unui limba= [i al unui compilator (a `ncepe prin a scrie &ramatica limba=ului# acea descriere inducti( # structurat a sintaxei limba=ului `nsu[i% <i `i (a asocia pe urm re&ulile semantice destinate a conduce traducerea% !efini]ie/ >n compilator este un translator al c rui limba= surs este un limba= de ni(el `nalt 0apropiat omului# cu cu(inte din limbile umane1 [i al c rui limba= obiect este apropiat de limba=ul ma[in al computerului concret disponibil% Compilatorul tipic parcur&e urm toarele fa+e [i fiecare fa+ prelucrea+ Ioutput'ulI# ie[irea care se ob]ine din fa+a precedent / Fa+a de analiz\ lexical\ 0IscanareaI textului `n c utarea cu(intelor [i altor entit ]i1 &rupea+ caracterele `n unit ]i lexicale# numite atomi lexicali 0`n en&le+ ItoHensI1% ;a intrarea anali+orului lexical se prime[te pro&ramul ca un [ir amorf de caractere# litere spa]ii [i simboluri% ;a ie[ire re+ult un [ir de atomi lexicali% )radi]ional# a [a+isele "expresiile regulate" sunt folosite pentru a defini [abloane de recunoa[tere a atomilor de c tre scaner 0anali+or lexical1% $cesta este implementat ca un automat finit determinist# o ma[in cu un num r de st ri finit care'[i sc.imb starea la primirea c=te unui caracter% 0Fot / 6unt posibile [i alte te.nici# de exemplu s'a in(entat anali+orul lexical adapti( care recuno[te [i `n(a' ] sin&ur diferitele cate&orii de atomi lexicali [i ne scute[te s mai scriem noi specifica]iile% )ot ce ne r m=ne e s spunem care dintre clasele de atomi descoperite (or fi identificatori# care numere etc% Fu (a fi `ns subiect al acestei c r]i%1 ;ex'ul [i Flex'ul sunt instrumentele cele mai populare de &enerare a anali+oarelor lexicale # acele pro&rame care recunosc sin&ure [abloane lexicale `n text% Flex este o (ariant mai rapid a ;ex'ului# compatibil cu acesta la ni(el de specifica]ii% 2n acest capitol# prin ;ex @ Flex (om numi simultan ambele &eneratoare% 2n anexa despre ;ex @Flex 0din (ersiunea en&le+ a c r]ii1 sunt preluate condensat elemente din manualul IflexdocI scris de Vern :

"axon% Analizorul sintactic 0parser'ul1 &rupea+ atomii lexicali 0toHens1 `n unit ]i 0structuri1 sintactice% Ca re+ultat ob]ine o repre+entare arborescent / $rborele sintactic al pro&ramului# abre(iat ca 6) ' syntax tree# `n literatura de limb en&le+ % , &ramatic independent de context furni+at parserului 0&ramatica limba=ului1 `i spune acestuia ce structuri sintactice s recunoasc % "arserul este cel mai adesea implementat ca un automat pus.'doAn% 0$dic o ma[in cu num r finit de st ri `n+estrat [i cu o sti( % 3ntui]i probabil de=a c sti(a `i este necesar pentru a urm ri imbricarea structurilor sintactice# `nc.iderea parante+elor desc.ise `n expresii [amd%1 Bacc [i Bison sunt instrumente pentru &enerarea de anali+oare sintactice 0parsere ' pro&rame care recunosc structura sintactic a unui pro&ram1% Bison este o (ersiune mai rapid de Bacc% 2n acest capitol# prin Bacc @ Bison ne (om referi la ambele instrumente% 6ec]iunea pri(ind Bacc @ Bison este o condensare [i apoi extindere a documentului IB36,F t.e Bacc'compatible "arser 9eneratorI scris de C.arles !onell- `mpreun cu celebrul Dic.ard 6tallman% Fa+a de analiz\ semantic\ prelucrea+ arborele sintactic `n c utarea acelor informa]ii dependente de context numite `n en&le+ Istatic semanticsI 0s'ar traduce prin Isemantic static I1% ;a terminarea ei se ob]ine un arbore sintactic 0$6)1 adnotat% 0!e exemplu stabilirea tipurilor (ariabilelor din expresii# pe ba+a declara] iilor precedente se face `n aceast fa+ %1 Gramaticile cu atribute sunt suportul teoretic al acestei etape% Cu a=utorul lor se descrie semantica static a unui pro&ram% $ceast fa+ se reali+ea+ de obicei concomitent cu anali+a sintactic % 3nforma]iile colectate `n aceast fa+ pri(ind (ariabilele [i alte entit ]i 0definite de pro&ramator `n pro&ram1 sunt culese [i stocate `n tabela de simboluri 0 `n en&le+ ' symbol table). $ceste informa]ii sunt folosite la (erific rile dependente de context# acele (erific ri `n care se confirm c o entitate a fost folosit conform cu specifica]iile existente despre ea% Optimizatorul 0arborelui1 supune arborele sintactic adnotat 0$6)1 unor transform ri care p strea+ sensul de ansamblu al pro&ramului dar simplific structura arborelui [i facilitea+ &enerarea unui cod mai eficient% Generatorul de cod transform arborele adnotat [i simplificat `n cod obiect# folosind re&uli care denot semantica limba=ului de pro&ramare% 0Vede]i [i materiale despre denotational semantics%1 9eneratorul de cod poate fi inte&rat anali+orului sintactic# astfel ca el s &enere+e cod imediat ce recunoa[te o structur sintactic % ,ptimi+atorul de cod &enerat 0`n en&le+ Ipeep'.ole optimi+er1 examinea+ codul obiect &enerat [i# constat=nd uneori c un &rup de instruc]iuni ale procesorului se 9

poate `nlocui cu una sin&ura sau cu un &rup mai mic# mai eficient# ori mai rapid# reali+ea+ `mbun t ]iri ale codului dependente de ma[in % 2n contrast cu compilatorul# interpretorul este un pro&ram care simulea+ execu]ia pro&ramului scris `n limba=ul surs % 3nterpretoarele pot I`n]ele&eI [i executa fie direct instruc]iuni ale unui limba= de pro&ramare de ni(el `nalt# fie pot compila pro&ramul [i executa iterpretati( codul re+ultat# acest cod fiind de obicei &enerat ca pentru o ma[in (irtual # adic un procesor de care nu dispunem `n form .ardAare% 2n aceast situa]ie# compilatorul inclus &enerea+ un cod pentru acea ma[in (irtual # cod care corespunde pro&ramului ini]ial din limba=ul surs % <xist o lar& palet de translatoare care se folosesc `mpreun cu compilatoarele `n procesul de reali+are a pro&ramelor% >n asamblor este acel translator 0compilator dac (re]i1 al unui limbaj de asamblare. 3nstruc]iunile acestui limba= corespund una c=te una unei instruc]iuni din codul obiect# adic din limba=ul procesorului% 0Cu alte cu(inte limba=ul de asamblare nu este un limba= structurat# `n care s pute]i scrie instruc]iuni compuse# imbricate# ci doar cel mult expresii # iar acestea sunt prelucrate doar de unele asambloare mai sofisticate1% <xist compilatoare care &enerea+ codul `n limba= de asamblare iar acesta (a fi transformat `n limba= ma[in de c tre un asamblor% >n `nc rc tor 0`n en&le+ loader1 e un translator pentru care at=t limba=ul de la intrare c t [i cel de la ie[ire sunt limba= obiect% ;a intrare prime[te [i o tabel care spune unde trebuie modificat pro&ramul `n limba= ma[in pentru a fi corect executat c=nd este plasat `n memorie la o adres anume% >n link-editor e tot un fel de translator care prime[te o colec] ie de module de pro&ram executabile [i le lea& `mpreun form=nd un sin&ur pro&ram executabil destinat apoi execu]iei% >n preprocesor este un translator al c rui limba= surs este un fel de limba= de ni(el superior extins cu alte construc]ii# iar al c rui limba= obiect este acel limba= de ni(el superior# neextins% Ca exemplu# `n cele ce urmea+ (om construi un compilator pentru un limba= de pro&ramare imperati( ' de=a clasic `n cursurile de compilatoare ' numit Simple% 9ramatica limba=ului Simple, a[a cum ne'o propune domnul $nt.on- $% $ab-# este /
program declarations id seq ::= ::= ::= LET [ declarations ] IN [command sequence] END INTEGER [ id seq ] IDENTIFIER . [id seq ...] IDENTIFIER

command sequence ::= command... command command ::= % % % % % !"I# $ IDENTIFIER := e&pression $ IF e&p T'EN [command sequence] EL!E [command sequence] FI $ ('ILE e&p D) [command sequence] END $ RE*D IDENTIFIER $ (RITE e&pression $

10

e&pression

::= N+,-ER % IDENTIFIER % ./. e&pression . 0. % e&pression 1 e&pression % e&pression 2 e&pression % e&pression 3 e&pression % e&pression 4 e&pression % e&pression 5 e&pression % e&pression = e&pression % e&pression 6 e&pression % e&pression 7 e&pression

Feterminalii sunt scri[i cu minuscule# terminalii 0cu(intele limba=ului1 s'au scris cu ma=uscule sau cu simboluri [i acolo unde ar fi fost pricin de confu+ie cu metasimboluri din <BFF# s'au folosit [i &.ilimele simple% 6imbolul de start este program, neterminalul corespun+ tor cate&oriei &ramaticale a pro&ramelor complet scrise% !e[i am folosit ma=uscule la scrierea cu(intelor limba=ului 0simbolurilor terminale1# la implementare (om lucra cu minuscule% ;imba=ul (a a(ea dou re&uli# restric]ii# dependente de context% 6e cere ca (ariabilele s fie declarate `nainte de a fi folosite [i ca (ariabilele s fie declarate exact o dat % "entru necunosc torii nota]iei folosite 0de inspira]ie <BFF1# coment m sintaxa de mai sus# re&ul cu re&ul /
program ::= LET [ declarations ] IN [command sequence] END

"ro&ramul e format din cu(=ntul obli&atoriu ;<)# ni[te declara]ii care pot lipsi 0atunci c=nd nu folosim (ariabile1# cu( ntul obli&atoriu 3F # sec(en]a de instruc]iuni de executat# care poate fi [i ea (id # [i# `n cele din urm se termin cu <F!%
declarations ::= INTEGER [ id seq ] IDENTIFIER .

!eclara]iile `ncep cu cu(=ntul 3F)<9<D [i se termin cu un identificator 0oarecare1 [i un punct% "oate fi dup 3F)<9<D o sec(en] mai lun& de al]i identificatori declara]i `n aceea[i declara]ie%
id seq ::= [ id seq ...] IDENTIFIER

$ceast sec(en] se termin totdeauna cu (ir&ul pus dup ultimul identificator [i `ncepe cu o sec(en] 0care not m noi poate fi [i (id % "ractic sec(en]a# a[a cum (a apare `n declara]ie# este format din identificatori urma]i de (ir&ul # cu excep]ia ultimului 0din declara]ie1 despre care am ( +ut din re&ula anterioar c era urmat de punct%
command sequence ::= command... command

6ec(en]a de comen+i este format din comen+i puse una dup alta# pur [i simplu% Vom (edea din re&ula urm toare c fiecare comand include un simbol Ipunct [i (ir&ul I% $m scris peste tot [command sequence] cu parante+e drepte deoarece ea putea fi [i (id # adic putea lipsi% 2n nota]ia de specialitate parante+a p trat marc.ea+ un element op' 11

]ional al construc]iei sintactice respecti(e%


command ::= % % % % % !"I# $ IDENTIFIER := e&pression $ IF e&p T'EN [command sequence] EL!E [command sequence] FI $ ('ILE e&p D) [command sequence] END $ RE*D IDENTIFIER $ (RITE e&pression $

3nstruc]iunile posibile sunt instruc]iunea (id 6S3"# atribuirea# 3F')M<F'<;6< terminat cu F3# TM3;<'!, terminat cu <F! precum [i dou instruc]iuni de intrare ie[ire# absolut necesare ca s comunic m cu calculatorul `n 6imple/ citirea (alorii unui identificator [i scrierea (alorii unei expresii% Fota]i c 3!<F)3F3C$),D este scris cu ma=uscule ca un terminal 0iar el (a fi furni+at ca atare dup anali+a lexical # ca un sin&ur atom lexical oricum s'ar numi el iar numele `i (a de(eni un simplu atribut1% 2n timp ce IexpressionI # expresia# este scris cu minuscule# ca un neterminal deoarece e numele unei cate&orii &ramaticale din pro&ram% <xpresiile au structur # nu's simboli terminali# [i (or trebui anali+ate sintactic mai departe% Felul cum sunt structurate expresiile e descris de re&ula urm toare/
e&pression ::= N+,-ER % IDENTIFIER % ./. e&pression . 0. % e&pression 1 e&pression % e&pression 2 e&pression % e&pression 3 e&pression % e&pression 4 e&pression % e&pression 5 e&pression % e&pression = e&pression % e&pression 6 e&pression % e&pression 7 e&pression

<xpresia poate fi un simplu num r# un simplu identificator sau o expresie pus `n parante+ 0ce se comport ca (aloarea ei1% *ai poate fi o sum # o diferen] # un produs sau un c=t de expresii precum [i un Kade( ratJ 011 sau KfalsJ 001 re+ultat `n urma unei compara]ii# a unei (erific ri dac alte dou expresii sunt `ntr'o rela]ie de e&alitate # ine&alitate ori compara]ie de un fel sau altul 0 U # V 1% ,bser(a]ie/ acele cate&orii &ramaticale care corespund unor neterminali din care poate deri(a un [ir (id 0deci acelea care pot lipsi1 au fost# nu uita]i# puse `n parante+ % Vom (edea `n capitolul urm tor o alt nota]ie pentru &ramatica limba=ului 6imple# e(iden]iind ni [te re&uli 0sau mai corect alternati(e ale unor re&uli1 cu partea dreapt (id % !ar aceasta la momentul potri(it% !eocamdat # `n acest capitol# am (rut doar s (a familiari+ m cu limba=ul ce urmea+ a fi implementat%

12

Capitolul 2 $nali+orul sintactic 0"arser'ul1 >n parser este un pro&ram care determin dac textul primit de el este sintactic corect [i `n plus# `i determin c.iar structura% $ltfel spus nu spune doar ICorect RI sau I3ncorect RI% "arserele pot fi scrise de m=n sau pot fi automat &enerate de un &enerator de anali+oare sintactice# pornind de la descrierea unor structuri sintactice corecte 0ce (or fi recunoscute# (alidate# de (iitorul parser1% $ceste descrierei de sintax iau forma unor &ramatici independente de context% 9eneratoarele de anali+oare sintactice pot fi folosite la de+(oltarea de parsere pentru o &am lar& de limba=e# de la limba=ul expresiilor cu parante+e pe care `l folose[te un calculator de birou p=n la cele mai complexe limba=e de pro&ramare% Bacc @ Bison este un asemenea &enerator care primind la intrare o descriere a unei &ramatici independente de context 093C1 construie[te un pro&ram `n C 0iar (ersiunile noi de Bison pot produce [i pro&rame `n CPP RR1 care (a anali+a sintactic un text conform cu re&ulile &ramaticii date% Bacc a fost de+(oltat de 6% C% Wo.nson [i de cole&ii s i de la $)X) Bell ;aboratories% $t=t Bacc c=t [i Bison permit s manipula]i `mpreun cu sti(a anali+orului sintactic o a doua sti( 0`n care se operea+ sincron cu prima la fiecare `ncepere@terminare de structur sintactic 1# aceast a doua sti( fiind destinat manipul rilor f cute de rutinele semantice% 0Fu uita]i c (om face traducere Is-ntax' dri(enI# deci condus de sintax 1% Fi[ierul de intrare pentru Bacc@Bison are urm toarea structur /
declara]ii C [i declara]ii parser 88 De&ulile &ramaticii [i ac]iunile semantice ata[ate 0care (or opera cu a doua sti( 1 88 Func]ii C 0adesea aici se include [i func]ia *ain# care nu e &enerat automat1

"e scurt/
declara]ii C [i parser 88 De&uli 88 Func]ii C

"rima sec]iune con]ine [i lista atomilor lexicali 0diferi]i de simple caractere1 care sunt a [tepta]i de c tre parser deoarece fac parte din limba=% )ot aici se include [i declara]ia simbolului ini]ial din &ramatic # acel neterminal care corespunde no]iunii de pro&ram complet% $ceast sec]iune poate con]ine [i specifica]ii pri(ind ordinea opera]iilor [i asociativitatea operatorilor. Ca efect# utili+atorul are o mai mare libertate `n proiectarea limba=ului# `n al&erea &ramaticii sale% $dunarea [i sc derea (or fi declarate asociati(e la 15

st=n&a [i cu cea mai mic preceden] `n timp ce ridicarea la putere este declarat ca fiind asociati( la dreapta [i a(=nd cea mai mare preceden] # cea mai mare prioritate%
8start program 8to9en LET INTEGER IN 8to9en !"I# IF T'EN EL!E END ('ILE D) RE*D (RITE FI 8to9en N+,-ER 8to9en IDENTIFIER *!!GN)# 8le:t .2. .1. 8le:t .3. .4. 8rig;t .5. 88 Reguli ale gramaticii cu ac]iuni 88 !u<rutine =

$ doua sec]iune a fi[ierului cuprinde &ramatica independent de context a limba=ului de anali+at% De&ulile 0numite produc]ii1 sunt aici separate prin IYI 0punct [i (ir&ul 1# simbolul Z ::= Z este `nlocuit de Z/Z # o e(entual parte dreapt (id este scris ca atare # neterminalii sunt scri[i cu minuscule iar terminalii din mai multe simboluri 0cum este semnul atribuirii1 cu ma=uscule% Demarca]i o anumit simplificare a &ramaticii datorit separ rii informa]iilor despre prioritatea operatorilor de restul &ramaticii% 0Constructorii de compilatoare cu experien] [tiu c lu=nd `n considerare prioritatea operatorilor# &ramatica expresiilor aritmetice se scrie cu mai multe re&uli dec=t `n exemplul nostru%1
Declaratiile anterioare 88 program : LET declarations IN commands END $ declarations : 43 empt> 34 % INTEGER id seq IDENTIFIER ... $ id seq : 43 empt> 34 % id seq IDENTIFIER . . $ commands : 43 empt> 34 % commands command .$. $ command : !"I# % RE*D IDENTIFIER % (RITE e&p % IDENTIFIER *!!GN)# e&p % IF e&p T'EN commands EL!E commands FI % ('ILE e&p D) commands END $ e&p : N+,-ER % IDENTIFIER % e&p .6. e&p % e&p .=. e&p % e&p .7. e&p % e&p .1. e&p

17

$ 88 !u<rutine =

% e&p .2. e&p % e&p .3. e&p % e&p .4. e&p % e&p .5. e&p % ./. e&p .0.

$ treia sec]iune din fi[ierul cu specifica]ii Bacc const `ntr'o colec]ie de func]ii scrise `n limba=ul C% "rintre ele se recomand s existe func]ia main() care (a apela func]ia yyparse(). Func]ia yyparse() este de fapt subrutina produs de &enerator 0pe ba+a specifica]iilor de mai `nainte1 [i este cea care (a conduce anali+a sintactic % 2n ca+ de eroare ea (a `ncerca s apele+e func]ia yyerror() pentru a semnala [i prelucra eroarea% $ceast func]ie --parse01 e l sat s fie scris de pro&ramator# ceea ce confer flexibilitate% 3at ni[te exemple simple cum ar putea ar ta func]iile main01 [i --parse01/
declara]ii C [i declara]ii parser 88 De&ulile &ramaticii 88 main/ int argc c;ar 3arg?[] 0 @ e&tern FILE 3>>in$ 11arg?$ 22argc$ >>in = :open/ arg?[A] .r. 0$ >>de<ug = B$ 43 errors = A$ 34 >>parse /0$ C >>error /c;ar 3s0 43 =alled <> >>parse on error 34 @ 43 errors 11$ 34 print: /D8sEnD s0$ C

Fot / Variabila errors (a num r erorile din timpul anali+ei sintactice% "ute]i renun]a la ea dac nu dori]i acest lucru% !ac totu[i dori]i s'o folosi]i# elimina]i comentariile de pe r=ndurile unde se fac referin]e la ea [i nu uita]i s'o declara]i ca (ariabil &lobal a pro&ramului `n sec]iunea declara]iilor C% 0 int errors; 1 !ar pentru a nu complica acest exemplu minimal ('a[ recomanda ca `n prima fa+ s renun]a]i la ea% "arserul# a[a cum este &enerat pe ba+a specifica]iilor de p=n acum# nu &enerea+ nimic la ie[ire# nici m car arborele sintactic% $cesta este `ns implicit construit `n timpul anali+ei% "e m sur ce anali+a pro&resea+ # parserul crea+ ni[te structuri interne care corespund sintaxei pro&ramului anali+at% Depre+entarea aceasta intern se ba+ea+ pe p r]ile drepte 15

ale re&ulilor &ramaticii% C=nd o parte dreapt a unei produc]ii 0re&uli1 este recunoscut ea e `nlocuit cu partea st=n& corespun+ toare% ,pera]ia se nume[te reducere. Vom spune c partea dreapt a re&ulii a fost redus\ la neterminalul din st=n&a re&ulii% $cesta la r=ndul s u este candidat la a fi&ura `n partea dreapt a unei alte re&uli [i a[a mai departe p=n c=nd `ntre&ul pro&ram este redus la simbolul de start al &ramaticii# semn c anali+a a reu[it cu succes% Compilarea fi[ierului surs de mai sus# simple.y se face cu Bacc# tast=nd comanda/ -acc '(d simple%sau pe un sistem ;inux pe care este instalat Bison# cu comanda/ bison '(d simple%sau bison 'd( simple%%%%unde pute]i `nlocui pe simple%- cu numele fi[ierului dumnea(oastr % 2n urma prelucr rii se ob]ine un fi[ier cu extensia dubl %tab%c [i acela[i nume `naintea extensiei ca fi[ierul ini]ial% 2n exemplul nostru se (a numi simple%tab%c deoarece specifica] iile se numeau simple%-% <xtensia tradi]ional a fi[ierelor cu specifica]ii Bacc@Bison este -% Fi[ierul %tab%c astfel ob]inut poate fi compilat cu compilatorul de C de pe sistemul dumnea(oastr >nix @ ;inux% <l con]ine [i func]iile scrise de dumnea(oastr [i func]ia &enerat --parse01 care face anali+a% 6istemul de ,perare ;inux (ine cu compilatorul 9CC# iar linia de comand necesar pentru a compila sursa %c (a fi/ &cc 'c simple%tab%c %%% ceea ce duce la ob]inerea modulului obiect cu numele simple%tab%o % Fota]i [i faptul c `n urma folosirii Bacc @ Bison se mai &enerea+ un fi[ier# cu extensia % tab%. % $cesta con]ine defini]ii de constante care asi&ur transferul corect al informa]iilor `ntre anali+orul sintactic 0parserul1 &enerat de Bacc @Bison [i anali+orul lexical &enerat de Flex @ ;ex % 3deea este c fiecare tip de atom lexical (a a(ea un num r# iar aceste numere definite [i a[teptate de parserul produs de Bacc @ Bison trebui s 'i (in de la anali+orul lexical% $cesta trebuie deci [i el s le cunoasc # ceea ce (a face inclu+=nd `n sursa sa fi [ierul cu extensia %tab%. &enerat de Bacc @ Bison% Fu c uta]i Bacc pe sistemele ;inux% Bacc este distribuit `mpreun cu sistemele >nix% 6istemele ;inux# oferite sub licen]a 9F> 9"; de c tre Free 6oftAare Foundation 3nc%# au `n distribu]ie Bison `n loc de Bacc% Bison este un produs al Free 6oftAare Foundation% "entru mai multe informa]ii despre folosirea Bacc @ Bison ( ru& m fie s c uta]i `n anexele c r]ii de fa] # fie s consulta]i pa&ina de manual pentru bison folosind comanda/ man bison 18

*ai pute]i citi 0dac le & si]i R1 lucr rile/ I"ro&rammin& >tilities and ;ibraries ;D "arsin&I de $%V%$.o [i 6%C%Wo.nson publicat `n Computin& 6ur(e-s `n iunie 1947 [i documentul IB36,F t.e Bacc'compatible "arser 9eneratorI# de C.arles !onnell- [i Dic.ard 6tallman% 2n urma complet rii tuturor celor trei sec]iuni ale fi[ierului Bacc# acesta (a ar ta ca mai =os/
43 Declaratii 34 8start program 8to9en LET INTEGER IN 8to9en !"I# IF T'EN EL!E END ('ILE D) RE*D (RITE FI 8to9en N+,-ER 8to9en IDENTIFIER *!!GN)# 8le:t .2. .1. 8le:t .3. .4. 8rig;t .5. 88 program : LET declarations IN commands END $ declarations : 43 empt> 34 % INTEGER idFseq IDENTIFIER ... $ idFseq : 43 empt> 34 % idFseq IDENTIFIER . . commands : 43 empt> 34 % commands command .$. $ command : !"I# % RE*D IDENTIFIER % (RITE e&p % IDENTIFIER *!!GN)# e&p % IF e&p T'EN commands EL!E commands FI % ('ILE e&p D) commands END $ e&p : N+,-ER % IDENTIFIER % e&p .6. e&p % e&p .=. e&p % e&p .7. e&p % e&p .1. e&p % e&p .2. e&p % e&p .3. e&p % e&p .4. e&p % e&p .5. e&p % ./. e&p .0. $ 88 43 !u<rutine 34 int main /int argc c;ar 3 arg?[] 0 @e&tern FILE 3>>in$ 11arg?$ 22argc$ >>in = :open/ arg?[A] DrD 0$

14

>>de<ug = B $ >>parse/0$ C >>error /c;ar 3s0 43 =alled <> >>parse on error 34 @ print/D8sEnD s0$ C

"entru a'l procesa urma]i indica]iile din pa&inile precedente sau exemplul de sesiune de lucru la terminal dat `n anex %

1:

Capitolul 5 6caner'ul 0$nali+orul lexical1 >n anali+or lexical 0en&l% scanner1 este un pro&ram capabil s descopere [i s clasifice por]iuni de text 0Icu(inteI1 conforme cu ni[te [abloane date% $nali+oarele lexicale pot fi ori scrise de m=n # ori &enerate automat de un &enerator de anali+oare lexicale# pe ba+a listei de [abloane pe care le au de recunoscut% !escrierea acestor [abloane se face sub form de expresii regulate% ;ex este un &enerator de anali+oare lexicale de+(oltat de *%<%;esH [i <%6c.midt de la $)X) Bell ;aboratories% ;ex prime[te la intrare un fi[ier con]in=nd descrierile atomilor de recunoscut# fiecare clas de asemenea atomi 0ex% numere# identificatori etc1 fiind caracteri+at # descris # de o expresie re&ulat % ;ex produce la ie[ire un `ntre& modul de pro&ram# scris `n C# care poate fi compilat [i linH'editat `mpreun cu alte module% 0"rintre aceste module este adesea [i cel &enerat de Bacc @Bison ' anali+orul sintactic ' precum [i alte componente ale unui compilator# sau interpretor%1 Fi[ierul de intrare pentru ;ex @Flex este or&ani+at similar cu cel pentru Bacc @Bison # tot `n trei sec]iuni separate prin LL% "rima con]ine declara]ii pentru scanner [i alte declara]ii C # a doua con]ine `n loc de &ramatic descrierile atomilor lexicali 0toHens1 sub form de expresii re&ulate [i ac]iunile pe care le (a face anali+orul `nt=lnindu'le 0de obicei returnea+ parser'ului codul atomului respecti(# e(entual [i alte informa]ii1 iar a treia con]ine restul de subrutine 0func]ii1 scrise `n C% Ca urmare a prelucr rii intr rii# ;ex produce un fi[ier cu extensia %c# `n care e definit func] ia yylex(), func]ie ce (a returna un `ntre& corespun+ tor fiec rui atom & sit% $ceast func] ie (a fi apelat de func]ia main() scris de pro&ramator `n ultima sec]iune# dac facem doar recunoa[terea [i prelucrarea atomilor lexicali sau de func]ia din modulul de anali+ sintactic # dac construim un compilator sau un interpretor% 2ntr'o asemenea situa]ie func] ia --lex01 ofer ser(icii 0(alori1 func]iei --parse01 din modulul &enerat de Bacc@Bison% Codurile di(ersilor atomi lexicali sunt la fel `n]elese de ambele func]ii --lex01 [i --parse01 deoarece fi[ierul &enerat de ;ex (a cuprinde [i directi(a de includere a fi[ierului .eader &enerat de Bacc# cu extensia %tab%.% 3ncluderea pic `n sarcina pro&ramatorului% $[a arat fi[ierul de intrare pentru ;ex/
declara]ii C [i declara]ii pentru scanner 88 !escrieri de atomi lexicali sub forma expresilor re&ulate [i ac]iuni 88 Func]ii C # subrutine

2n exemplul nostru# cea dint=i declara]ie care se (a scrie `n prima sec]iune a fi[ierului 19

pentru ;ex este cea de includere a fi[ierului simple%tab%.% # &enerat anterior de Bacc @ Bison% <l con]ine defin]ii pri(ind atomii multi'caracter% !e asemenea# prima sec]iune cuprinde o serie de defini]ii a=ut toare pentru scrierea expresiilor re&ulate din sec]iunea a doua% 2n exemplul nostru (om defini aici pe !393) ca o sec(en] de una sau mai multe cifre de la 0 la 9 iar pe 3! 0de la identificator1 ca fiind o liter urmat de una sau mai multe litere [i@sau cifre%
8@ 8C Ginclude Dsimple.ta<.;D DIGIT [A2H] ID [a2I][a2IA2H]3 43 T;e to9ens 34

88 !escrieri de atomi lexicali sub forma expresilor re&ulate [i ac]iuni 88 Func]ii C # subrutine

"or]iunea dintre 8@ [i 8C (a fi transcris f r modific ri `n textul &enerat% ,bser(a]i c am folosit directi(a Ginclude pentru a include fi[ierul simple%tab%. % 0'9 semnific o cifr din mul]imea de cifre de la 0 la 9% a'+ `nseamn o liter din mul]imea de litere de la a la + iar a'+0'9 un simbol din reuniunea celor dou mul]imi% ,bser(a]i c se scriu cu parante+ p trat nu cu acolad % 6telu]a de dup parante+a p trat `nseamn c pot fi oric=te elemente din acea mul]ime `n succesiune imediat # inclusi( nici unul% 2n cele din urm facem obser(a]ia c !393) repre+int orice cifr iar 3! orice identificator% $ doua sec]iune din fi[ierul ;ex 0acestea au extensia %lex1 este seria de perec i [ablon 0dat de expresia re&ulat 1 - ac]iune 0dat ca un corp de func]ie C# cuprins `n acolade1% Fiec rui fel de atom lexical 0toHen1 descoperit `i corespunde o ac]iune bine preci+at % Qirurile de unu sau mai mul]i di&i]i sunt recunoascute ca numere `ntre&i [i ca urmare# (aloarea constantei F>*B<D (a fi returnat parserului% Cu(intele re+er(ate ale limba=ului sunt sec(en]e de litere minuscule% 06e poate lucra [i cu ma=uscule dar ele (a fi necesar s fie tratate altfel RR1 6pa]iile albe# blanc'uri# tab'uri (or fi i&norate# nu (or produce nici o ac] iune% 2n dreptul lor `n loc de ac]iune este un comentariu% )oate celelalte caractere 0ceea ce `n ;ex se notea+ cu simbolul punct K.J1 (or fi pur [i simplu returnate a[a cum sunt% 6canerul plasea+ textul de parcurs `n (ariabila strin& yytext [i `ntotdeauna >>te&t[A] este caracterul curent de prelucrat%
declara]ii C [i declara]ii pentru scanner 88 D:=D @ return/*!!GN)#0$ C @DIGITC1 @ return/N+,-ER0$ C do @ return/D)0$ C else @ return/EL!E0$ C end @ return/END0$ C :i @ return/FI0$ C i: @ return/IF0$ C in @ return/IN0$ C integer @ return/INTEGER0$ C

20

let read s9ip t;en J;ile Jrite @IDC [ EtEn]1 . 88 !u<rutine =

@ return/LET0$ C @ return/RE*D0$ C @ return/!"I#0$ C @ return/T'EN0$ C @ return/('ILE0$ C @ return/(RITE0$ C @ return/IDENTIFIER0$ C 43 <lan9 ta< neJ line: eat up J;itespace 34 @ return/>>te&t[A]0$ C

,bser(a]i c fiec rui tip de atom lexical i se asocia+ de re&ul ac]iunea de a `ntoarce o (aloare `ntrea& 0constant 1 care semnific felul de atom lexical descoperit% ;ista urm toare cuprinde forma c=tor(a feluri u+uale de expresii re&ulate care ( pot fi de folos la a specifica atomii lexicali de recunoscut% Fota]i [i faptul c exist o (ariabil &lobal yylval , accesibil at=t scanerului &enerat de ;ex c=t [i parserului &enerat de Bacc @Bison% <a poate fi folosit pentru a transmite alte informa]ii le&ate de atomul al c rui cod tocmai a fost returnat%
. orice caracter cu excep]ia returului de car# <F)<D x [ablonul care se potri(e[te cu caracterul ZxZ rs concatenarea 0succesiunea1 a ce(a care se potri(e[te cu r [i ce(a ce se potri(e[te cu s r|s reuniunea sau alternati(aY se potri(esc cu ea at`t sec(en]ele de cractere corespun+ toare expresiei r c`t [i cele corespun+ toare expresiei s (r) la :el ca r $ parenteIele se :olosesc la grupare r* +ero sau mai multe sec(en]e de caractere ce se potri(ese cu r# unde r poate fi orice expresie re&ulat r+ una sau mai multe sec(en]e de caractere ce se potri(ese cu r# unde r poate fi orice expresie re&ulat [xyz] o clas 0mul]ime1 de caractere# `n acest exemplu se (or potri(i cu [ablonul doar caracterele ZxZ # Z-Z# Z+Z [abj-oZ] o clas 0mul]ime1 de caractere# `n acest exemplu se (or potri(i cu [ablonul doar caracterele ZaZ sau ZbZ #orice de la Z=Z la ZoZ inclusi(# sau Z[Z {NAME} expandarea unei 0macro1defini]ii anterioare# cu numele F$*< \X dac N este un ul dintre caracterele ZaZ# ZbZ# ZfZ# ZnZ# ZrZ# ZtZ sau Z(Z # atunci EK se interpretea+ con:orm standardului *N!I2= "[+xyz]+\"+foo" stringul: [&>I]D:oo

21

$ treia sec]iune a fi[ierului (a fi l sat necompletat `n acest exemplu% !ar `n ca+ul `n care ac]iunile anali+orului lexical presupuneau opera]ii complexe [i apeluri de func]ii utili+ator# aceste func]ii puteau fi ad u&ate aici# `n a treia sec]iune% $stfel scrierea ac]i' unilor de(ine mai clar iar unele detalii nesemnificati(e sunt ascunse `n func]iile 0subrutinele1 din a treia sec]iune% Compilarea fi[ierului ;ex se face cu una din comen+ile/ lex !i"ier.lex respecti( flex !i"ier.lex [i se (a ob]ine un fi[ier cu denumirea lex%--%c `n care e &enerat func]ia yylex(). ;a fiecare apel al func]iei --lex01# intrarea (a fi scanat 0parcurs 1 `n c utarea urm torului atom lexical [i se (a executa ac]iunea pro&ramat care'i corespunde% 2n ca+ul din exemplul nostru se (a returna codul atomului respecti(% Ve]i lucra cu ;ex dac a(e]i un sistem >nix de firm # deoarece ;ex este distribuit `mpreun cu sistemele >nix sau cu IclonaI acestuia# Flex# dac folosi]i un sistem ;inux% Flex este un produs al Free 6oftAare Foundation# 3nc%# distribuit sub licen] &neral public 9F> 9";% , sesiune tipic de lucru cu o ma[in ;inux# folosind Flex# Bison [i compilatorul 9CC pentru a ob]ine pro&ramul binar# executabil# 0in sursele C nerate de Flex [i Bison1 se desf [oar d nd comen+ile din lista de mai =os% $m presupus c cele dou fi[iere cu specifica]ii se numesc simple.y [i simple.lex% "romptul sistemului este notat cu I\I de obicei [i nu face parte din comand / \ bison 'd( simple.y \ &cc 'c simple.tab.c \ flex simple.lex \ &cc 'c lex%--%c \ &cc 'o simple simple.tab.o lex%--%o 'lm 'lfl "rima comand in(oc Bison pentru a &enera din sursa simple.y fi[ierul simple.tab.c [i fi [ierul simple.tab. care fi&urea+ ca inclus `n sursa ce V$ F3 &enerat de Flex @;ex% $ doua in(oc compilatorul &cc pentru a compila simple.tab.c [i a ob]ine modulul obiect simple.tab.o. $ treia &enerea+ din specifica]ia ;ex simple.lex sursa C cu nume standard lex%--%c% $ patra este comanda de compilare a acestei surse [i re+ult modulul obiect lex%--%o% 2n sf=r[it# cu ultima comand se lea& modulele obiect simple.tab.o [i lex%--%o `mpreun cu o serie de func]ii de bibliotec `n executabilul binar simple% $ten]ie la op]iunile din finalul liniei de comand % "e sistemul Ded Mat ;inux 5%2 cu care am rulat prima oar aceste exemple trebuie scrise neaparat op]iunile ';* ';F; dar cu minuscule RRR "e alte (ersiuni de sisteme ;inux este suficient doar prima op]iune ';* scris tot cu minusculeR "entru mai multe informa]ii despre comen+ile [i op]iunile ;ex @ Flex consulta]i pa&inile de 22

manual lex # flex de pe sistemul dumnea(oastr >nix @ ;inux# documenta]ia flexdoc [i citi] i lucrarea I;ex ' ;exical $nal-+er 9enerator de *% <% ;esH [i <% 6c.midt# `n ca+ul c=nd o pute]i & si% 2n final# `ntre&ul fi[ier simple%lex# pentru limba=ul 6imple# arat a[a/
8@ Ginclude Dsimple.ta<.;D 43 T;e to9ens 34 8C DIGIT [A2H] ID [a2I][a2IA2H]3 88 D:=D @ return/*!!GN)#0$ C @DIGITC1 @ return/N+,-ER0$ C do @ return/D)0$ C else @ return/EL!E0$ C end @ return/END0$ C :i @ return/FI0$ C i: @ return/IF0$ C in @ return/IN0$ C integer @ return/INTEGER0$ C let @ return/LET0$ C read @ return/RE*D0$ C s9ip @ return/!"I#0$ C t;en @ return/T'EN0$ C J;ile @ return/('ILE0$ C Jrite @ return/(RITE0$ C @IDC @ return/IDENTIFIER0$ C [ EnEt]1 43 <lan9 ta< neJ line: eat up J;itespace 34 . @ return/>>te&t[A]0$ C 88

Comentariile le pute]i scrie# bine`n]eles [i `n limba rom=n % "rimul ! "#e to$ens ! s'ar putea traduce prin !%tomii lexicali! de[i textual toHens `nseamn K=etoaneleJ% $l doilea @] blanH# tab# neA line/ eat up A.itespace ]@ s'ar traduce mai bine prin ! succesiunile formate cu spa]iu, tab sau enter & toate sunt consumate ! .

25

27

Capitolul 7 Contextul 6pecifica]iile din fi[ierele ;ex [i Bacc pot fi extinse pentru a manipula informa]ii dependente de context% !e exemplu# s presupunem c `n limba=ul 6imple impunem ca (ariabilele s fie declarate `nainte de a fi folosite% !in acest moti( parserul 0anali+orul sintactic1 trebuie s fie capabil s compare referin]ele la (ariabile cu declara]iile acestea# care sunt memorate `n (ederea (erific rilor% >n mod de a re+ol(a aceast problem este de a construi `nc din timpul parcur&erii sec] iunii de declara]ii a pro&ramului un fel de list de (ariabile [i de a (erifica apoi fiecare (ariabil `nt=lnit # compar=nd'o cu datele de pe list % , asemenea list este numit tabel\ de simboluri% )abelele de simboluri pot fi implementate folosind liste# arbori# 0arbori de c utare1 sau tabele'.as.% Vom modifica fi[ierul ;ex pentru a atribui (ariabilei &lobale yylval un strin& cu informa]ii de identificare de fiecare dat c=nd `nt=lnim o entitate 0atom1 a c rei set de caracteristici se (or p stra `n context% $semenea informa]ii (or fi# `n teorie# atribute prelucrate de gramatica cu atributre% *odulul )abel de 6imboluri 06)%.1 "entru a p stra informa]iile cerute de prelucr rile ce le (a face &ramatica cu atribute# (om construi o tabel de simboluri% )abela de simboluri cuprinde informa]ii de context pri(ind atributele di(erselor construc]ii 0sintactice1 scrise `n limba=ul de pro&ramare%2n particular# pentru (ariabile# cuprinde informa]ii despre tipul 0en&% type 1 [i domeniul de (i+ibilitate 0en&% scope 1 al (ariabilei% )abela de simboluri pe care o (om de+(olta (a fi un modul surs C care se (a include de c tre sursa &enerat 0de c tre Bacc @ Bison 1# cu oca+ia compil rii% Cititorul ambi]ios este in(itat ca# dup parcur&erea inte&ral a acestui (olum# s in(ente+e un limba= de specificare a tabelelor de simboluri [i un &enerator de surse C 0similar Bacc' ului [i Bison'ului1 pentru a &enera module asem n toare celui de mai =os pornind de la specifica]ii% 3nstrumentele cu care (a lucra (or fi e(ident Bacc @ Bison pentru anali+a sintactic [i &enerarea outputului prin ac]iuni semantice [i ;ex @Flex pentru anali+a lexical 1% )abela de simboluri pentru limba=ul 6imple const `ntr'o list identificatori# ini]ial (id % 3at declara]ia unui nod 0element1 al listei
struct s>mrec @c;ar 3name$

simplu `nl n]uit

de

43 name o: s>m<ol 2 numele sim<olului34

25

struct s>mrec 3ne&t$ 43 lin9 :ield 2 pointerul la alt element34 C$

apoi definirea tipului symrec [i ini]iali+area listei (ide cu un pointer nul


t>pede: struct s>mrec s>mrec$ s>mrec 3s>mFta<le = /s>mrec 30A$ s>mrec 3puts>m /0$ s>mrec 3gets>m /0$

[i cele dou opera]ii% "rima# putsym e cea care pune un identificator `n tabel
s>mrec 3 puts>m / c;ar 3s>mFname 0 @s>mrec 3ptr$ ptr = /s>mrec 30 malloc /siIeo:/s>mrec00$ ptr 27 name = /c;ar 30 malloc /strlen/s>mFname01B0$ strcp> /ptr 27 name s>mFname0$ ptr 27 ne&t = /struct s>mrec 30s>mFta<le$ s>mFta<le = ptr$ return ptr$ C

Comente+ pu]in codul func]iei putsym pentru e(entualii cititori mai pu]in familiari+a]i cu limba=ul C% !ac st p=ni]i bine C'ul# trece]i direct la pa&ina urm toare# la func]ia getsym% "rimul r=nd declar tipul re+ultatului dat de func]ie# care e pointer la un record 0element de list 1 symrec# deci e [i pointer la o list de asemenea elemente%
s>mrec 3

>rmea+ numele func]iei [i parante+a cu parametrul formal unic de tip pointer la caracter 0sinonim `n C cu strin&1# cu numele sym#name/
puts>m / c;ar 3s>mFname 0

Corpul func]iei `ncepe cu declararea (ariabilei locale ptr# pointer la tipul symrec/
@s>mrec 3ptr$

6e aloc spa]iu pentru structura 0record'ul1 propriu'+is [i pentru numele sym#name ce e destinat a fi stocat `n acea intrare din tabel %
ptr = /s>mrec 30 malloc /siIeo:/s>mrec00$ ptr 27 name = /c;ar 30 malloc /strlen/s>mFname01B0$

6e copie apoi numele dat ca parametru `n spa]iul alocat de=a# indicat de pointerul ptr-$name# stoc=nd astfel copia numelui `n tabel % 0Func]ia C strcp-01 este o (eritabil atribuire pentru strin&uri# capabil s copie al doilea strin& de la adresa sa# la adresa 28

primului strin&# dat ca prim parametru%1


strcp> /ptr 27 name s>mFname0$

<lementul nou creat# aflat la adresa ptr de(ine primul element din list iar capul de list sym#table (a arata acum spre el% )ot aceast adres a elementului nou [i simultan a listei este returnat de func]ia al c rei corp se `nc.eie cu obi[nuita acolad %
ptr 27 ne&t = /struct s>mrec 30s>mFta<le$ s>mFta<le = ptr$ return ptr$ C

3ar getsym returnea+ un pointer c tre intrarea din tabela de simboluri corespun+=nd unui identificator dat sau pointerul nul# +ero# dac nu l'a & sit%
s>mrec 3 gets>m / c;ar 3s>mFname 0 @s>mrec 3ptr$ :or /ptr = s>mFta<le $ ptr L= /s>mrec 30 A $ ptr = /s>mrec 30ptr2 7ne&t0 i: /strcmp /ptr 27name s>m name0 == A0 return ptr$ return A $ 43 sau e?entual return /s>mrec 30 A$ 34 C

2n final# modulul 6)%. ar putea ar ta a[a/


43 !T.; t;e s>m<ol ta<le module 34 43 De Dan #opa dupa *nt;on> * *a<> D=ompiler =onstruction using Fle& and -isonD 34 43 =ap M pg BM 34 struct s>mrec @ c;ar 3name$ 43 name o: s>m<ol 2 numele ?aria<ilei34 struct s>mrec 3ne&t$ 43 lin9 :ield 2 legatura la elementul urmator 34 C$ t>pede: struct s>mrec s>mrec$ s>mrec 3s>mFta<le = /s>mrec 30A$ s>mrec 3puts>m /0$ s>mrec 3gets>m /0$ 43 Doua operatii: punerea unui identi:icator in ta<ela ...34 s>mrec 3 puts>m / c;ar 3s>mFname 0

24

@ s>mrec 3ptr$ ptr = /s>mrec 30 malloc /siIeo:/s>mrec00$ ptr27name = /c;ar 30 malloc /strlen/s>mFname01B0$ strcp>/ptr27name s>mFname0$ ptr27ne&t = /struct s>mrec 30 s>mFta<le$ s>mFta<le = ptr$ return ptr$ C 43 si a doua operatie: a:larea pointerul intrarii din ta<el corespunIator unui identi:icator. 34 s>mrec3 gets>m /c;ar 3s>mFname0 @ s>mrec 3ptr$ :or /ptr = s>mFta<le$ ptr L= /s>mrec 30A$ ptr = /s>mrec 30 ptr27ne&t0 i: /strcmp /ptr27name s>mFname0 == A 0 return ptr$ return A$ C

,bser(a]iu c func]ia caut `n lista sym#table parcur&=nd'o cu pointerul 0local1 ptr c=t (reme mai sunt elemente `n list deci pointerul e nenul% !ac strin&ul dat sym#name coincide cu strin&'ul din elementul de list curent# adresa acestuia este returnat % $ltfel se returnea+ un 0 0care e practic un pointer nul1% Func]ia strcmp%& compar strin&urile de la cele dou adrese%

*odific rile anali+orului sintactic 0parserului1 <ste necesar s modific m specifica]iile oferite Bacc'ului @ Bison'ului# astfel `nc=t s includem tabela de simboluri [i rutinele necesare introducerii [i c ut rii unui identificator `n (ederea (erific rii folosirii sale corecte# conforme contextului% $m ad u&at [i (ariabila pentru num rarea erorilor# errors# nedeclarat `n capitolul anterior% $d u&irile se fac `n sec]iunea de specifica]ii pe care Bacc @ Bison le (a copia direct `n sursa C &enerat # adic (or fi scrise la `nceput# `ntre 8@ [i 8C.
8@ Ginclude 6stdli<.;7 Ginclude 6string.;7 Ginclude 6stdio.;7 Ginclude D!T.;D Gde:ine OODE-+G B int errors$ install / c;ar 3s>mFname 0 @ s>mrec 3s$ 43 Include malloc necesar pt. s>m<ol ta<le 34 43 Include strcmp necesar pt. s>m<ol ta<le 34 43 Functii pentru a:isarea de mesaNe de eroare 34 43 ,odulul D!>m<ol Ta<leD 34 43 #entru de<ugging seteI ?aria<ila Oacc la ?aloarea B34 43 =ontor de erori 34

2:

s = gets>m /s>mFname0$ i: /s == A0 s = puts>m /s>mFname0$ else @ errors11$ print:/ D8s is alread> de:inedEnD s>mFname 0$ C C conte&t c;ec9/ c;ar 3s>mFname 0 @ i: / gets>m/ s>mFname 0 == A 0 print:/ D8s is an undeclared identi:ierEnD s>mFname 0$ C 8C Declaratii pentru #arser 88 Gramatica: reguli plus actiuni 88 !u<rutine =

!eoarece anali+orul lexical 0scanerul &enerat de ;ex @ Flex1 (a returna doar (alorile unor identificatori 0constante `ntre&i1 [i doar at=t# o structur de record semantic 0semantic static 1 este necesar pentru a transmite denumirea fiec rui identificator de (ariabil % $[a putem deosebi (ariabilele `nt=lnite deoarece altfel anali+orul lexical returnea+ doar o aceea[i (aloare a constantei 3!<F)3F3<D pentru orice (ariabil % 6imple%lex (a fi modificat astfel/
Declaratii = 8union @ 43 RE=)RD !E,*NTI= 34 c;ar 3id$ 43 #entru trans:erul numelor identi:icatorilor34 C 8start program 8to9en INT !"I# IF T'EN EL!E FI ('ILE D) END 8to9en 6id7 IDENTIFIER 43 !imple identi:ier 34 8le:t .2. .1. 8le:t .3. .4. 8rig;t .5. 88 Gramatica: reguli plus actiuni 88 !u<rutine =

2n continuare# &ramatica independent de context [i ac]iunile ei semantice sunt modificate pentru a include apeluri la func]iile install%& [i context#c eck%& . Fota]i c fiecare \n este o (ariabil Bacc care face referire la al n'lea record semantic# cel corespun+ tor celui de'al n'lea element din partea dreapt a unei produc]ii 0re&uli a &ramaticii1% $stfel (om putea prelucra# stoca# testa# denumirile di(er[ilor identificatori de (ariabile care apar `n re&ulile &ramaticii# `n di(erse po+i]ii 0date de ordinea sintactic 1% *etoda se aplic la orice fel de element sintactic 0nu numai identificator de (ariabil 1 a c rui propriet ]i# atribute# urmea+ s le prelucr m% Demarca]i c po+i]ia cu(=ntului 3!<F)3F3<D `n re&ula &ramaticii 29

corespunde ca num r cu (ariabila \n implicat `n ac]i'unea semantic # 0unde n este acela [i num r R 1%
Declaratiii pt. = si parser 88 ... declarations : 43 empt> 34 % INTEGER idFseq IDENTIFIER ... @ install/ PQ 0$ C $ idFseq : 43 empt> 34 % idFseq IDENTIFIER . . @ install/ PR 0$ C $ command : !"I# % RE*D IDENTIFIER @ conte&tFc;ec9/ PR 0$ C % IDENTIFIER *!!GN)# e&p @ conte&tFc;ec9/ PB 0$ C ... e&p : INT % IDENTIFIER @ conte&tFc;ec9/ PR 0$ C ... 88 !u<rutine =

!up modificare [i sal(area fi[ierului cu numele simple.y# Bison 0pe un sistem ;inux1 (a fi in(ocat cu una din comen+ile/ bison '(d simple.y bison 'd simple.y 2n aceast implementare arborele sintactic este creat implicit [i adnotat implicit cu informa]ii pri(ind situa]ia unei (ariabile/ dac ea este sau nu declarat 0deci poate sau nu furni+a o (aloare1 `n momentul c=nd ea este referit dintr'o expresie% 3nforma]iile care ar trebui s adnote+e arborele sintactic sunt `ns p strate direct `n tabela de simboluri% Cititorii interesa]i de o implementare care crea+ efecti( un arbore sintactic adnotat pot consulta lucrarea I$ Compact 9uide )o ;ex X BaccI de ).omas Fiemann# disponibil &ratuit pe 3nternet# pe site'ul epapers%com% Fot m totu[i c exemplele de acolo nu pot fi folosite pe un sistem ;inux f r unele modific ri% Vom `ncerca s public m `n anexa acestui (olum sau `n partea a doua [i unele surse corectate pentru Flex @ Bison 0deci destinate platformei ;inux1 pe care le'am rescris document=ndu'ne din lucrarea citat % *odific rile 6canner'ului 0anali+orului lexical1 Qi scanerul 0anali+orul lexical1 trebuie modificat pentru a returna denumirea 0sub form de strin& a %%%1 fiec rui identificator# ea fiind practic (aloarea semantic 0d%p%d%(% al semanticii statice1 asociat fiec rui identificator% $ceast (aloare semantic (a fi returnat printr'o (ariabil &lobal numit yylval. )ipul acestei (ariabile este un tip reuniune 0union ca `n C1 creat cu directi(a 'union plasat `n fi[ierul cu descrierea parserului% !up ca+ [i tipul 50

(alorii semantice de comunicat de la scaner la parser# aceasta (a fi plasat membru corespun+ tor ca tip al reuniunii% !ac declara]ia IunionI'ului (a fi
8union @ c;ar 3id$ C

`ntr'un

(aloarea semantic (a trebui copiat din (ariabila &lobal yytext 0 care con]ine `ntotdeauna textul utimului atom lexical1 `n yylval.id % !eoarece exemplul de mai =os folose[te func]ia strdup din biblioteca strin&%.# aceast bibliotec trebuie s fie [i ea inclus % Fi[ierul cu descrierea scanerului# care (a fi prelucrat de ;ex @ Flex # (a con]ine/
8@ Ginclude 6string.;7 43 :iind necesar strdup 34 Ginclude Dsimple.ta<.;D 43 cu de:initiile atomilor si cu >>l?al 34 8C DIGIT [A2H] ID [a2I][a2IA2H]3 88 D:=D @ return/*!!GN)#0$ C @DIGITC1 @ return/N+,-ER0$ C do @ return/D)0$ C else @ return/EL!E0$ C end @ return/END0$ C :i @ return/FI0$ C i: @ return/IF0$ C in @ return/IN0$ C integer @ return/INTEGER0$ C let @ return/LET0$ C read @ return/RE*D0$ C s9ip @ return/!"I#0$ C t;en @ return/T'EN0$ C J;ile @ return/('ILE0$ C Jrite @ return/(RITE0$ C @IDC @ yylval. !"#"($%ar"*)"s&r!'((yy&)x&)* return/IDENTIFIER0$C [ EtEn]1 43 eat up J;itespace 2 pentru a consuma al<itura <lancurile ta<2 . 88 @ return/>>te&t[A]0$C

urile 34

Depre+entarea intermediar *ulte compilatoare con(ertesc codul surs `ntr'o repre+entare intermediar `n cursul acestei fa+e de traducere [i (erificare a restric]iilor contextuale% "e aceast repre+entare intermediar operea+ &ramatica cu atribute [i optimi+atorul arborelui 0sau al repre+ent rii intermediare1% 2n exemplul nostru repre+entarea intermediar implicit este c.iar arborele sintactic% "ractic el este construit ramur cu ramur pe sti( # pe m sura parcur&erii% !e[i deocamdat el este doar implicit# cu mici modific ri de pro&ram el poate fi construit explicit# apel=nd pentru fiecare structur sintactic func]ii care creea+ nodul respecti( 51

sau modific repre+entarea% $lte solu]ii r sp=ndite pentru reali+area repre+ent rii intermediare includ arborii de sintax abstract # cod cu trei adrese# cunoscutele ^uadruple [i scrierea postfix 0operatorii se scriu dup operan+i1% 6unt folosite `n di(erse etape intermediare ale compil rii% 2n acest exemplu de implementare a limba=ului simple (om s ri peste etapa &ener rii repre+ent rii intermediare a pro&ramului 0deci [i peste optimi+area ei1 [i (om trece direct la &enerarea de cod% !e altfel principiile ilustrate mai departe la &enerarea de cod se pot aplica foarte bine [i la &enerarea de repre+ent ri intermediare 0de exemplu la &enerarea de ^uadruple1% 2n urma modific rilor indicate `n acest capitol# fi[ierele dumnea(oastr ar putea ar ta a[a/ 6imple%lex
8@ Ginclude 6string.;7 43 *ici este :unctia DstrdupD 34 Ginclude Dsimple.ta<.;D 43 De:initiile atomilor si >>l?al 34 8C DIGIT [A2H] ID [a2I][a2IA2H]3 88 D:=D @ return/*!!GN)#0$ C @DIGITC1 @ return/N+,-ER0$ C do @ return/D)0$ C else @ return/EL!E0$ C end @ return/END0$ C :i @ return/FI0$ C i: @ return/IF0$ C in @ return/IN0$ C integer @ return/INTEGER0$ C let @ return/LET0$ C read @ return/RE*D0$ C s9ip @ return/!"I#0$ C t;en @ return/T'EN0$ C J;ile @ return/('ILE0$ C Jrite @ return/(RITE0$ C @IDC @ >>l?al.id = /c;ar 30 strdup />>te&t0$ return /IDENTIFIER0$ C [ EnEt]1 43 eat up J;itespace 2 pentru a consuma al<itura <lancurile ta<2urile 34 . @ return/>>te&t[A]0$ C 88

6imple%43 Oacc4<ison :ile :or !imple 34 43 Dan #opa dupa *nt;on> * *a<e> =omp. =onstr Jit; Fle& and -ison cap M pg BM 43 = and parser declarations 34 34

52

8@ Ginclude 6stdli<.;7 43=ontine malloc :olosit de ta<. de sim<oluri !T.;34 Ginclude 6string.;7 43=ontine strcmp :olosit de ta<. de sim<oluri !T.;34 Ginclude 6stdio.;7 43 #entru mesaNele de eroare S 34 Ginclude D!T.;D 43 ,odulul cu Ta<ela de sim<oluri 34 Gde:ine OODE-+G B 43 For de<ugging 34 int errors$ install /c;ar 3s>mFname 0 @ s>mrec 3s$ s = gets>m /s>mFname0$ i: /s == A0 s = puts>m /s>mFname0$ else @ errors11$ print:/ D8s is alread> de:ined EnD s>mFname 0$ C C conte&tFc;ec9/c;ar 3 s>mFname 0 @ i: / gets>m/s>mFname0 == A 0 print: /D8s is an undeclared identi:ier EnD s>mFname0$ C 43 !ectiunea continua cu: #arser declarations 34 43 Deoarece scanerul generat de Le& ?a returna identi:icatori 34 43 iar noi ?om utiliIa o semantica statica o inregistrare 34 43 numita Dsemantic recordD e necesara pentru a stoca ?aloarea 34 43 iar IDENT este asociat cu acest Dsemantic recordD. 34 8C 8start program 8union @ 43 !E,*NTI= RE=)RD 34 c;ar 3id$ 43:or returning identi:iers 34 C 8to9en LET INTEGER IN 8to9en !"I# IF T'EN EL!E END ('ILE D) RE*D (RITE FI 8to9en *!!GN)# N+,-ER 8to9en 6id7 IDENTIFIER 43 !imple identi:ier 34 8le:t .2. .1. 8le:t .3. .4. 8rig;t .5. 88 program : LET declarations IN commands END $ declarations : 43 empt> 34 % INTEGER idFseq IDENTIFIER ... @ install/PQ0$ C $ idFseq : 43 empt> 34 % idFseq IDENTIFIER . . @install/PR0$ C $ commands : 43 empt> 34 % commands command .$. $

55

command : !"I# % RE*D IDENTIFIER @ conte&tFc;ec9 /PR0$ C % (RITE e&p % IDENTIFIER *!!GN)# e&p @ conte&tFc;ec9 /PB0$ C % IF e&p T'EN commands EL!E commands FI % ('ILE e&p D) commands END $ e&p : N+,-ER % IDENTIFIER @ conte&tFc;ec9 /PB0$ C % e&p .6. e&p % e&p .=. e&p % e&p .7. e&p % e&p .1. e&p % e&p .2. e&p % e&p .3. e&p % e&p .4. e&p % e&p .5. e&p % ./. e&p .0. $ 88 43 = su<routines 34 int main /int argc c;ar 3 arg?[] 0 @e&tern FILE 3>>in$ 11arg?$ 22argc$ >>in = :open/ arg?[A] DrD 0$ >>de<ug = B $ 43 errors = A $ 34 >>parse/0$ C >>error /c;ar 3s0 43 =alled <> >>parse on error 34 @ print/D8sEnD s0$ C

57

Capitolul 5 ,ptimi+area <ste teoretic posibil s transform m arborele de deri(are pentru a'i reduce dimensiunile sau pentru a oferi &eneratorului de cod oportunitatea de a produce un cod mai eficient% 2ntruc=t compilatorul din exemplul nostru nu produce 0dec=t implicit1 arborele# nu (om ilustra aceste transform ri de arbore% 2n sc.imb (om pre+enta asemenea transform ri sub forma codului surs corespun+ tor instruc]iunilor neoptimi+ate [i respecti( optimi+ate% $ceast pre+entare i&nor deliberat faptul c unele compilatoare fac dou feluri de optimi+ ri# unele asupra arboreluli altele asupra codului &enerat% $ceste dou feluri de optimi+ ri# nu se pot substitui una pe alta% 'valuarea constantelor din timpul compil rii `[i propune s precalcule+e tot ce se poate pe ba+a (alorilor constante cunoscute la momentul compil rii# care apar `n expresii% 3at cum s'ar transforma ele/
N := T 1 " 1 U $ m := M $ n := m 1 Q$ 227 227 N := BB 1 "$ m := M$ n := V$

'liminarea calculelor repetate din bucle# scoaterea lor `nafara buclei# repre+int o alt optimi+are% Demarca]i parante+a din ciclu ce (a trebui e(aluat inutil [i repetat%
J;ile / inde& 6 ma&im 0 do input sales$ ?alue := sale& 3 ("+ar,-'("+"&ax")$ output := ?alue$ inde& := inde& 1 B$ end$ (odul ar putea fi optimi)at *n felul urm\tor+ temp := / mar9Fup 1 ta& 0$ J;ile / inde& 6 ma&im 0 do input sales$ ?alue := sale& 3 &)+($ output := ?alue$ inde& := inde& 1 B$ end$

'liminarea variabilei contor+ Cea mai mare parte din timpul de calcul al pro&ramelor este ocupat cu execu]ia calculelor din bucle% ,ptimi+area buclelor este deci o `mbun t ' ]ire semnificati( % >+ual# (ariabila contor a buclei este folosit doar `n interiorul buclei% 2n acest ca+ este mai bine ca ea s poat fi stocat `ntr'un re&istru `n loc s fie stocat `n memorie% 2n plus# dac ea este folosit doar ca indice pentru un (ector 0ceea ce implic o `nmul]ire [i o adunare la fiecare rotire a buclei1 optimi+area const `n a ini]ia'li+a (ariabila cu adresa de `nceput a (ectorului [i a o IincrementaI cu lun&imea unui element de (ector% 55

, bucl /
For I := B to BA do *[I] := *[I] 1 E ,evine + For I := adresa primului element din * &o adresa ultimului element din * by dimensiunea unui element din * !o *[I] := *[I] 1 E

'liminarea subexpresiilor comune dintr'un [ir de expresii prin calcularea (alorii lor doar o sin&ur dat /
* := U 3 /-1=0$ D := Q 1 V 3 /-1=0$ E := * 3 /-1=0$ ,evine+ TE,# := - 1 =$ * := U 3 TE,#$ D := Q 3 V 3 TE,#$ E := * 3 TE,#$

-nlocuirea unor *nmul]iri cu opera]ii mia rapide+


R3& 227 & 1 & R3& 227 s;i:t le:t &

.tili)area identit\]ilor matematice+


a3< 1 a3c 227 a3/<1c0 a 2 < 227 a 1 / 2 < 0

Fu (om `n+estra implementarea noastr de 6imple cu un optimi+ator de cod%

58

Capitolul 8 *a[ini Virtuale >n calculator construit efecti( din componente electronice este considerat o ma[in de calcul real % <l exist fi+ic% !in punct de (edere al pro&ramatorul# setul de instruc]iuni ale acelui .ardAare define[te clar ma[ina de calcul% >n sistem de operare este un pro&ram construit peste resursele oferite de ma[ina real # pentru a fi &estionarul acestora [i pentru a oferi o serie de alte ser(icii# de exemplu apelurile de sistem% 6er(iciile oferite de sistemul de operare# practic instruc]iuni aparte ce pot fi&ura `ntr'un pro&ram sau altul# definesc de data aceasta o ma[in (irtual % <a nu exist fi+ic% Fu exist circuite electronice speciali+ate care s ofere acele ser(icii% >n limba= de pro&ramare pune la dispo+i]ie un set de date [i un set de instruc]iuni exprimabile printr'o anume sintax % >n .ardAare capabil s execute direct acele instruc] iuni asupra datelor ar fi un computer real% 2n teorie este posibil s (orbim de o ma[n "ascal# o ma[in 6c.eme sau una Fort.% Cea din urm e c.iar implementat `ntr'un cip speciali+at% "ractic# pentru pro&armator nu contea+ dac ma[ina este real sau (irtual % Cei care au trecut de la C la Wa(a au constatat c trecerea de la pro&ramarea unei ma[ini reale la pro&ramarea uneia (irtuale nu'i deran=a cu nimic% 3ar pentru pro&ramator ma[ina e sinonim cu limba=ul computerului% ;imba=ul de pro&ramare define[te practic un computer ima&inar# (irtual sau araeori real# cu care interac]ione+i pro&ram=ndu'l% ,rice ma[in (irtual # pro&ramabil # capabil s manipule+e date# trebuie s aib o modalitate de a stoca at=t datele c=t [i pro&ramul% !ac o implemente+i `n alt limba= trebuie s specifici `n acest alt limba= cum se execut instruc]iunile ma[ini (irtuale asupra datelor ei% !e obicei 0obicei care a fost preluat de limba=e interpretate ca Basic# Wa(a1 `ntre pro&ramator# care dialo&.ea+ cu o ma[in (irtual ba+at pe un limba= de ni(el `nalt [i ma[ina (irtual care e sistemul de operare se interpune o alt ma[in (irtual % Compilatorul limba=ului poate &enera altfel de cod 0b-tecode1 [i pe acesta trebuie s 'l rule+e cine(a% $ceast ma[in (irtual este a[a'+isul Irun'time en&ineI al limba=ului% Complexitatea acesteia poate (aria de la nimic 0ca+ul Fortranului [i al acelor compilatoare care &enerea+ cod direct pentru procesor sau pentru ma[ina (irtual care este sistemul de operare1 la acele sisteme extrem de sofisticate# a(=nd mana&er de memorie [i mecanisme de intercomunicare `ntre procese cum e ca+ul unor limba=e de pro&ramare concurente# de exemplu 6D% Dun'time s-stem'ul pentru limba=ul 6imple (a include o component de procesare capabil s execute cod# implementat ca un mic interpretor interior [i o +on de date `n care (alorile atribuite (ariabilelor sunt accesate printr'un deplasament raportat la `nceputul +onei% < practic un (ector% Fot / unele pro&rame utili+ator pot fi considerate de asemenea ca o clas aparte de ma[ini (irtuale% 54

).e 60tacH1 *ac.ine ' , ma[in (irtual cu sti( 0adaptare dup FiHlaus Tirt.# Algorithms + Data Structure = Programs "rentice'Mall# <n&leAood Clifs# F%W%# 1948%1 6'ma[ina este o ma[in cu sti( proiectat pentru a simplifica implementarea limba=elor cu structur de bloc% <a ofer o alcare dinamic sub forma unei sti(e de `nre&istr ri de acti(are% 0Care corespund# nota bene# blocurilor%1 $ceste `nre&istr ri de acti(are sunt le&ate `ntre ele pentru a permite tipi+area static [i con]in [i informa]iile de context necesare procedurilor% /rgani)area ma[inii+ 6'ma[ina const `n dou +one de stocare# una dedicat pro&ramului [i numit ( 0or&ani+at ca un (ector read'onl-1 [i o +on de date S 0or&ani+at ca o sti( 1% <xist patru re&i[triY un re&istru de instruc]iuni 01 care con]ine instruc]iunea ce trebuie interpretat # un re&istru IstacH'pointerI " care con]ine adresa ultimului element al sti(ei# 2(, acel Ipro&ram'counterI care con]ine adresa urm toarei instruc]iuni de adus `n (ederea interpret rii [i re&istrul `nre&istr rii de acti(are curente# %1, cel care con]ine adresa ba+ei `nre&istr rii de acti(are aferente procedurii care e `n curs de interpretare% Fiecare loca]ie din ( este capabil s stoc.e+e o instruc]iune% Fiecare loca]ie din S este capabil s stoc.e+e o adres sau un `ntre&% Fiecare instruc' ]iune const `n trei informa]ii# trei c=mpuri/ un cod al opera]iei [i doi parametri% Setul de instruc]iuni+ (-codurile formea+ limba=ul ma[in al 6'ma[inii% 6'codurile ocup fiecare c=te patru b-tes% "rimul b-te este codul opera]iei 0op'code1% <xist nou astfel de instruc]iuni 06'coduri1 de ba+ # fiecare cu un cod de opera]ie diferit% $l doilea b-te al 6' codului con]ine ori un +ero# ori un fel de offset lexical# ori un cod de condi]ie pentru instruc] iunile de salt condi]ionat% >ltimii doi b-tes lua]i `mpreun formea+ un `ntre& pe 18 bi]i cu rolul de operand% <l poate fi o constant 0Iliteral (alueI1# un offset al po+i]iei unei (ariabile pe sti( pornind de la ba+a# adresa loca]iei altui 6'cod# un num r de opera]ie 0RGR1# ori un alt num r special al c rui sens e (alabil doar pentru un 6'cod cu anumit cod de opera]ie% (omentarii+ < normal ca di(ersele feluri de instruc]iuni 06'coduri1 s se distin& prin codul opera]iei% , adunare e ce(a diferit de un salt# de exemplu% ;a r=ndul lor salturile condi] ionate pot fi condi]ionate de faptul c o (aloare este +ero# sau nu este +ero deci oricum a(em mai multe cate&orii de instruc]iuni de salt% $l doilea octet diferen]ia+ tocmai instruc] iunile din aceea[i familie# cu acela[i cod de opera]ie% 3nstruc]iunile pot s manipule+e [i adrese sau numere de 18 bi]i ori de 2 b-tes deci mai poate fi ne(oie de `nc doi b-tes suplimentari pentru corpul instruc]iunii% "ractica arat c la un asemenea limba= simplu nu e ne(oie de mai mul]i b-tes pentru un 6'code% )oate instruc]iunile# indiferent de codul de opera]ie din primul octet n'au ne(oie de mai mult de 5 octe]i pentru a a(ea `n continuarea op'code'ului informa]iile necesare% 6emantica# ac]iunea fiec reia dintre instruc]iuni este descris mai =os# folosind un amestec de limba= natural [i nota]ie formal % $ceast nota]ie inspirat din limba=ele de 5:

pro&ramare de ni(el `nalt este folosit pentru a preci+a sc.imb rile care au loc `n memoria de date [i `n re&istrele ma[inii cu sti( % ,bser(a]i c instruc]iunile de acces la date 0practic la (ariabilele locale ale procedurilor1 au ne(oie de un deplasament raportat la `nre&istrarea de acti(are curent 0arat a c=ta (ariabil local= e implicat 1 [i de diferen]a de ni(el dintre ni(elul referin]ei [i ni(elul declara]iei 0era posibil de exemplu ca (ariabila s fi fost declarat `ntr'o procedur exterioar # dar contea+ exact `n a c=ta deoarece aceasta determin po+i]ia ei pe sti( `n `nre&istrarea de acti(are corespun+ toare1% $pelurile de procedur au ne(oie de adresa codului apelat [i de asemenea de diferen]a dintre ni(elul referin]ei [i cel al declara]iei%
./s&r'$& o/ RE*D (RITE )#R AA *DD !+,+LT DIW ,)D EX LT GT LDFINT LDFW*R !T)RE =*L AN LN LN LN 0()ra/!s" AN 1o++)/&s I4) operations Input integer in to location N: !/N0 := Input )utput top o: stac9: )utput := !/T0$ T:= T2B Arithmetic and logical operations process and :unction return operation T:= *R2B$ *R:= !/T1R0$ #:= !/T1Q0 *DD: !/T2B0 := !/T2B0 1 !/T0$ T := T2B !+-TR*=T: !/T2B0 := !/T2B0 2 !/T0$ T := T2B ,+LTI#LO: !/T2B0 := !/T2B0 3 !/T0$ T := T2B DIWIDE: !/T2B0 := !/T2B0 4 !/T0$ T := T2B ,)D: !/T2B0 := !/T2B0 mod !/T0$ T := T2B TE!T EX+*L: !/T2B0 := i: !/T2B0 = !/T0 t;en B else A$ T:= T2B TE!T LE!! T'*N: !/T2B0 := i: !/T2B0 6 !/T0 t;en B else A$ T:= T2B TE!T GRE*TER T'*N: !/T2B0 := i: !/T2B0 7 !/T0 t;en B else A$ T:= T2B L)*D literal ?alue onto stac9: T:= T1B$ !/T0:= N L)*D ?alue o: ?aria<le at le?el o::set L <ase o::set N in stac9 onto top o: stac9 T:= T 1 B$ !/T0:= !/:/L *R01N01Q store ?alue on top o: stac9 into ?aria<le location at le?el o::set L <ase o::set N in stac9 !/:/ld *R01os1Q0:= !/T0$ T:= T 2 B call #R)= or F+N= at !2code location N declared at le?el o::set L !/T1B0:= :/ld *R0$ @ !tatic Lin9 C !/T1R0:= *R$ @ D>namic Lin9 C !/T1Q0:= #$ @ Return *ddress C *R:= T1B$ @ *cti?ation Record C #:= cos$ @ #rogram =ounter C T:= T1Q @ !tac9 Top C call procedure address in memor>: #)# address #+!' return address Y+,# to address *DD NN to stac9 pointer T := T1NN Y+,#: # := N Y+,#: i: !/T0 = = t;en #:= N$ T:= T2B

=*L D*T* G)T) Y,#FF*L!E

RTT A A NN AN =N

59

$ici diferen]a de ni(el static `ntre procedura curent [i cea apelat este notat cu ld% Cu os este notat offsetul 0deplasamentu1 `n cadrul `nre&istr rii de acti(are curente [i tot ld este diferen]a de ni(el static `ntre `nre&istrarea de acti(are curent [i `nre&istrarea de acti(are `n care (a fi stocat (aloarea% Func]ia f0ld#a1 este implementarea urm toarei expresii condi]ionale% , pute]i scrie ca o func]ie cu acolad daca dori]i% :/i a0 = i: i=A t;en a else :/i2B !/a00

3ma&ina]i'( c fiecare `nre&istrare de acti(are are la `nceputul ei# la adresa a# un pointer c tre precedenta `nre&istrare de acti(are% "ractic 60a1 (a fi adresa `nre&istr rii de acti(are precedente% 6e mer&e pe acest [ir de `nre&istr ri de acti(are `napoi# pas cu pas# p`n a=un&em la prima% $dresa ei este la ba+a sti(ei% 3unc]ionarea+ De&istrii ma[inii cu sti( sunt `ni]iali+a]i dup cum urmea+ /
# = A. @ #rogram =ounter 2 Indica instructiunea curentaC *R = A$ @ *cti?ation Record Z Indica inregistrarea de acti?are curentaC T = R$ @ !tac9 Top Z Wir:ul sti?eiC ![A] := A$ @ !tatic Lin9 Z Legatura staticaC ![B] := A$ @ !tatic D>namic Lin9 Z Legatura dinamicaC ![R] := A$ @ Return *ddress Z *dresa de reintoarcere C

*a[ina aduce periodic `n re&istrul 3D instruc]iunea indicat de re&istrul "C# incrementea+ re&istrul "C [i execut instruc]iunea% )otul se repet p`n c=nd "C'ul a=un&e s con]in +ero sau este `nt=lnit [i executat o instruc]iune M$;)% 2ntr'un pseudocod inspirat de "ascal#0parte a unei masini (irtuale1 ciclul s'ar scrie/
RE#E*T IR:= =/#0$ /3 Fetc; 30 #=:= #=1B$ interpret/IR0$ /3 E&ecute30 +NTIL IR = D'altD or #= = A

$ceast bucl numit [i Ifetc.'execute loopI are de f cut deci dou lucruri `nainte de a executa 0interpreta1 o instruc]iune/ s aduc op'codul ei `n re&istrul de instruc]iuni [i s po+i]ione+e contorul de pro&ram "C astfel ca el s indice octetul urm tor% $ici (a & si subrutina IinterpretI b-te'ul al doilea% Decuperarea acestor al doilea [i la ne(oie# al treilea [i al patrulea b-te din 6'codul instruc]iunii curente r m=n `n sarcina subrutinei IinterpretI% <a poate dup ca+ s aduc spre utili+are unu# doi sau trei dintre ace[ti b-tes sau c.iar pe niciunul# dar oricum (a face (a trebui s incremente+e re&istrul "C astfel `nc=t el s indice op'cod'ul urm tor% "ractic dup terminarea subrutinei IinterpretI "C'ul (a ar ta o adres cu 5 b-tes mai departe# ea fiind adresa urm toarei instruc]iuni% ,p'codul de aici (a fi `nc rcat `n 3D la urm torul Ifetc.I atunci c=nd se reia bucla% Qi tot a[a mai departe% *odulul I*a[ina Virtual cu 6ti( I# 6*%. 3mplementarea ma[inii cu sti( de care a(em ne(oie e dat `n continuare% 6etul de instruc]iuni implementate [i structura unei instruc]iuni sunt definite dup cum urmea+ / 70

43 )#ER*TI)N!: Internal Representation 34 enum codeFops @ '*LT !T)RE Y,#FF*L!E G)T) D*T* LDFINT LDFW*R RE*DFINT (RITEFINT LT EX GT *DD !+- ,+LT DIW #(R C$ 43 )#ER*TI)N!: E&ternal Representation 34 c;ar 3opFname[] = @D;altD DstoreD DNmpF:alseD DgotoD DdataD DldFintD DldF?arD DinFintD DoutFintD DltD DeqD DgtD DaddD Dsu<D DmultD Ddi?D DpJrD C$ struct instruction @ enum codeFops op$ int arg$ C$

*emoria este separat `n dou se&mente# un se&ment destinat codului [i altul destinat deopotri( sti(ei [i (ariabilelor locale create dinamic `n cursul execu]iei%
struct instruction code[HHH]$ int stac9[HHH]$

>rmea+ defini]iile re&i[trilorY contorul de instruc]iuni 0en&% Ipro&ram counterI1 pc# re&istrul de instruc]iuni ir, re&istrul indicator al `nre&istr rii de acti(are 0 en&% Iacti(ation recordI1 curente numit ar [i re&istrul care arat spre (=rful sti(ei# numit top% 2n pa&inile anterioare fusese numit ) dar este (orba de acela[i re&istru% <ste uneori numit [i stacH pointer ' indicator de sti( # din aceast cau+ fiind notat 6" la unele procesoare% De&istrul ar indic `nceputul por]iunii din sti( care (a corespunde ultimei proceduri acti(e% !e (ariabila c. (om a(ea ne(oie mai t=r+iu dar o declar m de=a aici%
int struct instruction int int c;ar pc = A $ ir $ ar = A $ top = A $ c; $

Ciclul Ifetc.'executeI se repet p=n la `nt=lnirea unei instruc]iuni speciale# numit M$;)# instruc]iune care exist [i la procesoarele reale%
?oid :etc;Fe&ecuteFc>cle/0 @ do @ 43 Fetc; 34 ir = code[pc11]$

71

43 E&ecute 34 sJitc; /ir.op0 @ case '*LT case RE*DFINT case (RITEFINT case !T)RE case Y,#FF*L!E case G)T) case D*T* case LDFINT case LDFW*R case LT case EX case GT

: print:/ D;altEnD 0$ <rea9$ : print:/ DInput: D 0$ scan:/ D8ldD [stac9[ar1ir.arg] 0$ <rea9$ : print:/ D)utput: 8dEnD stac9[top22] 0$ <rea9$ : stac9[ir.arg] = stac9[top22]$ <rea9$ : i: / stac9[top22] == A 0 pc = ir.arg$ <rea9$ : pc = ir.arg$ <rea9$ : top = top 1 ir.arg$ <rea9$ : stac9[11top] = ir.arg$ <rea9$ : stac9[11top] = stac9[ar1ir.arg]$ <rea9$ : i: / stac9[top2B] 6 stac9[top] 0 stac9[22top] = B$ else stac9[22top] = A$ <rea9$ : i: / stac9[top2B] == stac9[top] 0 stac9[22top] = B$ else stac9[22top] = A$ <rea9$ : i: / stac9[top2B] 7 stac9[top] 0 stac9[22top] = B$ else stac9[22top] = A$ top22$ <rea9$ : stac9[top2B] = stac9[top2B] 1 stac9[top]$ top22$ <rea9$ : stac9[top2B] = stac9[top2B] 2 stac9[top]$ top22$ <rea9$ : stac9[top2B] = stac9[top2B] 3 stac9[top]$ top22$ <rea9$ : stac9[top2B] = stac9[top2B] 4 stac9[top]$ top22$ <rea9$ : s&a$,[&o(-2]"#"s&a$,[&o(-2]"*"s&a$,[&o(]*" ""3*"4)& "$or)$&a"a $ 5"*3 top22$ <rea9$ : print:/ D8sInternal Error: ,emor> DumpEnD 0$ <rea9$

case *DD case !+case ,+LT case DIW case #(R

de:ault C C J;ile /ir.op L= '*LT0$ C

*a[ina (irtual de mai sus are ne(oie de o corectur deoarece tentati(a ei de a executa instruc]iunea "TD duce la calculul unui produs nu la cel al unei ridic ri la putere% Deali+area acestei corecturi este l sat pe seama cititorului# ca exerci]iu%

72

"entru depanarea buclei Ifetc.'executeI pute]i scrie [i urm toarele linii de pro&ram `n locul comentariului @] Fetc. ]@ sau imediat dup acesta%
print: / D#= = 8RQd IR.arg =8\d *R = 8RQd Top = 8Qd 8\d EnD pc ir.arg ar top stac9[top] 0$

*odific ri ale parserului 6unt necesare modific ri `n fi[ierul anterior cu specifica]ii Bacc@Bison astfel ca pro&ramul principal s apele+e ma[ina (irtual pentru a rula pro&ramul care a fost anali+at 0IparsatI1 cu succes% $d u&a]i `n sec]iunea *$3F a parserului 6imple%- linile/
print: / D#arse =ompletedEnD 0$ i: / errors == A 0 @ printFcode /0$ :etc;Fe&ecuteFc>cle/0$ C

2ntrea&a func]ie main din fi[ierul 6imple%- (a ar ta a[a/


43======================================================= ,*IN =======================================================34 main/ int argc c;ar 3arg?[] 0 @ e&tern FILE 3>>in$ 11arg?$ 22argc$ >>in = :open/ arg?[A] DrD 0$ 43>>de<ug = B$34 errors = A$ >>parse /0$ print: / D#arse =ompletedEnD 0$ i: / errors == A 0 @ printFcode /0$ :etc;Fe&ecuteFc>cle/0$ C C

$ceste modific ri (or permite s fie executat pe ma[ina (irtual &enerarea codului se ocup capitolul urm tor%

codul &enerat% !e

75

77

Capitolul 4 9enerarea codului "e m sur ce pro&ramul surs este parcurs 0de c tre parser1 el este tradus `ntr'o form intern % Frec(ent folosit este forma de arbore% $cesta poate fi creat explicit sau parcurs implict# ca o sec(en] de apeluri de subpro&rame% 2n exemplul nostru arborele (a fi implicit% "ot exista [i alte forme interne% ;a unele compilatoare# `nainte de codul obiect &enerat# exist o (ariant a lui `ntr'un limba= care seam n cu limba=ul de asamblare% Codul `n form intern este `n final transformat `n cod obiect de c tre &eneratorul de cod% )ipic# codul obiect este un pro&ram pentru o minuscul ma[in (irtual % $lteori el este c.iar cod pentru procesorul .ardAare al sistemului% "entru execu]ia pro&ramelor scrise `n 6imple (om folosi ma[ina (irtual descris anterior# format din trei se&mente 0de memorie1Y un segment de date# un segment de cod [i o stiv\# aceasta fiindu'ne util pentru e(aluarea expresiilor% ;a implement ri de limba=e care folosesc subpro&rame sti(a ser(e[te [i pentru controlul execu]iei acestora [i stocarea (alorilor locale% 6e&mentul de date este cel care stoc.ea+ (alorile (ariabilelor%Fiecare (ariabil are asociat o loca]ie `n care se (a stoca (aloarea ei% !eci o parte din acti(itatea &eneratorului de cod (a consta `n atribuirea de adrese pentru fiecare (ariabil % 6e&mentul de cod con]ine sec(en]a tuturor instruc]iunilor pro&ramului% Constantele din pro&ram sunt stocate tot `n se&mentul de cod# lucru posibil deoarece (alorile lor nu se sc.imb iar se&mentul de cod este din punct de (edere al ma[inii (irtuale Iread'onl-I% 6ti(a expresiilor este o sti( folosit `n special pentru a p stra (alorile intermediare care apar `n timpul e(alu rii expresiilor% !atorit pre+en]ei ei# ma[ina (irtual a limba=ului 6imple este numit o ma[in cu sti( sau 6'ma[in 0en&% 6tacH'mac.ine1% )raducerea declara]iilor !eclara]iile definesc contextul e(alu rii expresiilor% "entru a re+er(a spa]iul pe sti( necesar (ariabilelor (om folosi instruc]iunea !$)$ a ma[inii (irtuale# creat c.iar `n acest scop% Dolul ei este s I`mpin& I capul sti(ei mai departe l s=nd loc pe sti( pentru num rul de (ariabile cerut% 2n 6imple toate (ariabilele fiind de acela[i tip# spa]iul ocupat pe sti( este propor]ional cu num rul lor [i e suficient s d m acest num r ca parametru al instruc]iunii !$)$% <l (a fi p strat `n se&mentul de cod ca ar&ument al instruc]iunii !$)$% !ar (ariabilele (or fi stocate `n se&mentul de date% $cesta fiind practic un (ector declarat `n C# num r toarea (ariabilelor (a `ncepe cu 0# prima (ariabil ocup=nd po+i]ia 0# a doua po+i]ia 1# a treia po+i]ia 2 [%a%m%d% !eci se (a compila/
integer & > I. 2227 D*T* R iar integer n &. 2227 D*T* B

75

)raducerea instruc]iunilor 3nstruc]iunile de atribuire# if# A.ile# read [i Arite sunt traduse dup re&ulile de mai =os/
& := e&pr i: cond t;en !B else !R end J;ile cond do ! end cod pentru e&pr !T)RE K cod pentru cond Y,#FF*L!E LB cod pentru !B -R LR LB:cod pentru !R LR: LB: cod pentru cond Y,#FF*L!E LR cod pentru ! G)T) LB LR: INFINT K cod pentru e&pr )+TFINT

read K Jrite e&pr

,bser(a]i c anumite adrese cum sunt ;1 [i ;2 pentru if sau ;2 pentru A.ile nu sunt imediat disponibile# (aloarea lor fiind determinat de lun&imea unor se&(en]e de cod care n'au fost `nc &enerate% <le (or fi completate atunci c=nd (aloarea lor exact de(ine cunoscut % ,pera]ia se nume[te IbacH'patc.in&I [i (a fi executat de o subrutin care se apelea+ `n finalul compil rii structurii respecti(e% 2n exemplul nostru aceast subrutin se (a numi c.iar back#patc % )raducerea expresiilor <xpresiile (or fi e(aluate folosind sti(a% ;a traducerea lor se (or &enera instruc]iuni ale ma [inii (irtuale cum sunt ;! [i ;!?3F)% Codul pentru un operator (a fi &enerat dup codurile pentru operan+i% "ractic traducerea transform expresia obi[nuit `n forma ei polone+ postfixat 0cu operatorul dup operan+i1 iar e(aluarea se (a face de c tre ma'[ina (irtual care implementea+ re&ulile/ 11 constanta sau (ariabila se pune pe sti( [i 21 operatorul scoate din sti( c=]i operan+i are ne(oie# face calculul [i pune re+ultatul tot `n sti( % Cu aceste re&uli simpla parcur&ere a unei expresii duce la plasarea (alorii ei pe sti( % Ca o consecin] # pentru ma[ina (irtual # simpla execu]ie a codului asociat expresiei (a duce la punerea re+ultatului `n sti( % )raducerea se fece dup re&ulile/
constanta ?aria<ila LDFINT constanta LDFW*R ?aria<ila

78

eB op eR

cod pentru eB cod pentru eR cod pentru op

*odulul &enerator de cod / C9%. 6e&mentul de date `ncepe cu loca]ia 0 % De+er(area spa]iului `n se&mentul de date se (a face apel=nd func]ia data#location care (a returna adresa loca]iei nou re+er(ate% Variabila data#o!!set arat totdeauna urm toarea loca]ie liber `n se&mentul de date% 2ntruc=t datele ocup exact o loca]ie `n se&ment# tot ce are de f cut data#location este s returne+e adresa loca]iei curente libere [i apoi s incremente+e (ariabila data#o!!set.
int dataFo::set = A$ int dataFlocation/0 @ return dataFo::set11$ C

6e&emntul de cod are [i el loca]iile numerotate `ncep=nd cu +ero% $ici `ns alocarea de spa]iu se (a face apel=nd subrutina reserve#loc care (a returna adresa loca]iei & site% 0"rima loca]ie liber %1 !ac nu mai (rem s aloc m dar ne interesea+ la ce adres (a `ncepe sec(en]a de cod urm toare 0ca `n ca+ul `n care acolo ar fi o etic.et ;21 (om apela func]ia gen#label care nu face dec t s returne+e (aloarea adresei urm toarei loca]ii libere#dar f r s aloce spa]iul%
int codeFo::set = A$ int reser?eFloc/0 @ return codeFo::set11$ C int genFla<el/0 @ return codeFo::set$ C

Func]iile reserve#loc [i gen#label ne (or ser(i la bacH'patc.in&'ul codului% Func]iile gen#code [i back#patc sunt folosite `n procesul &ener rii codului% gen#code &enerea+ codul unei instruc]iuni `n po+i]ia curent 0code?offset1 `n se&mentul de cod% 2n sc.imb back#patc este folosit la a &enera complet ri ale codului la c=te'o adres re+er(at dinainte# adresa fiindu'i dat ca prim parametru%
?oid genFcode/ enum codeFops operation int arg 0 @ code[codeFo::set].op = operation$ code[codeFo::set11].arg = arg$ C ?oid <ac9Fpatc;/ int addr enum codeFops operation int arg 0 @ code[addr].op = operation$ code[addr].arg = arg$ C

74

7:

*odific ri ale modulului )abela de 6imboluri/ 6)%. Formatul articolelor din tabela de simboluri trebuie extins% <l (a con]ine pentru fiecare (ariabil din tabel [i offset'ul 0po+i]ia1 acesteia `n se&mentul de date% $ceasta e adresa +onei `n care (ariabila `[i p strea+ (aloarea% 3ar func]ia putsym de ad u&are a simbolului `n tabel (a fi [i ea extins pentru a `ndeplini sarcina de plasare a offset'ului `n articolul din tabel corespun+ tor (ariabilei%
struct s>mrec @ c;ar 3name$ 43 numele sim<olului 2 identi:icatorul ?aria<ilei 34 int o::set$ 43 o::set in segmentul de date 34 struct s>mrec 3ne&t$ 43 legatura cu urmatorul din lista 34 C$ ... s>mrec 3 puts>m /c;ar 3s>mFname0 @ s>mrec 3ptr$ ptr = /s>mrec 30 malloc /siIeo:/s>mrec00$ ptr27name = /c;ar 30 malloc /strlen/s>mFname01B0$ strcp> /ptr27name s>mFname0$ ptr27o::set = dataFlocation/0$ ptr27ne&t = /struct s>mrec 30s>mFta<le$ s>mFta<le = ptr$ return ptr$ C ...

*odific rile parserului 0anali+orului sintactic1/ 6imple%Complet m exemplul nostru anterior cu &enerarea de cod% Vom extinde defini]iile din fi' [ierele ;ex [i Bacc ale limba=ului 6imple astfel ca s &ener m cod pentru 6'ma[in % "entru `nceput (om modifica fi]ierele Bacc [i ;ex astfel ca (alorile constantelor s fie transmise de la scanner 0anali+orul lexical1 la parser 0anali+orul sintactic1% <l e acel care# prin re&uli semantice ata[ate re&ulilor sintactice# &enerea+ cod% Vom modifica defini]ia acelui Isemantic'recordI din fi[ierul Bacc astfel ca (aloarea constantelor s fie returnat ca parte a acestui Isemantic'recordI% Corespun+ toare celor dou etic.ete care apar `n codurile instruc]iunilor if [i A.ile (a exista o structur cu dou c=mpuri% 6e (a defini [i un tip special de atomi 0ItoHenI1 numit UlblsV corespun+ tor lui 3F [i TM3;<% <l ofer [i spa]iu de stocare pentru adresele etic.etelor ce's ad u&ate `n procesul de bacHpatc.in&% ne)lblrec e func]ia care aloc spa]iul necesar pentru a stoca (alorile etic.etelor necesare la bacHpatc.in&% Func]ia context#c eck (a prelua &enerarea de cod aferent opera]iei efectuate asupra unei (ariabile 0dar (a a(ea ne(oie [i de codul opera]iei de implementat R1% Codul e &enerat doar dac identificatorul exist `n tabel % 79

8@Ginclude 6stdio.;7 Ginclude 6stdli<.;7 Ginclude 6string.;7 34 Ginclude D!T.;D Ginclude D!,.;D Ginclude D=G.;D Gde:ine OODE-+G B int errors$

43 #entru I4) 34 43 #entru malloc :olosit aici si in !T.; 34 43 #entru strcmp :olosuit in ta<ela de sim<oluri !t.; 43 Ta<ela de !im<oluri 34 43 !2,asina 34 43 Generator de cod 34 43 #entru depanare 34 43 =ontor de erori incrementat de =G.; 34

struct l<s 43 #entru etic;etele de la i: si J;ile 34 @ int :orFgoto$ int :orFNmpF:alse$ C$ struct l<s 3 neJl<lrec/0 43 *lloca spatiu pentru etic;ete 34 @ return /struct l<s 30 malloc/siIeo:/struct l<s00$ C install / c;ar 3s>mFname 0 @ s>mrec 3s$ s = gets>m /s>mFname0$ i: /s == A0 s = puts>m /s>mFname0$ else @ errors11$ print:/ D8s is alread> de:inedEnD s>mFname 0$ C C conte&tFc;ec9/ enum codeFops operation c;ar 3s>mFname 0 @ s>mrec 3identi:ier$ identi:ier = gets>m/ s>mFname 0$ i: / identi:ier == A 0 @ errors11$ print:/ D8sD s>mFname 0$ print:/ D8sEnD D is an undeclared identi:ierD 0$ C else genFcode/ operation identi:ier27o::set 0$ C 8C 8union semrec 43 Record2ul semantic 34 @ int int?al$ 43 Waloarea cinstantei intregi 34 c;ar 3id$ 43 Identi:icatorul 34 struct l<s 3l<ls 43 *drese etic;etate pentru <ac9patc;ing34 C 8start program 43 Neterminalul de la care incepe analiIa e DprogramD 34 8to9en 6int?al7 N+,-ER 43 =onstante intregi 34 8to9en 6id7 IDENTIFIER 43 Identi:icatori 34 8to9en 6l<ls7 IF ('ILE 43 Etic;ete pentru <ac9patc;ing 34

50

8to9en !"I# T'EN EL!E FI D) END 8to9en INTEGER RE*D (RITE LET IN 8to9en *!!GN)# 8le:t .2. .1. 43 )peratorii asociaIa la stinga si au prioritate minima 34 8le:t .3. .4. 43 )peratorii asociaIa la stinga 34 8rig;t .5. 43 )peratorii asociaIa la dreapta si au prioritatea ma&ima34 88 43 Regulile gramaticii si *ctiunile semantice 34 88 43 !u<rutine scrise in =34

$nali+orul sintactic# parserul# este acum extins cu re&uli de &enerare [i `mbinare a por] iunilor de cod% 2n final# codul &enerat pentru instruc]iunile if [i A.ile trebuie s con]in adresele corecte pentru salturi% $cetsea sunt marcate cu etic.ete# `n re&ulile de traducere% !eoarece destina]iile exacte ale salturilor nu sunt cunoscute dec=t dup &enerarea codului `ntre&ii structuri# e ne(oie de aceast ad u&are a lor# numit backpatc ing 0ceea ce s'ar putea traduce prin Ipeticire `napoiI1% Valoarea exact a adresei destina]ie pentru salturi (a fi ad u&at 0ca un petec1 `n cod# dup ce# prin compilarea `ntre&ii instruc]iuni structurate se (a [ti precis ce adres e `n punctul (i+at# corespun+ tor etic.etei 0fie ea ;1 sau ;21% Bacc permite pentru fiecare re&ul sintactic s ad u& m ac]iuni semantice care (or &enera cod% *ai mult dec t at=t# pentru fiecare element 0terminal sau neterminal din re&ul 1 Bacc asocia+ o (ariabil special al c rui nume `ncepe cu \ [i continu cu num rul elementului din re&ul % Capul re&ulii beneficia+ [i el de o asemenea (ariabil # \\# f r num r% Consulta]i documenta]ia Bacc@Bison de pe sistemul dumnea(oastr # pentru a afla am nunte% "ute]i folosi aceste (ariabile locale procedurilor de anali+ sintactic pentru a stoca informa]ii semantice 0atribute1 despre elementul sintactic respecti(% !ac a(e]i de stocat mai multe informa]ii pute]i s folosi]i (ariabila ca pe adresa unei structuri de date ce (a con]ine informa]iile necesare% 6tructura de date o (e]i creea `ns dumnea(oastr prin alocare dinamic % C.iar [i declara]iile de (ariabile 0statice1 (or &enera cod/ codul &enerat de o declara]ie nu face dec=t s re+er(e loc `n se&mentul de date pentru (ariabila respecti( %
43 Declaratiile pentru = si #arser 34 88 program : LET declarations IN @ genFcode/ D*T* dataFlocation/02B 0$ commands END @ genFcode/ '*LT A 0$ OO*==E#T$ C $ declarations : 43 empt> 34 % INTEGER idFseq IDENTIFIER ... @ install/ PQ 0$ C $ idFseq : 43 empt> 34

51

% idFseq IDENTIFIER . . @ install/ PR 0$ C

3nstruc]iunile 3F [i TM3;< (or recur&e la bacHpatc.in&%


commands : 43 empt> 34 % commands command .$. $ command : !"I# % RE*D IDENTIFIER % (RITE e&p % IDENTIFIER *!!GN)# e&p % IF e&p T'EN commands EL!E commands FI % ('ILE C C D) END e&p commands @ genFcode/ G)T) PB27:orFgoto 0$ <ac9Fpatc;/ PB27:orFNmpF:alse Y,#FF*L!E genFla<el/0 0$

@ conte&tFc;ec9/ RE*DFINT PR 0$ C @ genFcode/ (RITEFINT A 0$ C @ conte&tFc;ec9/ !T)RE PB 0$ @ PB = /struct l<s 30 neJl<lrec/0$ PB27:orFNmpF:alse = reser?eFloc/0$ @ PB27:orFgoto = reser?eFloc/0$ C @ <ac9Fpatc;/ PB27:orFNmpF:alse Y,#FF*L!E genFla<el/0 0$ C

C C

@ <ac9Fpatc;/ PB27:orFgoto G)T) genFla<el/0 0$ C @ PB = /struct l<s 30 neJl<lrec/0$ PB27:orFgoto = genFla<el/0$ @ PB27:orFNmpF:alse = reser?eFloc/0$

Codul corespun+ tor expresiilor e &enerat de re&ulile de mai =os/


e&p : N+,-ER % IDENTIFIER % e&p .6. e&p % e&p .=. e&p % e&p .7. e&p % e&p .1. e&p % e&p .2. e&p % e&p .3. e&p % e&p .4. e&p % e&p .5. e&p % ./. e&p .0. $ 88 43 !u<programe = 34 @ genFcode/ LDFINT PB 0$ C @ conte&tFc;ec9/ LDFW*R PB 0$ C @ genFcode/ LT A 0$ C @ genFcode/ EX A 0$ C @ genFcode/ GT A 0$ C @ genFcode/ *DD A 0$ C @ genFcode/ !+- A 0$ C @ genFcode/ ,+LT A 0$ C @ genFcode/ DIW A 0$ C @ genFcode/ #(R A 0$ C

*odific rile $nali+orului ;exical# 06canerului1 , `ntrebare pe care ('o pune]i citind re&ulile de compilare a expresiilor [i semn turile 52

func]iilor implicate este de ce pentru F>*B<D (aloarea (ariabilei Bacc \1 este c.iar (aloarea numeric a constantei iar `n ca+ul unui identificator 03!<F)3F3<D1 este c.iar strin&ul format de literele identificatorului% ;a urma urmei de ce n'ar fi [i la num r la fel ca la identificator G 6 se transmit [irul cifrelor# de ce nu G Ceea ce nu am specificat este c acest comportament (a trebui preci+at express `n specifica]iile scanerului% Valoarea respecti( (a fi stocat `n record'ul semantic%
8@ Ginclude 6string.;7 43 :or strdup 34 Ginclude Dsimple.ta<.;D 43 :or to9en de:initions and >>l?al 34 8C DIGIT [A2H] ID [a2I][a2IA2H]3 88 @DIGITC1 @ >>l?al.int?al = atoi/ >>te&t 0$ return/INT0$ C ... @IDC @ >>l?al.id = /c;ar 30 strdup/>>te&t0$ return/IDENT0$ C [ EtEn]1 43 eat up J;itespace 34 . @ return/>>te&t[A]0$C 88

, func]ie pentru afi[area codului "entru a afi[a codul &enerat pute]i ad u&a la finalul modulului C9%. urm toarea func]ie% $pela]i'o dup &enerarea de cod# `nainte de a'l executa# pentru a (erifica codul &enerat% , serie de exemple de mici pro&rame `n 6imple [i codul &enerat la compilarea lor inten' ]ion m s le anex m acestui material%
?oid FprintFcode/0$ @ int i = A$ J;ile /i 6 codeFo::set0 @ print:/D8Qld: 82BAs8MldEnD i opFname[/int0 code[i].op] code[i].arg 0$ i11 C C

55

>n exemplu "entru a ilustra felul cum func]ionea+ &eneratorul de cod al compilatorului nostru pre+ent m un pro&ram `n 6imple [i codul &enerat
let integer n &. in read n$ i: n 6 BA t;en & := B$ else s9ip$ :i$ J;ile n 6 BA do & := T3&$ n := n1B$ end$ s9ip$ Jrite n$ Jrite &$ end Figura V.B: #rogram !imple

>n exemplu de cod produs `n urma compil rii/


A: data B: inFint R: ldF?ar Q: ldFint M: lt T: NmpF:alse U: ldFint V: store \: goto H: ldF?ar BA: ldFint BB: lt BR: NmpF:alse BQ: ldFint BM: ldF?ar BT: mult BU: store BV: ldF?ar B\: ldFint BH: add RA: store RB: goto RR: ldF?ar RQ: outFint RM: ldF?ar RT: outFint RU: ;alt B A A BA A H B B H A BA A RR T B A B A B A A H A A B A A

Figura V.R: =od generat

57

Capitolul : ,ptimi+area de cod dup &enerare C.iar [i dup &enerarea codului exist optimi+ ri care se mai pot face% Fu uita]i c por]i' unile de cod &enerat s'au al turat a[a cum impunea sursa pro&ramul de compilat dar nimic nu &arantea+ c `mbinarea lor este optim % !e asemenea anumite constante care apar `n instruc]iunile &enerate pot su&erea `nlocuirea `ntre&ii instruc]iuni cu alta mai scurt sau mai rapid % >nele `nmul]iri sau `mp r]iri# de exemplu cele cu 2 pot fi `nlocuite cu alte opera]ii# cum sunt cele de deplasare a bi]ilor% 3nstruc]iuni de adunare cu +ero # cele de `nmul]ire cu 1 [i alte opera]ii de(enite inutile din cau+a anumitor (alori ale constantelor pot fi `nlocuite ori cu F," 0no operation1 sau c.iar eliminate% $dunarea sau sc derea cu 1 beneficia+ [i ele de instruc]iuni speciale mai rapide# pe care ma=oritatea procesoarelor .ardAare le ofer % 3ar anumite opera]ii cu (ariabile pot fi `nlocuite cu opera]ii reali+ate cu a=utorul re&i[trilor procesorului# m rindu'se astfel (ite+a codului &enerat% "entru a'l optimi+a# `ntre&ul cod &enerat (a fi parcurs a(=nd la fiecare moment `n (i+or c=te(a instruc]iuni (ecine 0ca [i cum a]i (edea o camer pri(ind pe &aura c.eii1% !ac ele se potri(esc cu anumite [abloane cunoscute de optimi+ator 0 procesul e numit c.iar Ipeep.ole optimi+ationI ' Ioptimi+are tip &aura c.eiiI1 atunci acesta le (a `nlocui cu alte sec(en]e de cod mai rapide 0sau mai eficiente din alt punct de (edere# de exemplu mai scurte1% >n exemplu tipic este eliminarea unor sec(en]e ">6M E "," care nu fac dec=t s pun [i s scoat aceea[i (aloare din sti( sau inlocuirea acestora cu opera]ii de transfer `ntre re&istri 0dac sunt mai mul]i cu func]ii asem n toare1 sau `ntre re&i[tri [i memorie% Fu (om ilustra `n exemplul nostru de compilare a limba=ului 6imple asemenea te.nici de optimi+are% !e altfel limba=ul ma[in extrem de simplu al 6'ma[inii noastre nu ofer prea multe posibilita]i de a face asemenea optimi+ ri# fiind un limba= minimalist% Cu totul alta este situa]ia atunci c=nd se &enerea+ cod pentru un procesor .ardAare real# care este oferit de fabricant cu un set mult mai (ast de instruc]iuni# dintre care unele pot `nlocui uneori cu suces pe altele# oferind [i a(anta=e%

55

58

Capitolul 9 ;ecturi suplimentare 2n ultimele (ersiuni 015 sept% 2005 [i 25 feb% 20071 ale documentului care a stat la ba+a acestui (olum# document oferit de prof% $nt.on- $% $ab- prin 3nternet capitolul 9 nu cuprindea dec=t dou r=nduri care recomand alte materiale ' nenumite ' pri(ind ;ex [i Bacc precum [i lucr rile ' tot necitate ' scrise de un autor pe nume "ratt# pri(itoare la ma [inile (irtuale% Vom suplini aceast omisiune indic=nd alte materiale accesibile `n Dom=nia sau pe 3nternet pe care le'am selectat `n procesul elabor rii acestui (olum deri(at din lucrarea domnului $nt.on- $% $ab-% !espre 6%,% >F3N [i componentele sale# inclu+=nd Bacc [i ;ex pute]i consulta capitolul 11 al (olumui de mai =os# scris de Valentin Cristea [i colecti(ul s u de coautori% <xplica' ]ii suplimentare despre folosirea (ariabilelor \\ [i \1#\2 `n re&ulile semantice se & sesc la pa&ina 257% 4) 5alentin (ristea, %lexandru 2\noiu, 'ugenia 6alis), 0rina %t#anasiu, 7orina 8egreanu, Silviu (\linoiu, 3lorin 9aboescu - UNIX, 9ucure[ti 4::;, 'd."eora , 0S98 :<;-=>4-4>?-@ , carte accesibil # disponibil [i prin 3nternet dup ce `n prealabil fusese publicat de 3nternational ).omson `n 1998 apar]ine profesorului "%!%)err- de la D.odes >ni(ersit-% 2n anex este un `ntre& compilator pentru limba=ul Clan&# scris `n C% <xtrem de instructi( % ,fer un bun suport teoretic dar recomand alt &enerator de compilatoare# Coco@D% 6e poate & si c ut=nd numele profesorului )err- cu un motor de c utare% 2n prefa]a c r]ii sunt indicate site'urile/ .ttp/@@AAA%scifac%ru%ac%+a@compilers@ [i .ttp/@@cs%ru%ac%+a@.ome@cspt@compbooH%.tm% A) 2.,."erry, Compilers and Compiler Generators, 1#odes .niversity, 4::=, 2ublis#ed by 0nternational "#omson >rmea+ un concis dar frumos manual de folosire pentru ;ex [i Bacc# utili+abil cu pu]in effort [i pentru clonele lor de pe platforma ;inux# Flex'ul [i Bison'ul% <ra disponibil `n format pdf pe site'ul epapers%com% Compilatorul pre+entat acolo foloseste un arbore creat explicit nu implicit ca `n exemplul din acest (olum% $cest arbore poate fi exploatat de un e(aluator# interpretor'ul de arbori# ob]in`ndu'se un interpretor pentru limba=ul propus% $lt (ariant este &enerarea de cod pe ba+a arborelui% >n exerci]iu interesant este implementarea unui compilator ca cel din lucrarea amintit 0mai =os1 folosind o distribu]ie ;inux care include pro&ramele Flex [i Bison% ;) "#omas 8iemann, A Compact Guide to Lex & Yacc, epapers.com "entru cunosc torii de "ascal interesa]i s scrie f r &enerator un mic compilator putem 54

recomanda un (olum practic# de tipul Ilearn'b-'doin&I scris de un specialist `n fi+ic dar pasionat de compilatoare# domnul WacH T%Crens.aA% <xist di(erse (ersiuni pe 3nternet ale serialului s u despre scrieirea practic a unui compilator# fie ca ar.i(e +ip cu plain'text sau ca fi[ier pdf% $m a(ut la dispo+i]ie (ersiunea 1%: `n format pdf% < un mod interesant de a face cuno[tin] cu un compilator [i cu problemele reali+ rii acestuia% "unctul de (edere este cel al practicianului care nu'[i pierde mult timp cu teoria% Ceea ce face ca lectura unui (olum de teorie `npreun cu acesta s fie cu at=t mai interesant % @) Bac$ C. (rens#aD, Compiler Building Tutorial, ver. 4.E, %prill 44,A>>4. 2n cele din urm # dar poate cel mai citat# celebrul (olum scris de $lfred $.o# Da(i 6et.i [i Weffre- >llmann `n 19:8 [i republicat apoi `n 19::% 6e poate & si la unele biblioteci din Dom=nia% ?) %lfred %#o, 1avi Set#i [i Beffrey .llmann, (ompilers, 2rinciples, "ec#niFues and "ools, 4:E=, %ddison-Cesley, 1eading, Gassac#usetts.

5:

Capitolul 10 <xerci]ii <xerci]iile care urmea+ sunt (ariate ca dificultate% "entru fiecare se cere s determina]i ce modific ri trebuie f cute &ramaticii# tabelei de simboluri [i ma[inii cu sti( % 6unt c=te(a dintre exerci]iile oferite de prof% $%$%$ab- ele(ilor s i% 1% De'implementa]i tabela de simboluri sub form de arbore binar de c utare% 2% De'implementa]i tabela de simboluri ca tabel .as.% 5% De'implementa]i tabela de simboluri# &eneratorul de cod [i ma[ina cu sti( sub form de clase C11.0Foile (ersiuni de Flex [i Bison pot produce [i ele cod sub form de clase C11.1 7% <xtinde]i compilatorul cu extensiile date mai =os% <xtensiile cer modificarea scanerului pentru a manipula noii atomi [i modificarea parserului pentru a &estiona &ramatica extins % 0a1 !eclara]ii/ 6c.imba]i procesarea semanticii identificatorilor astfel `nc=t ace[tia s 0nu1 necesite declarare anterioar % 0b1 Constante [i (ariabile reale/ <xtinde]i tabela de simboluri astfel `nc=t subrutinele care'o actuali+ea+ s stoc.e+e [i atributul de tip pentru fiecare identificator% <xtinde]i rutinele semantice ale &eneratorului de cod astfel ca acesta s &enere+e codul corespun+ tor tipului de constante [i (ariabile pe care le `nt=lne[te# (ariabile pe care aceste rutine le primesc ca parametri% 0c1 2nmul]ire# `mp r]ire 0[i ridicare la putere R1% Face]i sc.imb rile necesare `n rutinele semantice pentru a se ocupa corect de &enerarea de cod% 0d1 3nstruc]iunile if [i D#ile+ Dutinele semantice trebuie s &enere+e propriile teste [i salturi% 0e1 "roceduri f r parametri/ )abela de simboluri trebuie extins pentru a manipula declara]ii imbricate iar rutinele semantice trebuie extinse pentru a &enera cod pentru asi&urarea transferului controlului la fiecare punct de apel [i de asemenea la `nceputul [i sf=r[itul corpului procedurii% 3ndica]ie/ 6e (a folosi re&istrul $D al ma[inii (irtuale [i instruc] iunile care operea+ cu el% ,p]ional pute]i ad u&a/ 0a1 >n interpretor pentru codul produs de compilator% 0b1 2nlocui]i parserul &.idat de tabele# cu un parser descendent recursi(% 5% <xtinde]i compilatorul% , descriere este 0sau a fost1 inclus `n dosarul cs580@compiler tools de pe site'ul cs%AAc%edu% "e scurt# sunt cerute urm toarele extensii/ 59

0a1 <xtinderea scanerului pentru a manipula noii atomi% Folosi]i un &enerator pentru a produce noile tabele% 0b1 !eclara]ii pentru (ariabile `ntre&i [i reale% 0c1 Constante `ntre&i# expresii cu `ntre&i# opera]ii de 3@, pentru `ntre&i [i de ie[ire pentru strin&uri% 0d1 3nstruc]iunea loop cu exit [i ad u&area lui else [i elsif la instruc]iunea if. 0e1 "roceduri recursi(e cu parametri% 0f1 !eclararea recordurilor [i utili+area c=mpurilor% 0&1 !eclararea (ectorilor [i utili+area elementelor din (ectori% 0.1 >tili+area modulelor [i folosirea identificatorilor cu calificare% 8% Compilatorul urm tor trebuie s 'l scrie]i complet# de la +ero% ;ista de mai =os enumer caracteristicile limba=ului# pre+ent=nd `nt=i un subset de ba+ absolut necesar% Celelalte caracteristici care urmea+ sunt op]ionale% 6etul de ba+ / 0a1 )ipurile `ntre&# real# boolean% 0b1 <xpresii simple cu `ntre&i reali [i (alori booleene folosind operatorii/ +6-"6*6"36 /o&6"a/!6"or6"abs6"+o!6"**6"767#6868#6#6"3# 0c1 ,pera]ii de intrare pentru (alori `ntre&i# reale [i booleene 0d1 ,pera]ii de ie[ire pentru strin&uri [i expresii `ntre&i# reali# (alori booleene% F r formatare% 0e1 6tructuri de bloc# inclu+=nd declara]ii de (ariabile locale [i de constante 0f1 $tribuirea 0&1 3nstruc]iunile if# loop [i exit 0.1 "roceduri [i func]ii f r ar&umente# cu re+ultat scalar# inclusi( imbricate [i cu (ariabile non'locale% 6etul op]ional/ Fu este tradus aici% 2l pute]i & si `n lucrarea ori&inal a prof% $%$%$ab-% Deamintim c un compilator scris de la +ero dar care &enerea+ cod pentru un procesor real *otorola & si]i `n (olumul lui Bac$ C. (rens#aD, Compiler Building Tutorial, ver. 4.E, %prill 44,A>>4, disponibil pe 3nternet%

80

$nexa $ ;imba=ul 6imple ' 3mplementarea complet $1% "arserul 6imple%!ac a]i reali+at fi[ierul cu specifica]ii Bacc@Bison# conform cu indica]iile din capitolele precedente# ar trebui s ob]ine]i un text similar cu cel de mai =os# cu excep]ia comentariilor% !ecoment=nd r=ndul /*yydebug = 1;*/ din func]ia main (e]i ob]ine la execu]ie mult mai multe detali despre func]ionarea parserului%
%{/************************************************************************* Compiler for the Simple language ***************************************************************************/ /*========================================================================= C Libraries, Symbol Table, Code enerator ! other C "ode =========================================================================*/ #in"lude $stdio%h& /* 'or (/) */ #in"lude $stdlib%h& /* 'or mallo" here and in symbol table */ #in"lude $string%h& /* 'or str"mp in symbol table */ #in"lude *ST%h* /* Symbol Table */ #in"lude *S+%h* /* Sta", +a"hine */ #in"lude *C %h* /* Code enerator */ #define --./01 1 /* 'or .ebugging */ int errors; /* /rror Count */ /*2222222222222222222222222222222222222222222222222222222222222222222222222 The follo3ing support ba",pat"hing 2222222222222222222222222222222222222222222222222222222222222222222222222*/ stru"t lbs /* Labels for data, if and 3hile */ { int for4goto; int for45mp4false; 6; stru"t lbs * ne3lblre"78 /* 9llo"ate spa"e for the labels */ { return 7stru"t lbs *8 mallo"7si:eof7stru"t lbs88; 6 /*2222222222222222222222222222222222222222222222222222222222222222222222222 (nstall identifier ! "he", if pre;iously defined% 2222222222222222222222222222222222222222222222222222222222222222222222222*/ install 7 "har *sym4name 8 { symre" *s; s = getsym 7sym4name8; if 7s == <8 s = putsym 7sym4name8; else { errors==; printf7 *%s is already defined>n*, sym4name 8; 6 6 /*2222222222222222222222222222222222222222222222222222222222222222222222222 (f identifier is defined, generate "ode 2222222222222222222222222222222222222222222222222222222222222222222222222*/

81

"onte?t4"he",7 enum "ode4ops operation, "har *sym4name 8 { symre" *identifier; identifier = getsym7 sym4name 8; if 7 identifier == < 8 { errors==; printf7 *%s*, sym4name 8; printf7 *%s>n*, * is an unde"lared identifier* 8; 6 else gen4"ode7 operation, identifier2&offset 8; 6 /*========================================================================= S/+9@T(C A/C)A.S =========================================================================*/ %6 %union semre" /* The Semanti" Ae"ords */ { int int;al; /* (nteger ;alues */ "har *id; /* (dentifiers */ stru"t lbs *lbls; /* 'or ba",pat"hing */ 6 /*========================================================================= T)B/@S =========================================================================*/ %start program %to,en $int;al& @1+0/A /* Simple integer */ %to,en $id& (./@T('(/A /* Simple identifier */ %to,en $lbls& (' CD(L/ /* 'or ba",pat"hing labels */ %to,en SB(E TD/@ /LS/ '( .) /@. %to,en (@T/ /A A/9. CA(T/ L/T (@ %to,en 9SS @)E /*========================================================================= )E/A9T)A EA/C/./@C/ =========================================================================*/ %left F2F F=F %left F*F F/F %right FGF /*========================================================================= A9++9A A1L/S for the Simple language =========================================================================*/ %% program H L/T de"larations (@ { gen4"ode7 .9T9, data4lo"ation78 2 1 8; 6 "ommands /@. { gen4"ode7 D9LT, < 8; --9CC/ET; 6 ; de"larations H /* empty */ I (@T/ /A id4seJ (./@T('(/A K%K { install7 LM 8; 6 ; id4seJ H /* empty */ I id4seJ (./@T('(/A F,F { install7 LN 8; 6 ; "ommands H /* empty */ I "ommands "ommand F;F

82

; "ommand I I I I

H SB(E A/9. (./@T('(/A { "onte?t4"he",7 A/9.4(@T, LN 8; CA(T/ e?p { gen4"ode7 CA(T/4(@T, < 8; (./@T('(/A 9SS @)E e?p { "onte?t4"he",7 ST)A/, L1 8; (' e?p { L1 = 7stru"t lbs *8 ne3lblre"78; L12&for45mp4false = reser;e4lo"78; TD/@ "ommands { L12&for4goto = reser;e4lo"78; /LS/ { ba",4pat"h7 L12&for45mp4false, O+E4'9LS/, gen4label78 8;

6 6 6 6 6 6

"ommands '( I CD(L/ .) e?p

{ ba",4pat"h7 L12&for4goto, )T), gen4label78 8; 6 { L1 = 7stru"t lbs *8 ne3lblre"78; L12&for4goto = gen4label78; 6 { L12&for45mp4false = reser;e4lo"78; 6 { gen4"ode7 )T), L12&for4goto 8; ba",4pat"h7 L12&for45mp4false, O+E4'9LS/, gen4label78 8;

"ommands /@.

6 ; e?p H @1+0/A { gen4"ode7 L.4(@T, L1 8; 6 I (./@T('(/A { "onte?t4"he",7 L.4P9A, L1 8; 6 I e?p F$F e?p { gen4"ode7 LT, < 8; 6 I e?p F=F e?p { gen4"ode7 /Q, < 8; 6 I e?p F&F e?p { gen4"ode7 T, < 8; 6 I e?p F=F e?p { gen4"ode7 9.., < 8; 6 I e?p F2F e?p { gen4"ode7 S10, < 8; 6 I e?p F*F e?p { gen4"ode7 +1LT, < 8; 6 I e?p F/F e?p { gen4"ode7 .(P, < 8; 6 I e?p FGF e?p { gen4"ode7 ECA, < 8; 6 I F7F e?p F8F ; %% /*========================================================================= +9(@ =========================================================================*/ main7 int arg", "har *arg;RS 8 { e?tern '(L/ *yyin; ==arg;; 22arg"; yyin = fopen7 arg;R<S, *r* 8; /*yydebug = 1;*/ errors = <; yyparse 78; printf 7 *Earse Completed>n* 8; if 7 errors == < 8 { print4"ode 78; fet"h4e?e"ute4"y"le78; 6 6 /*=========================================================================

85

--/AA)A =========================================================================*/ yyerror 7 "har *s 8 /* Called by yyparse on error */ { errors==; printf 7*%s>n*, s8; 6 /**************************** /nd rammar 'ile ***************************/

87

$%2% 3ndica]ii de lucru $m transcris mai =os comen+ile pe care (a trebui s le da]i sistemului dumnea(oastr ;inux% $m testat aceast sec(en] pe un DedMat ;inux 5%2 [i nu am & sit deosebiri fa] de comen+ile propuse de dl% $%$%$ab-% 6in&urele deosebiri au fost c promptul sistemului meu ;inux nu este IVI ci I\I 0de[i el se poate modifica folosind comanad prompt1 iar (ersiunea de compilator &cc folosit mai a(ea ne(oie de o op]iune `n linia de comand 0 'lfl1%
7 <ison 2d !imple.> sau 7 <ison 2d? !imple.> !imple.> contains QH s;i:t4reduce con:licts. 7 gcc 2c !imple.ta<.c 7 :le& !imple.le& 7 gcc 2c le&.>>.c 7 gcc 2o !imple !imple.ta<.o le&.>>.o 2lm 2l:l 7 !imple testFsimple #arse =ompleted A: data B B: inFint A R: ldF?ar A Q: ldFint BA M: lt A T: NmpF:alse H U: ldFint B V: store B \: goto H H: ldF?ar A BA: ldFint BA BB: lt A BR: NmpF:alse RR BQ: ldFint T BM: ldF?ar B BT: mult A BU: store B BV: ldF?ar A B\: ldFint B BH: add A RA: store A RB: goto H RR: ldF?ar A RQ: outFint A RM: ldF?ar B RT: outFint A RU: ;alt A

85

$%5% 6canerul/ 6imple%lex


/*************************************************************************** S"anner for the Simple language ***************************************************************************/ %{ /*========================================================================= C2libraries and To,en definitions =========================================================================*/ #in"lude $string%h& /* for strdup */ /*#in"lude $stdlib%h& */ /* for atoi */ #in"lude *Simple%tab%h* /* for to,en definitions and yyl;al */ %6 /*========================================================================= T)B/@ .efinitions =========================================================================*/ .( (T R<2TS (. Ra2:SRa2:<2TS* /*========================================================================= A/ 1L9A /UEA/SS()@S defining the to,ens for the Simple language =========================================================================*/ %% *H=* { return79SS @)E8; 6 {.( (T6= { yyl;al%int;al = atoi7 yyte?t 8; return7@1+0/A8; 6 do { return7.)8; 6 else { return7/LS/8; 6 end { return7/@.8; 6 fi { return7'(8; 6 if { return7('8; 6 in { return7(@8; 6 integer { return7(@T/ /A8; 6 let { return7L/T8; 6 read { return7A/9.8; 6 s,ip { return7SB(E8; 6 then { return7TD/@8; 6 3hile { return7CD(L/8; 6 3rite { return7CA(T/8; 6 {(.6 { yyl;al%id = 7"har *8 strdup7yyte?t8; return7(./@T('(/A8; 6 R >t>nS= /* eat up 3hitespa"e */ % { return7yyte?tR<S8; 6 %% int yy3rap7;oid8{6 /************************** /nd S"anner 'ile *****************************/

88

$%7 )abela de simboluri/ 6t%.


/*************************************************************************** Symbol Table +odule ***************************************************************************/ /*========================================================================= ./CL9A9T()@S =========================================================================*/ /*2222222222222222222222222222222222222222222222222222222222222222222222222 S-+0)L T90L/ A/C)A. 2222222222222222222222222222222222222222222222222222222222222222222222222*/ stru"t symre" { "har *name; /* name of symbol */ int offset; /* data offset */ stru"t symre" *ne?t; /* lin, field */ 6; typedef stru"t symre" symre"; /*2222222222222222222222222222222222222222222222222222222222222222222222222 S-+0)L T90L/ /@TA2222222222222222222222222222222222222222222222222222222222222222222222222*/ symre" *identifier; /*2222222222222222222222222222222222222222222222222222222222222222222222222 S-+0)L T90L/ (mplementationH a "hain of re"ords% 222222222222222222222222222222222222222222222222222222222222222222222222*/ symre" *sym4table = 7symre" *8<; /* The pointer to the Symbol Table */ /*======================================================================== )perationsH Eutsym, etsym ========================================================================*/ symre" * putsym 78; symre" * getsym 78; symre" * putsym 7"har *sym4name8 { symre" *ptr; ptr = 7symre" *8 mallo" 7si:eof7symre"88; ptr2&name = 7"har *8 mallo" 7strlen7sym4name8=18; str"py 7ptr2&name,sym4name8; ptr2&offset = data4lo"ation78; ptr2&ne?t = 7stru"t symre" *8sym4table; sym4table = ptr; return ptr; 6 symre" * getsym 7"har *sym4name8 { symre" *ptr; for 7 ptr = sym4table; ptr V= 7symre" *8 <; ptr = 7symre" *8ptr2&ne?t 8 if 7str"mp 7ptr2&name,sym4name8 == <8 return ptr; return <; 6 /************************** /nd Symbol Table **************************/

84

$%5 9eneratorul de cod/ C9%.


/*************************************************************************** Code enerator ***************************************************************************/ /*2222222222222222222222222222222222222222222222222222222222222222222222222 .ata Segment 2222222222222222222222222222222222222222222222222222222222222222222222222*/ int data4offset = <; /* (nitial offset */ int data4lo"ation78 /* Aeser;es a data lo"ation */ { return data4offset==; 6 /*2222222222222222222222222222222222222222222222222222222222222222222222222 Code Segment 2222222222222222222222222222222222222222222222222222222222222222222222222*/ int "ode4offset = <; /* (nitial offset */ int reser;e4lo"78 /* Aeser;es a "ode lo"ation */ { return "ode4offset==; 6 int gen4label78 /* Aeturns "urrent offset */ { return "ode4offset; 6 /* enerates "ode at "urrent lo"ation */ ;oid gen4"ode7 enum "ode4ops operation, int arg 8 { "odeR"ode4offsetS%op = operation; "odeR"ode4offset==S%arg = arg; 6 /* enerates "ode at a reser;ed lo"ation */ ;oid ba",4pat"h7 int addr, enum "ode4ops operation, int arg 8 { "odeRaddrS%op = operation; "odeRaddrS%arg = arg; 6 /*2222222222222222222222222222222222222222222222222222222222222222222222222 Erint Code to stdio 2222222222222222222222222222222222222222222222222222222222222222222222222*/ ;oid print4"ode78 { int i = <; 3hile 7i $ "ode4offset8 { printf7*%MldH %21<s%Wld>n*,i,op4nameR7int8 "odeRiS%opS, "odeRiS%arg 8; i==; 6 6 /************************** /nd Code enerator **************************/

8:

$%8 *a[ina cu sti( / 6*%.


/*************************************************************************** Sta", +a"hine ***************************************************************************/ /*========================================================================= ./CL9A9T()@S =========================================================================*/ /* )E/A9T()@SH (nternal Aepresentation */ enum "ode4ops { D9LT, ST)A/, O+E4'9LS/, )T), .9T9, L.4(@T, L.4P9A, A/9.4(@T, CA(T/4(@T, LT, /Q, T, 9.., S10, +1LT, .(P, ECA 6;

/* )E/A9T()@SH /?ternal Aepresentation */ "har *op4nameRS = { *halt*, *store*, *5mp4false*, *goto*, *data*, *ld4int*, *ld4;ar*, *in4int*, *out4int*, *lt*, *eJ*, *gt*, *add*, *sub*, *mult*, *di;*, *p3r* 6;

stru"t instru"tion { enum "ode4ops op; int arg; 6; /* C)./ 9rray */

stru"t instru"tion "odeRTTTS; /* A1@2T(+/ Sta", */ int sta",RTTTS; /*2222222222222222222222222222222222222222222222222222222222222222222222222 Aegisters 2222222222222222222222222222222222222222222222222222222222222222222222222*/ int p" = <; stru"t instru"tion ir; int ar = <; int top = <; "har "h; /*========================================================================= 'et"h /?e"ute Cy"le =========================================================================*/ ;oid fet"h4e?e"ute4"y"le78 { do { /*printf7 *EC = %Md (A%arg = %Xd 9A = %Md Top = %Md,%Xd>n*, p", ir%arg, ar, top, sta",RtopS8; */ /* 'et"h */ ir = "odeRp"==S; /* /?e"ute */ s3it"h 7ir%op8 {

89

"ase D9LT "ase A/9.4(@T

6 /*************************** /nd Sta", +a"hine **************************/

6 6 3hile 7ir%op V= D9LT8;

printf7 *halt>n* 8; brea,; printf7 *(nputH * 8; s"anf7 *%ld*, !sta",Rar=ir%argS 8; brea,; "ase CA(T/4(@T H printf7 *)utputH %d>n*, sta",Rtop22S 8; brea,; "ase ST)A/ H sta",Rir%argS = sta",Rtop22S; brea,; "ase O+E4'9LS/ H if 7 sta",Rtop22S == < 8 p" = ir%arg; brea,; "ase )T) H p" = ir%arg; brea,; "ase .9T9 H top = top = ir%arg; brea,; "ase L.4(@T H sta",R==topS = ir%arg; brea,; "ase L.4P9A H sta",R==topS = sta",Rar=ir%argS; brea,; "ase LT H if 7 sta",Rtop21S $ sta",RtopS 8 sta",R22topS = 1; else sta",R22topS = <; brea,; "ase /Q H if 7 sta",Rtop21S == sta",RtopS 8 sta",R22topS = 1; else sta",R22topS = <; brea,; "ase T H if 7 sta",Rtop21S & sta",RtopS 8 sta",R22topS = 1; else sta",R22topS = <; brea,; "ase 9.. H sta",Rtop21S = sta",Rtop21S = sta",RtopS; top22; brea,; "ase S10 H sta",Rtop21S = sta",Rtop21S 2 sta",RtopS; top22; brea,; "ase +1LT H sta",Rtop21S = sta",Rtop21S * sta",RtopS; top22; brea,; "ase .(P H sta",Rtop21S = sta",Rtop21S / sta",RtopS; top22; brea,; case PWR : stack[top-1] = stack[top-1] * stack[top]; top--; break; default H printf7 *%s(nternal /rrorH +emory .ump>n* 8; brea,;

H H

$[a cum am preci+at `n capitolele precedente# instruc]iunea "TD a ma[inii (irtuale trebuie s fac ridicare la putere nu `nmul]ire% "or]iunea din text care trebuie `nlocuit este e(iden]iat %

40

$%4 >n exemplu de pro&ram/ test?simple


let integer n &. in read n$ i: n 6 BA t;en & := B$ else s9ip$ :i$ J;ile n 6 BA do & := T3&$ n := n1B$ end$ s9ip$ Jrite n$ Jrite &$ end

Qi codul produs# de data aceasta al turate/


A: data B: inFint R: ldF?ar Q: ldFint M: lt T: NmpF:alse U: ldFint V: store \: goto H: ldF?ar BA: ldFint BB: lt BR: NmpF:alse BQ: ldFint BM: ldF?ar BT: mult BU: store BV: ldF?ar B\: ldFint BH: add RA: store RB: goto RR: ldF?ar RQ: outFint RM: ldF?ar RT: outFint RU: ;alt B A A BA A H B B H A BA A RR T B A B A B A A H A A B A A Figura V.R: =odul generat

41

$nexa ! 3nstalarea pro&ramelor Flex [i Bison "entru a putea experimenta folosirea Flex'ului [i Bison'ului trebuie s instala]i pro&rame pe computerul dumnea(oastr dotat cu ;inux% *ai ales dac nu familiari+at cu instalarea pro&ramelor sub ;inux sau dac ;inux'ul dumnea(oastr de la ma&a+in &ata instalat dar f r Flex [i Bison 0ceea ce se `nt=mpl `n alte <uropei [i `n 6>$1# acest capitol ( poate fi de folos% aceste sunte]i a (enit ] ri ale

$nexa descrie felul cum pute]i instala Flex'ul [i Bison'ul pe un computer dotat cu o distribu]ie ;inux care folose[te pac.ete D"*% 0Ded Mat "acHa&es1% $semenea distribu]ii ;inux sunt/ Ded Mat ;inux# *andri(a ;inux 0fost *andraHe ;inux1# "C ;inux ,6# ,penna ;inux# ;-coris# Corel ;inux 0o (ec.e distribu]ie care nu mai este de+(oltat 1 [i multe multe altele% "rima metod / <ste suficient s a(e]i acces la o consol [i pri(ile&ii de root 0mana&er de sistem1 pentru a putea instala pac.etele cu comanda rpm, dat la promptul 9+ G rpm 2+?; 6fi[ierul'pac.et'dorit7 unde Ufi[ierul'pac.et'doritV (a fi numele pac.etului pe care dori]i s 'l instala]i% 6e pot instala mai multe pac.ete cu aceea[i linie de comand # lucru util mai ales dac depind unele de altul 0ceea ce nu este ca+ul aici%1% $]i putea uneori dori s folosi]i alte combina]ii de sAitc.'uri `n comand # cum ar fi - v% sau" s ad u&a]i" --for$)% Consulta]i manualul cu comanda man rpm sau .elp'ul comen+ii rpm tast=nd r(+":%)l("|"+or) pentru a afla detalii despre folosirea rpm% !in cau+a numerelor de (ersiune numele pac.etelor rpm par complicate [i lun&i% "ruc util+ >nii utili+atori scriu doar `nceputul numelui pac.etului [i apas tasta )$B pentru ca sistemul s scrie continuarea automat% !ac sunt mai multe pac.ete cu nume similare `n acela[i director pute]i ob]ine lista lor cu comanda ls# dat `n directorul unde sunt pac.etele/ G ls 6pre:i&2pac;et73 2ncerca]i/ G ls :le&3 6au/ G ls <ison3

42

Cele de mai sus combinate cu ideea de substitu]ie ne permit s scriem o comand de instalare capabil s instale+e toate pac.etele al c ror nume `ncep cu un prefix dat% Folosi]i comen+i ca/ G rpm 2+?; ]ls :le&3] G rpm 2+?; ]ls <ison3] Bine`n]eles [i `n aceste linii de comand se pot ad u&a alte sAitc.'uri dec=t '>(. # a[a cum este --for$) citat mai sus% <l ( a=ut s reu[i]i o instalare care altfel ar fi e[uat# de exemplu din lipsa sincroni+ rii dintre lista pac.etelor din sistem [i fi[ierele efecti( existente% $cest truc este util atunci c`nd a(e]i de instalat un &rup mai mare de pac.ete cu nume asem n toare# prefixate la fel% !ar aten]ie/ risca]i s instala]i mai multe pac.ete dec=t a]i fi dorit dac prefixul este prea scurt% !ar exist [i alte instrumente capabile de a instala pac.ete rpm% >nul din ele este binecunoscuta clon de Forton Commander numit *idni&.t Commander 0mc1% 0nstalarea pac#etelor cu mc decurge astfel+ "ro&ramul mc este capabil s intre `n pac.etele rpm a[a cum intr [i `n directoare% Folosi] i tastele cu s &e]i pentru a ale&e pac.etul dorit [i tasta]i <nter `n dreptul unui pac.et pentru a'i (edea con]inutul% 6e intr cu <nter `n directoarele din pac.et a[a cum se intr `n directoarele obi[nuite%

45

<xemplu/ 2n ca+ul din fi&ur # tast=nd <nter se intr `n directorul @mnt# locul unde sunt de obicei montate mediile amo(ibile# printre care [i C!'D,*'ul% 3ntra]i la fel `n directorul @cdrom [i de acolo `n directorul cu rpm'uri%

$ici pute]i s parcur&e]i lista de pac.ete cu tastele cu s &e]i sau s c uta]i un pac.et cu C)D;'s# scriind `nceputul numelui% V opri]i pe r=ndul unde este fi[ierul dorit%

)ast=nd `nc o dat <nter con]inutul pac.etului de(ine (i+ibil% $rat urm toare% $cest con]inut ( este pre+entat ca [i cum ar fi un director % 47

ca `n ima&inea

$le&e]i scriptul 3F6)$;; [i tasta]i <nter pentru a `ncepe instalarea%

"entru a moderni+a un pac.et la o nou (ersiune s'ar fi ales scriptul >"9D$!<%

45

M<$!<D con]ine informa]ii importante despre pac.et%

Folosi]i tasta F5 pentru a le consulta `nainte de a instala pac.etul% $colo pot fi mai multe ecrane cu text# le pute]i face s defile+e folosind clasicele taste cu s &e]i% 48

2n timpul instal rii (om (edea un mesa= anun]=nd fa+a K"repairin&J apoi dou indicatoare de pro&res `n form de bare ori+ontale [i `n finalul un procent 100L care indic terminarea fiec rei etape% Vor ar ta a[a/ Prepairing: 1:flex ##################################### [100%] ##################################### [100%]

Fot / $lte distribu]ii folosesc alte comen+i pentru instalarea pac.etelor 0de exemplu apt' &et# emer&e [amd1% Consulta]i documenta]ia distribu]iei de ;inux pe care o folosi]i% 6ucces%

44

Construc]ia compilatoarelor folosind Flex [i Bison

Volumul se adresea+ at=t pro&ramatorilor pe platforma >F3N @ ;3F>N care doresc s se instruiasc `n construc]ia limba=elor de pro&ramare c=t [i liceenilor [i studen]ilor care (or s cunoasc modul cum se scrie un compilator folosind limba=ul C [i &eneratoarele de pro&rame Bacc [i ;ex sau clonele lor Flex [i Bison disponibile pe sistemele de operare din familia ;inux% "re+entarea pas cu pas a componentelor compilatorului unui limba= asem n tor cu C# numit 6imple# `mpreun cu explicarea clar a conceptelor folosite de autori la construc]ia limba=elor de pro&ramare [i subsistemelor unui compilator fac din aceast carte deopotri( un curs condensat de compilatoare c=t [i un `ndrumar practic pentru reali+area unui compilator cu aceste instrumente celebre/ Flex [i Bison% Volumul poate fi folosit ca material de studiu auxiliar ori ca `ndrumar de laborator `n cadrul cursului de translatoare sau compilatoare at=t `n mediul polite.nic c=t [i `n facult ]ile de informatic % *u pot s\ v\ descriu emo]ia scrierii primului progr\mel care va rula pe interpretorul dumneavoastr\ sau va !i compilat cu compilatorul dumneavoastr\. +i mai ales satis!ac]ia care o ve]i sim]i v\z,nd c\ ruleaz\ sau se compileaz\ "i se execut\ !\r\ erori. --o spune un !ost absolvent al primei serii de la o !acultate de .n!ormatic\/ serie n\scut\ prin trans!ormarea uneia din seriile de la o sec]ie a 0aculta]ii de 1atematic\. 2an 3opa

Cate&oria/ Construc]ia compilatoarelor 36BF 945'0'07015'5

4:

You might also like