fbenjih.web.elte.hufbenjih.web.elte.hu/fordítóprogramok/asd.docx · web viewmagasszintű...

Post on 23-Jul-2021

1 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Magasszintű programozási nyelvek

• Könnyebb programozni

• Közelebb a megoldandó problémához

• Platform független Gépi kód

• Gépközeli (numerikus utasításkódok, regiszterek, memóriahivatkozások)

• Erősen platform függő

• Optimalizált Fordítóprogramokat általában a kettő közötti átalakításra használjuk

Az assembly nyelvekben (assembler: assembly nyelvről gépi kódra fordít)

• A gépi kód utasításaihoz neveket (mnemonikokat) rendelünk

• A regiszterekre névvel hivatkozunk

• Az egyes memóriacímeket címekkel azonosítjuk

• Gyakran közbülső állomás a magasszintű nyelvről gépi kódra történő fordítása

Magasszintű nyelvek fordítóprogramjai: (compiler) gcc, javac, ghc... Assembly nyelvek fordítóprogramjai: (assembler) nasm, masm, gas... Nyelvek közötti fordítás: (translator) fortran => C, latex2html, dvips... Egyéb fordítóprogramok: latex, hardware leíró nyelvből áramkörök tervei

Fordítás: a forráskódot a fordítóprogram tárgyprogrammá alakítja. A tárgyprogramból a szerkesztés során futtatható állomány jön létre.

• Fordítási idő: amikor a fordító dolgozik

• Futási idő: amikor a program fut

Interpretálás: a forráskódot az interpreter értelmezi és azonnal végrehajtja

• A fordítási és futási idő nem különül el

Fordítás vs. Interpretálás

Fordítás Interpretálás

Gyorsabb végrehajtás Rugalmasabb (pl. utasítások fordítási időben történő összeállítása)

A forrás alaposabb ellenőrzése Minden platformon azonnal futtatható, ahol az interpreter rendelkezésre áll

Minden platformra külön kell fordítani Perl, php, javascript C++, ADA, Haskell

Fordítás és interpretálás egymásra építve(Pl. Java)

• A forráskód fordítása bájtkódra

• A bájtkód interpretálása virtuális géppel

Virtuális gép: olyan gépes szoftver megvalósítása, amelynek a bájtkód a gépi kódja

Fordítóprogram szerkezete: Forrásprogram => analízis => belső reprezentáció => szintézis => tárgyprogram

Forráskezelő:

• Bemenet: fájlok

• Kimenet: karaktersorozat

• Feladata o Fájlok megnyitása o Olvasás o Pufferelés

o Az OPrendszer-specifikus feladatok elvégzése o Ha a fordítóprogram készít listafájlt, akkor ezt is kezeli Példa: input.cpp => x = x + 1; Lexikális elemző:

• Bemenet: karaktersorozat

• Kimenet: szimbólumsorozat, lexikális hibák

• Feladata:

o Lexikális egységek felismerése, azonosító, konstans, kulcsszó Példa: x=x+1; => változó[x] operátor[=] változó[x] operátor[+] konstans[1] utasításvég

Szintaktikus elemző:

• Bemenet: szimbólumsorozat

• Kimenet: szintaxisfa, szintaktikus hibák

• Feladata:

o A program szerkezetének felismerése o Szerkezet ellenőrzése: megfelel-e a nyelv defijének?

Szemantikus elemző:

• Bemenet: szintaktikusan elemzett program (szintaxisfa, szimbólumtábla...) • Kimenet: szemantikusan elemzett program, szemantikus hibák • Feladata:

o Típusellenőrzés

o Változók láthatóságának ellenőrzése o Eljárások hívása megfelel-e a szignatúrának? Stb...

Kódgenerátor:

• Bemenete: szemantikusan elemzett program • Kimenet: tárgykód utasításai (pl. assembly, gépi kód)

• Feladata:

o A forrásprogrammal ekvivalens tárgyprogram készítése

Kódoptimalizáló:

• Bemenet: tárgykód

• Kimenet: optimalizált tárgykód

• Feladata:

o Pl. futási sebesség növelése, méret csökkentése

o Pl. felesleges utasítások megszüntetése, ciklusok kifejtése

• Optimalizáció végezhető o Az eredeti programon (szemantikus elemzés után) o A tárgykódon

A fordítás menetei

• Az egyes komponensek egymást követik (az egyik kimenete a másik bemenete)

• Ez nem jelenti azt, hogy pl. a lexikális elemzőnek be kell fejeződnie a szintaktikus elemzés előtt (a szintaktikus elemző meghívhatja a lexikálisat, amikor egy újabb szimbólumra van szüksége)

• Eredmény: egy utasításnak akár a tárgykódja is elkészülhet, amikor a következő utasítás még be sincs olvasva

• A kódoptimalizálásnál viszont jellemzően újra át kell olvasni az egész tárgykódot (akár többször is) A fordítás menetszáma: a fordítás annyi menetes, ahányszor a programszöveg (vagy annak belső reprezentációja) végig olvassa a fordító teljes fordítási folyamat során Lexikális elemzés ... forrás-kezelő => lexikális elemző (scanner) => szintaktikus elemző...

Elemzési lépések szétválasztva:

• Lexikális elemzés: megadható reguláris nyelvtannal (3-as)

• Szintaktikus elemzés: megadható környezetfüggetlen nyelvtannal (2-es)

• Szemantikus elemzés: környezetfüggő (1-es) (egy változó használatának helyessége függhet a deklarációjától)

Szétválasztás oka: ne használjunk egyszerű feladatokhoz bonyolult eszközöket

Reguláris nyelvtan (Chomsky 3): a szabályok a következők lehetnek:

Jobbrekurzív eset Balrekurzív eset

A -> a A -> a

A -> aB A -> Ba

A -> ε A -> ε

Reguláris kifejezés:

• Kifejező ereje azonos a reguláris nyelvtanokéval • Alapelemek:

o Üres halmaz

o Üres szöveget tartalmazó halmaz o Egy karaktert tartalmazó halmaz

• Konstrukciós műveletek:

o Konkatenáció o Unió | o Lezárás * Véges determinisztikus automaták (VDA):

• Kifejező ereje azonos a reguláris nyelvtanokéval és a reguláris kifejezésekével • Elemei:

o Ábécé o Állapotok halmaza o Átmenetfüggvények o Kezdőállapot o Végállapotok halmaza

VDA implementációja:

• Egymásba ágyazott if vagy case utasításokkal egy cikluson belül:

o Elágazunk a pillanatnyi állapot szerint o Ezen belül elágazunk a következő karakter szerint

o Az egyes ágakban beállítjuk a következő állapotot és kezdjük elölről

• Táblázattal:

o A táblázat soraihoz az állapotok, oszlopaihoz a karakterek vannak rendelve o Celláiban a következő állapotok sorszáma van

o A következő állapot a pillanatnyi állapot sorában és az olvasott karakter oszlopában van

Lexikális elemző működése:

• Mindig a lehető leghosszabb karaktersorozatot ismeri fel

• Az elemző megadásakor sorba rendezhetjük a szimbólumok definícióit, ha egyszerre több szimbólum is felismerhető, a sorrendben a korábbi lesz az eredmény. (kulcsszavak definícióját előre kell vinni)

Kulcsszavak és standard szavak:

• Kulcsszó: előre adott jelentésük van, ez nem definiálható felül, o ha véges determinisztikus automatával akarjuk felismerni, nagyon nagy méretű automatát kaphatunk.

o Jobb módszer táblázatban tárolni őket: ha a lexikális elemző egy azonosítót ismer fel megnézi, hogy benne van-e a táblázatban (ha igen akkor kulcsszó, egyébként azonosító)

• Standard szó: előre adott jelentésük van, de ez felüldefiniálható

Előre olvasás:

• Lexikális elemző időnként több karaktert is előre olvas a szimbólum felismeréséhez

Szemantikus értékek és szimbólumtábla:

• A felismert szimbólum fajtáján kívül továbbítani kell még a:

o Változót: a változó neve o Konstanst: a konstans értéke

• Ezekre a szemantikus elemzéshez és a kódgeneráláshoz van szükség

• A változókat és azok adatait a szimbólumtáblába kell felírni (általában a szintaktikus elemző teszi meg a vált. deklarációjának felismerésekor)

Direktívák:

• #include, #define, #ifndef, #endif

• célszerű egy előfeldolgozó fázis beiktatása a lexikális és a szintaktikus elemzés közé, ami o feljegyzi a makródefiníciókat o elvégzi a makróhelyettesítést

o meghívja a lexikális elemzőt a beillesztett fájlokra

o kiértékeli a feltételeket és dönt a kódrészletek beillesztéséről vagy törléséről

Hibatípusok és javítási lehetőségek:

• illegális karakter: karakter kihagyása, helyettesítése szóközzel

• elgépelt kulcsszó: LE azonosítónak ismeri fel, SZE javíthatja a hibát

• kihagyott szimbólum: csak a SZE tudja felismerni

• hibás számformátum: illegális karakternek lehet tekinteni

• befejezetlen megjegyzések és sztringek: egész program bejegyzésbe kerülhet

Szintaktikus elemzés ...lexikális elemző => szintaktikus elemző(parser) => szemantikus elemző ...

bemenet: szimbólumsorozat kimenet: szintaxisfa, szintaktikus hibák feladata:

• a program szerkezetének felismerése

• a szerkezet ellenőrzése: megfelel-e a nyelv definíciójának?

Környezetfüggetlen nyelvtan (Chomsky 2) A -> a alakú szabályok

Jelölés Jelentés

a,b,c Terminális szimbólum(lexikális elemek)

A,B,C Nemterminális szimbólum

X,Y,Z Terminális vagy nemterminális

x,y,z Terminális szimbólumok sorozata

α,β,γ Terminális vagy nemterminális szimbólumok sorozata

Levezetések és kapcsolódó fogalmak

Jelölés Jelentés

A -> a Szabály

A => a Egy lépéses levezetés (1 szabály alkalmazása)

A=>* a Nulla, egy vagy több lépéses levezetés

A =>+ a Legalább egy lépésből álló levezetés

Mondat: a startszimbólumból levezethető terminális sorozat (S =>* x) Mondatforma: a startszimbólumból jelből levezethető bármilyen sorozat (S =>* a) Részmondat: β az α1βα2 mondatforma részmondata, ha S =>* α1Aα2 => α1βα2 Egyszerű részmondat: β az α1βα2 mondatforma egyszerű részmondata, ha S =>* α1Aα2 => α1βα2

Követelmények:

• ciklusmentesség: nincs A =>+ A levezetés

• redukáltság: nincsenek felesleges nemterminálisok o minden nemterminális szimbólum előfordul valamelyik mondatformában o mindegyikből levezethető valamilyen terminális sorozat

• egyértelműség: minden mondathoz pontosan egy szintaxisfa tartozik

nem egyértelmű nyelvtan E -> e |E + E

Legbal levezetés: mindig a legbaloldalibb nemterminálist helyettesítjük

• S => AB => aaB => aab Legjobb levezetés: mindig a legjobboldalibb nemterminálist helyettesítjük

• S => AB => Ab => aab

Felülről lefelé elemzés: startszimbólumból indulva, felülről lefelé építjük a szintaxisfát. A mondatforma baloldalán megjelenő terminálisokat illesztjük az elemzendő szövegre

• Stratégiák:

o visszalépéses keresés (backtrack): ha nem illeszkednek a szövegre a mondatforma baloldalán megjelenő terminálisok lépjünk vissza és válasszunk másik szabályt => visszalépéses felülről lefelé elemzések

§ Lassú § Ha hibás a szöveg, az csak túl későn derül ki o Előre olvasás: olvassunk előre a szövegben valahány szimbólumot, ez

alapján döntsünk az alkalmazandó szabályról => LL elemzések Csak szűk nyelvosztályokra alkalmazható

Alulról felfelé elemzés: az elemzendő szöveg összetartozó részeit helyettesítjük nemterminális szimbólumokkal és így alulról, a startszimbólum felé építjük a fát

• Mit redukáljunk?

o Visszalépéses keresés (backtrack): ha nem sikerül eljutni a startszimbólumig, akkor lépjünk vissza és válasszunk másik redukciót => visszalépéses alulról felfelé elemzések

§ Lassú § Ha hibás a szöveg túl lassan derül ki o Precedenciák használata: az egyes szimbólumok között adjunk meg

precedenciarelációkat és ennek segítségével határozzuk meg a megfelelő redukciót => precedencia elemzések § Kevésbé használatos § Operátorokkal felépített kifejezések esetén természetes a használata o Előre olvasás : olvassunk előre a szövegben

valahány szimbólumot és az alapján döntünk a relációról => LR elemzések § Minden programozási nyelvhez lehet LR elemzőt készíteni § Majdnem mindegyikhez lehet gyors LALR elemzőt készíteni

LL elemzések

• Felülről lefelé elemzés, k terminális szimbólum előre olvasásával döntünk az alkalmazandó szabályról.

• Nem mindig használható pl: S -> A | B A -> a | aB B -> ab | aBb

nem tudjuk eldönteni h S -> A vagy S -> B a jó

FIRST halmazok

• FIRSTk(α): az α mondatformából levezethető terminális sorozatok k hosszúságú kezdő szeletei

Definíció:

LL(k) grammatikák: a levezetés tetszőleges pontján a szöveg következő k terminálisa meghatározza az alkalmazandó levezetési szabály

Definíció:

DEFINÍCIÓ EGYSZERŰ LL(1): olyan LL(1) grammatika amelyben a szabályok jobboldala terminális szimbólummal kezdődik (ezért ε mentes is) (összes szabály A -> aα alakú)

• Egyszerű LL(1) grammatika esetén az azonos nemterminálisokhoz tartozó szabályok jobboldalai különböző terminálissal kezdődnek. TÉTEL: egy grammatika pontosan akkor egyszerű LL(1) ha o Csak A -> aα alakú szabályai vannak

o És ha A -> a1α1 és A -> a2α2 két különböző szabály akkor a1 ≠ a2

ε-mentes LL(1) nyelvtan

DEFINÍCIÓ: olyan LL(1), amely ε mentes (nincs A -> ε szabály) Következmény: ε mentes LL(1) grammatika esetén az egy nemterminálishoz tartozó szabályok jobboldalainak FIRST1 halmazai diszjunktak

TÉTEL:

ELEMZÉS:

• Ha a verem tetején terminális szimbólum van: o Egyezik a szöveg következő karakterével: pop és lépés a szövegben, különben hiba

• Ha a verem tetején nemterminális szimbólum van o Ha van A -> a szabály amelyre a ∈ FIRST1(a): A helyére a és bejegyzés szintaxisfába, különben hiba

• Ha a verem üres o Ha a szöveg végére értünk OK, különben hiba

LL(1) GRAMMATIKA

Definíció:

FOLLOW halmazok FOLLOWk(a): a levezetésekben az a után előforduló k hosszúságú terminális sorozatok

DEFINÍCIÓ:

LL(1) ELEMZÉST MEGALAPOZÓ TÉTEL

FIRST1(aFOLLOW(A)) jelentése: a-hoz konkatenáljuk FOLLOW1(A) elemeit és az így kapott halmaz minden elemére alkalmazzuk a FIRST1 függvényt.

LL(1) ELEMZÉS

• Ha a verem tetején terminális szimbólum van o Egyezik a szöveg következő karakterével: pop és lépés a szövegben, különben hiba

• Ha a verem tetején nemterminális szimbólum van o Ha van A -> a szabály amelyre a ∈ FIRST1(aFOLLOW1(A)): A helyére a és bejegyzés a szintaxisfába, különben hiba

• Ha a verem üres o Szöveg végén vagyunk OK, különben hiba Rekurzív leszállás:

• Az LL(1) elemzés egy másik implementációja

• Minden nemterminálishoz egy eljárást készítünk

• Az eljáráshívásokon keresztül a futási idejű verem valósítja meg az elemzés vermét

LR elemzések Az LR(0) elemzés (felülről lefele, alulról felfele)

Kiegészített grammatika:

• Az elemzés végét arról fogjuk felismerni, hogy egy redukció eredménye a kezdőszimbólum lett

• Ez csak akkor lehet, ha a kezdőszimbólum nem fordul elő a szabályok jobb oldalán • Nem minden grammatika teljesíti de mindegyik kiegészíthető:

o Legyen S’ az új kezdőszimbólum o Legyen S’ -> S egy új szabály

• Mindig kiegészített nyelvtanokat fogunk használni

Mit kell redukálni?

• Egyszerű részmondat: α a γαβ mondatforma egyszerű részmondata, ha S ⇒∗ γAβ ⇒ γαβ.

• nyél: a mondatformában a legbaloldalibb egyszerű részmondat

LR(k) grammatika: k szimbólum előre olvasásával eldönthető, hogy mi legyen az elemzés következő lépése

LR(K) DEFINÍCIÓ:

LR(0) grammatika: előre olvasás nélkül eldönthető az elemzés következő lépése

LR(0) ELEM DEFINÍCIÓ:

LR(0) Lezárás művelet:

• a lezárás állapotához több LR(0) is tartozhat -> kanonikus halmazok

DEFINÍCIÓ:

LR(0) Olvasás művelet:

• ha [A->a.Ad] állapotban vagyunk, A kerül a verem tetejére, akkor [A -> aA.d]-be jutunk

DEFINÍCIÓ:

LR(0) KANONIKUS HALMAZOK DEFINÍCIÓ:

Az elemző táblázat létrehozása véges sok lépésben befejeződik.

JÁRHATÓ PREFIX DEFINÍCIÓ:

Maximális járható prefix: olyan járható prefix, amihez nem lehet újabb szimbólumot hozzávenni, hogy járható prefixet kapjunk. Épp akkor maximális ha a végén van a nyél.

JÁRHATÓ PREFIXRE ÉRVÉNYES LR(0) ELEMEK DEFINÍCIÓ:

AZ LR(0) ELEMZÉS HELYESSÉGE TÉTEL:

Konfliktus: egy Ik kanonikus halmaz alapján nem lehet egyértelműen eldönteni, hogy az adott állapotban milyen akciót kell végrehajtani

• léptetés/redukálás

• redukálás/redukálás Az LR(0) tulajdonság biztosítja a táblázat konfliktusmentes kitöltését

SLR(1) elemzés alapötlete:

• olvassunk előre egy szimbólumot o léptessük ha az automata tud lépni vele

o redukáljunk ha az előreolvasott szimbólum benne van a FOLLOW1 halmazban SLR(1) elemzés szabályai

• ha az aktuális állapot i , és az előre olvasás eredménye az a szimbólum:

o ha [A → α.aβ] ∈ Ii és read(Ii,a) = Ij, akkor léptetni kell, és átlépni a j állapotba, o ha [A→α.]∈Ii (A ≠ S′) és a∈FOLLOW1(A) akkor redukálni kell A→α

szabály szerint o ha [S′ →S]∈Ii és a=#,akkor el kell fogadni a szöveget, o minden más esetben hibát kell jelezni

• ha az i állapotba A kerül a verem tetejére:

o ha read(Ii,A) = Ij, akkor át kell lépni a j állapotba, o egyébként hibát kell jelezni

SLR(1) GRAMMATIKA DEFINÍCIÓ: Egy kiegészített grammatika SLR(1) grammatika, ha az SLR(1) elemző táblázata konfliktusmentes

Probléma az SLR(1)-el? Ha egy szimbólum több FOLLOW1 halmazban is szerepel.

LR(1) elemzés alapötlete:

• vegyük hozzá az LR(0) elemekhez azokat a szimbólumokat amik követhetik a szabályt az adott állapotban.

LR(1) ELEMEK DEFINÍCIÓ:

LR(1) Lezárás művelet:

LR(1) Olvasás művelet:

LR(1) KANONIKUS HALMAZOK DEFINÍCIÓ:

Az LR(1) elemzés szabályai:

• ha az aktuális állapot i, és az előre olvasás eredménye az a szimbólum:

o ha [A → α.aβ,b] ∈ Ii és read(Ii,a) = Ij, akkor léptetni kell, és átlépni a j állapotba, o ha [A→α.,a]∈Ii (A ≠ S′),akkor redukálni kell A→α szabály szerint,

o ha [S′ →S.,#]∈Ii és a=#, akkor el kell fogadni a szöveget, o minden más esetben hibát kell jelezni

• ha az i állapotban A kerül a verem tetejére o ha read(Ii,A) = Ij, akkor át kell lépni a j állapotba, o egyébként hibát kell jelezni az LR(1) elemző táblázat konfliktusmentessége tétel: egy grammatika pontosan akkor LR(1) grammatika, ha az LR(1) elemző táblázatai konfliktusmentesek

Az LR(1) elemző a megadott véges sok lépésben és teljesen automatikusan létrehozható

Járható prefix, érvényes LR-elem

• járható prefix: mondatformának olyan prefixei, amelyek legfeljebb a nyél végéig tartanak

• járható prefixre érvényes LR-elemek: a járható prefix „lehetséges folytatásai”

JÁRHATÓ PREFIXRE ÉRVÉNYES LR(1)-ELEM DEFINÍCIÓ:

LR(1)-ELEMZÉS NAGY TÉTELE:

Összefoglalva:

• az LR(1) elemző automatikusan és véges lépésben generálható a nyelvtan szabályaiból

• minden LR(1) grammatika elemzéséhez használható

• az elemző mindig a helyes lépést írja elő a fenti tétel miatt Probléma: túl sok állapota van

LALR(1) elemzés Az egyesíthető kanonikus halmazokat vonjuk össze. Az egyesített kanonikus halmazokat LALR(1) kanonikus halmazoknak nevezzük.

LALR(1) elemzés, LALR(1) grammatika

• az LALR(1) elemző táblázat kitöltése megegyezik az LR(1) táblázatéval

• az elemzés menete is azonos

DEFINÍCIÓ LALR(1) GRAMMATIKA: egy grammatika LALR(1) grammatika , ha az LALR(1) elemző táblázata konfliktusmentesen kitölthető.

DEFINÍCIÓ LR(0) KANONIKUS HALMAZOK TÖRZSE:

DEFINÍCIÓ LR(1) KANONIKUS HALMAZOK TÖRZSE:

Hibakezelés:

• hibajelzés: a táblázatok üres cellái hibarutinokra hivatkoznak

• hibaelfedés: az elemző szinkronizálja a vermet az inputtal és folytatja az elemzést

Szimbólumtábla-kezelés

Lexikális elemző: lexikális elemek sorozatát állítja elő Szintaktikus elemző: felépíti a szintaxisfát Szemantikus elemző: deklarálva van-e? Kifejezések típusa azonos-e? Kódgenerálás: utasítások generálása a tárgyprogram nyelvén amelyek megvalósítják az értékadást

A szemantikus elemzés és a kódgenerálás számára szükséges kiegészítő információk:

• konstansok értéke

• változók típusa

• függvények, operátorok szignatúrája

• a tárgykódba már bekerült változók

• részkifejezések típusa kétféle módon tárolhatjuk:

• szimbólumtábla o szimbólum neve § SZE és a KG a szimbólumokat a nevükkel azonosítja o szimbólum attribútumai § definíció adatai § típus § tárgyprogram-beli cím

• globális, statikus

• lokális változók

• dinamikusan foglalt változók § definíció helye a forrásprogramban § szimbólumra hivatkozások a forrásprogramban

• deklaráció definíció

• szemantikus értékek

Szimbólum tábla műveletei: keresés, beszúrás Hatókör: ahol a deklaráció érvényben van Láthatóság: ahol hivatkozni lehet rá a nevével Élettartam: amíg memóriaterület van hozzárendelve

Hatékonyságnövelés:

• kiegyensúlyozott fa: keresés és beszúrás is logaritmikus

• hash-tábla: keresés és beszúrás is konstans műveletigényű faszerkezetű szimbólumtábla:

• minden blokkhoz egy fa tartozik

• a fákat egy verembe tároljuk

• keresés

hash-szerkezetű szimbólumtábla:

• szimbólumtábla sorai: veremben

• hash-függvény: a szimbólumtábla sorait egy hash-értékre képezi le

• hash-tábla: hash értékekhez hozzárendeli a legutóbbi ilyen hash-kódú szimbólum pozícióját a veremben

keresés a hash-szerkezetű szimbólumtáblán

• a hash-függvénnyel meghatározzuk a keresendő szimbólum hash-értékét

• a hash-táblából megkapjuk az ilyen kódú szimbólumok láncolt listáját

• végigmegyünk a listán az első találatig

beszúrás a hash-szerkezetű szimbólumtáblába

• a szimbólumot a verem tetejére helyezzük

• a hash-függvénnyel meghatározzuk a beszúrandó szimbólum hash-értékét

• a hash táblában a kapott hash értékhez bejegyezzük a verem-beli pozíciót

• ha volt már ilyen hash-kódú szimbólum, akkor az új szimbólumhoz beláncoljuk

törlés a hash-szerkezetű szimbólumtáblából

• blokk végén a blokk-index vektor tetején lévő elem mutatja, hogy meddig kell törölni a szimbólumokat

• egy szimbólum törlése:

• a blokk összes szimbólumának törlése után a blokk-index vektor legfelső elemét is töröljük

Szemantikus elemzés feladatai • jellemzően környezetfüggő ellenőrzéseket valósítja meg.

o Deklarációk kezelése o Láthatósági szabályok

o Aritmetikai ellenőrzések (nullával osztás esetén kiszűrhető, hasonlóan a konstansok estén túl- vagy alul csordulás)

o A program szintaxisának környezetfüggő részei

o Típusellenőrzés (első közelítésben a kifejezések típusozhatóságának ellenőrzése) a szemantikus elemzés erősen függ a konkrét programozási nyelvtől

• Statikus típusozás:

o Az ellenőrzések fordítási időben történnek

o Futás közben csak értékek tárolása, „nem történhet baj” o Biztonságosabb o Ada, haskell

• Dinamikus típusozás:

o Futás közben az értékek mellett típusinfot is kell tárolni o Minden utasítás előtt ellenőrizni kell a típusokat o Típushiba esetén futási idejű hiba keletkezik o Hajlékonyabb

o Lisp, erlang

• Típusellenőrzés:

o Minden típus a deklarációban adott

o Kifejezések egyszerű szabályok alapján típusozhatóak o Egyszerűbb fordítóprogram, gyors fordítás o Kényelmetlenebb a programozónak

• Típuslevezetés:

o A változók fgv-ek típusai nem kell megadni

o A típusokat fordítóprogram „találja ki” a definíciójuk használata alapján o Bonyolultabb fordítóprogram, lassabb fordítás o Kényelmesebb a programozónak

• Típuskonverzió

o A típuskonverzió esetén át kell írni a kifejezés típusát

o Ha szükséges a tárgykódba generálni kell a konverziót elvégző utasításokat

Típusok ekvivalenciája

• Szerkezeti:

o Bonyolultabb az ellenőrzés

o Nem mindig fejezi ki a programozói szándékot

• Név szerinti:

o Egyszerűbb az ellenőrzés (==)

o Időnként kényelmetlen lehet a programozónak

Altípusok származtatott típusok

• Altípus: általában valamilyen megszorítást tesz az altípusra • Származtatott típus:

o Öröklődéssel jön létre az altípusból o Sokféle specializáció: Új adatréteg/metódus Upcast: altípus vagy származtatott típus mindenhol használható, ahol az altípus megengedett Downcast: az altípus általában nem használható a származtatott vagy altípus helyett

Szemantikus elemzés elmélete

• A nyelvtan szabályait kiegészítjük a szemantikus elemzés tevékenységeivel:

o fordítási grammatikák

• a nyelvtan szimbólumaihoz szemantikus típusokat rendelünk o attribútum fordítási grammatikák

• megvizsgáljuk, hogy mikor lehet kiértékelni az attribútumértékeket o jól definiált attribútum fordítási grammatikák

• megszorításokat teszünk a grammatikára, hogy a kiértékelés egyszerűbb legyen o particionált attribútum fordítási grammatikák o rendezett attribútum fordítási grammatikák

• megvizsgáljuk, hogyan illeszthetők ezek a módszerek a tanult szintaktikus elemzőhöz

fordítási grammatika

• a grammatika szabályaiban jelöljük, hogy milyen szemantikus elemzési tevékenységre van szükség, ezeket hívjuk akciószimbólumoknak. Ezek által jelölt szemantikus tevékenységet szemantikus rutinnak nevezzük

• az ilyen módon kiegészített grammatikát fordítási grammatikának nevezzük.

Attribútumok

• a szimbólumokhoz attribútumokat rendelünk. Ezek jelzik, hogy a szimbólumhoz milyen szemantikus értékek kapcsolódnak

• jelölése: A.x, y (az A szimbólumhoz az x és y attribútumokat rendeljük.)

Attribútum fajták

• szintetizált: helyettesítési szabály bal oldalán áll abban a szabályban amelyikhez az őt kiszámoló szemantikus rutin tartozik

• örökölt: helyettesítési szabály jobb oldalán áll abban a szabályban amelyikhez az őt kiszámoló szemantikus rutin tartozik

• kitüntetett szintetizált: olyan attribútumok, amelyek terminális szimbólumokhoz tartoznak és kiszámításukhoz nem használunk fel más attribútumokat

Attribútum fajták fordítási grammatika (ATG)

• Egészítsük ki egy fordítási grammatika szimbólumait attribútumokkal, a szabályokat feltételekkel, valamint rendeljünk szemantikus rutinokat az akciószimbólumokhoz a következő szabályok betartásával:

o Egy adott szabályhoz tartozó feltételek csak a szabályban előforduló attribútumoktól függhetnek.

o A szemantikus rutinok csak annak a szabálynak az attribútumait használhatják és számíthatják ki, amelyikhez az őket reprezentáló akciószimbólum tartozik.

o Minden szintaxisfában minden attribútumértéket pontosan egy szemantikus rutin határozhat meg.

DEFINÍCIÓ JÓL DEFINIÁLT ATTRIBÚTUM FORDÍTÁSI GRAMMATIKA:

• Olyan attribútum fordítási grammatika, amelyre igaz, hogy a grammatika által definiált nyelv mondataihoz tartozó minden szintaxisfában minden attribútum értéke egyértelműen kiszámítható.

DEFINÍCIÓ DIREKT ATTRIBÚTUM FÜGGŐSÉGEK:

• Ha az Y.b attribútumot kiszámoló szemantikus rutin használja az X.a attribútumot, akkor (X.a, Y.b) egy direkt attribútum függőség. Ezek a függőségek a függőségi gráfban ábrázolhatók.

• Jól definiált attribútum fordítási grammatikákhoz tartozó szintaxisfák függőségi gráfjaiban biztosan nincsenek körök!

Egy attribútum kiértékelő algoritmus:

• Nem determinisztikus algoritmus:

o A szintaxisfa minden folyamatához egy algoritmust rendelünk

o A folyamat azt figyeli, hogy az attribútum kiértékeléséhez szükséges összes attribútum értékét meghatározza-e a többi folyamat, ha igen akkor kiszámítja az attribútum értékét

ha a fordítási grammatika jól definiált akkor biztos, hogy minden attribútum érték ki lesz számolva és terminál a program

particionált ATG

• Minden X szimbólum attribútumai szétoszthatók az AX1 , AX2 , . . . , AXmX diszjunkt halmazokba (partíciókba) úgy, hogy o AXmX , AXmX −2… halmazokban csak szintetizált attribútumok AXmX −1, AXmX −3,

… halmazokban csak örökölt attribútumok vannak, ésminden szintaxisfában az X attribútumai a halmazok növekvő sorrendjében meghatározhatók.

Rendezett ATG

• egyszerű algoritmussal meghatározhatók a partíciók.

• a halmazokat fordított sorrendben határozzuk meg.Felváltva szintetizált és örökölt attribútumokat teszünk a halmazokba mindegyikbe azokat az attribútumokat tesszük, amikre csak olyan attribútumok kiszámításához van szükség, amelyeket már beosztottunk valamelyik halmazba

S-attribútum fordítási grammatikák

• Olyan attribútum fordítási grammatika, amelyben kizárólag szintetizált attribútumok vannak.

• A szemantikus információ a szintaxisfában a levelektől a gyökér felé terjed.

• Jól illeszthető az alulról felfelé elemzésekhez!

S-ATG és alulról felfelé elemzés

• redukció esetén a szabály jobb oldalának attribútumértékei már ismertek

• a szabályhoz rendelt szemantikus rutin feladata a baloldalon álló szimbólum szintetizált attribútumainak meghatározása

L-attribútum fordítási grammatikák

• Olyan attribútum fordítási grammatika, amelyben mindenA → X1X2 . . . Xn szabályban az attribútumértékek az alábbi sorrendben meghatározhatók:

• A örökölt attribútumai

• Xn örökölt attribútumai

• Xn szintetizált attribútumai

• A szintetizált attribútumai

• Jól illeszkedik a felülről lefelé elemzésekhez.

Mi az assembly?

• Programozási nyelvek egy csoportja

• Gépközeli

• a futtatható programban pontosan azok az utasítások lesznek, amit a programba írunk • Fordító: assembler

• Változói: regiszterek (eax, ebx, ecx,edx), memória (program által használt adatok, maga a program kódja) o Eax – accumulator – elsősorban aritmetikai számításokhoz(alsó 16bit: ax – felső ah alsó al)

o Ebx – base – tömbök rekordok kezdőcíme o Ecx – counter – számlálók tárolása o Edx – data – egyéb adatok

o Esi – source index – stringmásolásnál a forrás címe o Edi – destination index – a cél címe o Esp – stack pointer – program vermének teteje

o Ebp – base pointer – aktuális alprogramhoz tartozó verem-rész o Eic – instruction pointer – a következő végrehajtandó utasítás o Eflags – jelzőbitek – összehasonlítások eredményeinek tárolása

• Adatterület megadása o Resb, resw, resd – 1-2-4 bájt lefoglalása o Db, dw, dd – 1-2-4 bájt kezdőértékkel

• Adatmozgás: mov

• Aritmetikai művelet: inc, dec, add, sub, mul, div

• Logikai műveletek: and, or, not, xor, 1 (true), 0 (false)

• Ugró utasítás: jmp

• Feltételes ugró: je (=), jne(≠), jb (<), ja (>), jnb (>=), jna (<=)

• Verem műveletek: push, pop (minden futó programhoz hozzá van rendelve egy saját memóriaterület, ebben lehet tárolni a lokális változókat, paraméter átadás alprogramhívás estén, ebbe kerül bele a visszatérési cím) csak 2, 4 bájtot lehet kivenni

Kódgenerálás … belső reprezentáció -> kódgenerátor -> optimalizáció…

Kódgenerálás feladata:

• A szintaktikusan és szemantikusan elemzett programot tárgykóddá alakítja

• Szorosan összekapcsolódik a szemantikus elemzéssel

Értékadások fordítása alakja: assignment -> variable assignment_operator expression Egy ágú elégazás alakja: statement -> if condition then program end Többágú elágazás alakja: statement -> if condition1 then program1

… elseif conditionn programn

else programn+1 end switch-case utasítás alakja: statement -> switch variable case value: program elöltesztelős ciklus alakja: statement -> while condition program end hátul tesztelős ciklus alakja: statement -> loop program while condition for ciklus alakja: statement -> for variable from value1 to value2 program end

kezdőérték nélküli változódefiníció fordítása: section.bss kezdőértékkel adott változódefiníció fordítása: section.data konstans kiértékelése: mov eax, 25 változó kiértékelése mov eax, [x]

alprogramok fordítása

• Függvény

o Csak bemenő paraméterek, visszatérési érték, nincs mellékhatás

• Eljárás o Ki és bemenő paraméter, jellemzően nincs visszatérési érték

• Metódus

• Paraméterátadási formák:

o Érték szerint:

§ A paraméterek másoljuk a verembe, ha az alprogram módosítja az nem hat az átadott változóra

o Hivatkozás szerint:

§ Az átadandó változóra mutató pointert kell tenni a verembe, az alprogramban a lokális változó kiértékelése is módosul

• Tagfüggvények

Call címke: az eip regiszter tartalmát a verembe teszi Ret: kiveszi a verem legfelső 4 bájtját és az eip regiszterbe teszi

Memóriakezelés:

• Statikus: .data vagy .bss szakaszban

• Dinamikus: verem vagy heap memória

Heap memória: allokállás és felszabbadítás, oprendszer vagy egy programkönyvtár végzi, a szabad területet nyilván kell tartani

Kódoptimalizálás …kódgenerátor -> optimalizáló -> kód kezelő

Célja: hatékonyabb program létrehozása

Az optimalizált programnak ugyanúgy kell működni mint az eredetinek. Az adott nyelv szemantikája dönti el, hogy egy optimalizálási lépés megengedhető-e

Mit optimalizálunk?

• Az eredeti programot

• A tárgyprogramot Mi az átalakítás hatóköre?

• Lokális: kis program részletek

• Globális: a teljes program szerkezete Mit használ ki az átalakítás?

• Általános: algoritmusok javítása

• Gépfüggő: az adott architektúra sajátosságait

DEFINÍCIÓ ALAPBLOKK Egy program egymást követő utasítások sorozatát alapblokknak nevezzük, ha

• Az első utasítás kivételével egyik utasításra sem lehet távolról átadni a vezérlést

• Az utolsó utasítás kivételével nincs benne vezérlés-átadó utasítás

• Az utasítás-sorozat nem bővíthető a fenti két szabály megsértése nélkül

Lokális optimalizálás: egy alapblokkon belüli átalakítások Tömörítés: minél kevesebb konstans és konstans értékű változó legyen

• Konstansok összevonása: fordítási időben kiértékelhető kifejezések kiszámítása

• Konstans továbbterjesztése: a fordítási időben kiszámítható értékű változók helyettesítése az értékükkel

Ablakoptimalizálás: ez egy módszer a lokális optimalizálás egyes fajtáihoz

• Felesleges műveletek törlése

• Egyszerűsítések

• Nulla mozgatása helyett a regiszter törlése

• Regiszterbe töltés és ugyanoda visszaírás esetén a visszaírás elhagyható

• Utasításismétlések törlése

Globális optimalizálás: teljes program szerkezetét meg kell vizsgálni (adatáram analízis) Frekvenciaredukálás: a költésges utasítások átköltöztetése ritkábban végrehajtódó alapblokkba Erős redukció: a ciklusban lévő költséges műveletek kiváltása kevésbé költésgessel Funkcionális programozási nyelvek Programok futtatása:

• Funkcionális eset: függvények kiszámítása

• Imperatív eset: állapotváltozások sorozata Tiszta függvény: olyan függvény amelynek nincs mellékhatása Tisztán funkcionális nyelv: csak tiszta függvények írhatóak benne

Nagyon kifinomult a típusrendszerük

• Többalakúság, típusellenőrzés helyett típuslevezetés, típusosztályok A függvények teljes jogú tagjai a nyelvnek

• Lehet paraméterként átadni és lehet visszatérési érték Lusta vagy szigorú kiértékelés

• Lusta: csak akkor étkékel ki egy kifejezést, amikor arra valóban szükség van

• Szigorú: minden paramétert kiértékel a függvényhívás előtt

Nyelvek fordítása: lexikális/szintaktikus/szemantikus elemzés eredménye egy transzponált program Margó szabály: utasítások végét és a blokkszerkezetet a sorok behúzása definiálja

• Lexikális elemző feladata

• Megjegyezzük hányadik oszlopban van az első karaktere

• Verembe beletesszük a legelső utasítás behúzását

• Kulcsszavak után beszúrunk ‘{‘ tokent és a következő token behúzását a verembe tesszük

• Minden sortörésnél meg kell vizsgálni az új sor behúzását

A kiértékeletlen kifejezések kezelése

• Objektum ami tartalmaz egy pointer a függvényre, és további pointereket a függvény megfelelő paramétereire

• Az ilyen objektumok (closure) átadhatók a függvénynek és vissza adhatóak visszatérési értékként

• Ha mindegyik paraméter rendelkezésre áll egy closure-ben és szükségessé válik a kiértékelése akkor elvégezhető a művelet

Gráfátírás:

• Egy closure-ben a paraméterek is és a függvény is lehet további kiértékeletlen kifejezés

• A teljes kifejezés ábrázolható egy fával

• Kódgenerálás a modern lusta kiértékelésű funkcionális nyelveken írt programokhoz

• A programok lefuttatása

top related