1/26 8.. A lexikális szintaktikai Babe³Bolyai Tudományegyetem Matematika Informatika Kar
2/26 magasszint programozási nyelv fordítóprogram alacsonyszint programozási nyelv magasszint nyelvek: C, C++, Pascal,... alacsonyszint nyelvek: assembly, gépi kód Magasszint programnyelv egesz a; egesz b; b = 3; a = b + 2; kiir a; Assembly % include " _io_win. asm " section. text global _main _main : mov eax, 3 mov [ _b ], eax mov eax, [ _b ] push eax mov eax, 2 pop ebx add eax, ebx mov [ _a ], eax mov eax, [ _a ] push eax call print_int add esp, 4 ret section. data _a dd 0 _b dd 0
3/26 forrásprogram, forrásnyelv program: a magasszint nyelven írt program tárgyprogram, tárgynyelv program: az alacsonyszint nyelvre (assemblyre vagy gépi kódra) lefordított, futtatható program fordítási id : fordítás id tartama futtatási id : a lefordított tárgyprogram végrehajtási ideje egymenetes/többmenetes fordítási folyamat: Legyen P a forrásnyelv, Q a tárgynyelv program, T a fordítás transzformációja; ekkor a fordítási folyamat a Q = T (P) képlettel írható le. Ha T = T n T n 1... T 1, akkor P n 1 = T n (P) P n 2 = T n 1 (P n 1 )... P 1 = T 2 (P 2 ) Q = T 1 (P 1 )
4/26 az el bbi többmenetes/n-menetes esetben P i, i = 1, 2,..., n 1 a program közbüls programformája fordítóprogram típusai: compiler ez az amivel foglalkozni fogunk(!) interpreter olyan gép (program) kzíte, amelyik a magasszint nyelvet ismeri fel = a gép gépi kódja a magasszint nyelv formulavezérl számítógép ha az interpretert hardver szinten valósítjuk meg interpreter esetén a fordítási futási id egybeesik Compilerek: C, C++, Pascal,... Interpreterek: Java (interpreter = Java Virtual Machine), Perl (interpreter = perl), PHP (interpreter = PHP/FI [Personal Home Page/Forms Interpreter], Zend Engine, Zend Engine II),... els compilerek: 50-es évek eleje els k között volt a FORTRAN compiler is (1957)
forrásnyelvű compiler source- lista 5/26 ADATOK ADATOK forrásnyelvű program compiler forrásnyelvű program tárgynyelvű program compiler végrehajtás tárgynyelvű program végrehajtás 1. ábra. Compiler: fordítási folyamat EREDMÉNY EREDMÉNY ADATOK forrásnyelvű program interpreter (végrehajtás) forrásnyelvű program EREDMÉNY ADATOK interpreter (végrehajtás) EREDMÉNY forrásnyelvű 2. ábra. Interpreter: source- interpretálási lista folyamat program handler
6/26 A fordítóprogram szerkezete compiler(forrásprogram)(tárgyprogram, lista) source-handler(forrásprogram, hibák)(karaktersorozat, lista) input-handler(forrásprogram)(karaktersorozat) a forrásprogramot alakítja át, küldi a compilernek (általában egy puerben helyezi el ezeket); levágja az újsor karaktereket output-handler(forrásprogram, hibák)(lista) listát kzít a forrásprogramból a hibákból, melyet a compiler kzít; a listát, amely a hibák (pontos) helyét tartalmazza a háttértárolón helyezi el. Fontos: a szinte mindig hibás programot fordítanak, hibátlan programokkal csak elhanyagolhatóan kev esetben találkoznak, ezért nagyon fontos a pontos hibajelz! code-handler(tárgykód)(tárgyprogram) a compiler által kzített tárgykód elhelyeze a háttertárolón
7/26 *compiler(karaktersorozat)(tárgykód, hibák) (ténylegesen csak a fordítóprogram feladatával foglalkozik) forrásnyelvű program sourcehandler lista *compiler codehandler tárgynyelvű program 3. ábra. A compiler felépíte
8/26 A *compiler analízis: a forrásprogram karaktersorozatát rzekre bontja vizsgálja lexikális elemz : lexikális elemz (karaktersorozat)(szimbólumsorozat, lexikális hibák) szimbólumtábla: általában a szimbólumra a hozzá rendelt kóddal hivatkozunk kisz ri: szóköz vagy más fehér karaktereket, kommentek szintaktikai elemz : szintaktikai elemz (szimbólumsorozat)(szintaktikusan elemzett program, szintaktikai hibák) a program struktúrájának felismere: az egyes szimbólumok a megfelel helyen vannak-e, megfelelnek-e a programozási nyelv szabályainak, nem hiányzik-e valahonnan valamilyen szimbólum kimenet: szintaktikailag elemzett program (pl. szintaxisfa)
9/26 (analízis): szemantikai elemz : szemantikai elemz (szintaktikailag elemzett program)(elemzett program, szemantikai hibák) szemantikai tulajdonságok vizsgálata pl.: azonosito + konstans vizsgálatakor megnézi, hogy az azonosito szimbólum deklarálva van-e, a konstans -nak van-e értéke, típusuk azonos-e szintézis: az egyes rzeknek megfelel tárgykódokból felépíti a program teljes tárgykódját kódgeneráló: kódgenerátor(elemzett program)(tárgykód) assembly vagy gépi kód el állítása kódoptimalizáló: kódoptimalizáló(tárgykód)(tárgykód) cél: hatékonyabb kód elkzíte, mint amilyet egy jó assembly programozó írni tud
10/26 többmenetes fordítóprogram: bizonyos lépeket több menetben tud csak elvégezni a menetek számát a köv. tényez k befolyásolhatják: a compiler rendelkezére álló memória a compiler mérete sebessége a tárgyprogram mérete sebessége a hibajavítási lehet ségek hibafelismeri hibajavítási stratégiák (a compiler megírására rendelkezre álló id szellemi kapacitás) az egyszer egymenetesek segédeszközök: lexikális elemz : lex vagy flex szintaktikus elemz : yacc vagy bison (a szemantikus elemz kódgenerátor is beépíthet )
11/26 ANALÍZIS lexikális elemző szintaktikai elemző szemantikai elemző SZINTÉZIS kódgeneráló kódoptimalizáló 4. ábra. Az analízis szintézis fázisai
12/26 meghatározza a lexikális elemeket/egységeket kisz ri az információt nem hordozó rzeket (fehér karakterek, újsor, kommentek) továbbadja a lexikális elemeket a szintaktikus elemz nek a feladat megoldása: reguláris grammatikával (Chomsky 3-as típusú grammatikával), reguláris kifejezekkel, véges automatákkal általában: a szimbolikus egységeket reguláris kifejezekkel adjuk meg építhet szimbólumtáblát, ahol a szimbólumok a hozzájuk tartozó kódok szerepelnek
13/26 1. Példa Tekintsük a következ kódokat: azonosító 01 if 25 else 26 ( 43 ) 44 < 29 ++ 98 ; 45 Ekkor a lexikális elemz a if (_ == ) _++; else ++; kódból a 25 43 01 29 01 44 01 98 45 26 01 98 45 sorozatot kzíti, amely már kevbé olvasható.
14/26 Kiterjesztett reguláris kifejezek (flex) x x karakter. minden karaktek, kivéve az újsort [xyz] karakterosztály, az x, y vagy z karakterre illeszkedik [abj-oz] karakterosztály, a vagy b vagy j-t l o-g vagy Z [^A-Z] karakterosztály negáltja (komplementere) r* zéró vagy több r r+ egy vagy több r r? opcionalitás: zéró vagy egy db. r r{2,5} kett, három, négy vagy öt r r{2,} legalább két r r{4} pontosan négy r {nev} a nev kiterjeszte (r) zárójelez a precedencia/prioritás megváltoztatása érdekében rs konkatenáció
15/26 r s vagy r/s r ha követi t egy s; az s-et beszámítja az illeszked hosszába, de csak az r-re illeszked sztringet téríti vissza (el reolvasási szimbólum, követ kontextus, trailing context) ^r r a sor elején r$ r a sor végén <s>r r ha s startfeltételben (start condition) vagyunk; s lehet s1,s2,s3 alakú is <*>r bármilyen startfeltételben <<EOF>> fájlvége szimbólum
16/26 2. Példa Írjuk le reguláris kifejezekkel a következ lexikális elemeket: egz szám, valós szám, egysoros komment, azonosító szimbólum, fehér karakterek. Jelöljük a következ reguláris kifejezeket: D = [0-9] A = [a-za-z] Ekkor: 1. egz szám: ("+" "-")?{D}+ 2. valós szám: ("+" "-")?{D}+(.{D}+) 3. egysoros komment: //.* 4. azonosító: ({A} _)({A} _ {D})* 5. [ \t\n]+
17/26 Az ezekhez tartozó automaták sorban:
18/26 Speciális problémák kulcsszavak standard szavak vannak programozási nyelvek, melyek különbséget tesznek kulcsszavak között kulcsszónak nem változtathatjuk meg a jelentét, standard szavaknak megváltoztathatjuk C/C++-ban pl. csak kulcsszavak vannak, de Pascal-ban vannak standard szavak standard szavak használata nagyon rontja a program olvashatóságát, a programozónak sokkal nehezebb megtalálni a hibát anomália esetén például: (ez nem fordítható le Pascal-ban, de létezhet olyan nyelv, amiben igen): if if then else = then; tanács: hanyagoljuk standard szavak bevezetét
el reolvasás (lásd az el reolvasási szimbólumot a kiterjesztett reguláris kifejezeknél) bizonyos esetekben el fordul, hogy a lexikális elemz nek el re kell olvasni néhány karaktert, hogy meg tudja állapítani a helyes lexikális elemet pl.1: meg akarjuk különböztetni a változókat a függvényekt l, de mindkett nevét ugyanúgy építhetjük fel, vagyis mindkett t az (A _)(A _ D)* reguláris kifejezsel írjuk le; a következ kifejez megoldja a problémát (flex): (A _)(A _ D)*/"(" pl.2: azt akarjuk, hogy a lexikális elemz kisz rje a numerikus konstansok elejér l a zérókat (ha azokat más számjegyek követik): 0+/[1-9]+ direktívák a fordítóprogram m ködének vezérlére szolgának pl. egy if direktíva esetén (C/C++: #if, #ifdef, ifndef, #elif, #else, #endif) ki kell értékelnie a feltételt, csak a megfelel ágat bennhagynia a kódban másik típusú ilyen probléma a makróhelyettesít a lexikális elemz nek tehát szintaktikus szemantikus ellen rzeket is kell végeznie általában a lexikális elemz utáni el feldolgozóval oldják meg ezeket 19/26
20/26 hibakezel lexikális hiba: nem tud megfeleltetni egyetlen szimbólumot sem hibaelfed módszereket használunk; nem jó ha a fordítóprogram már ebben a fázisban kiakad módszerek: 1. gyelmen kívül hagyjuk a rossz karaktereket, külön lexikális elemként továbbítjuk a szintaktikai elemz nek a két oldalán álló szimbólumokat 2. gyelmen kívül hagyjuk a rossz karaktereket, összeolvasztjuk a két oldalán lev szimbólumokat 3. továbbítjuk a rossz karaktereket a szintaktikai elemz nek egy undef szimbólumként más problémák: a sztringek végét jelz " hiánya, a többsoros kommentek zárószimbólumának hiánya
21/26 %{ #i n c l u d e <i o s t r e a m > #i n c l u d e " grammar_tab. h" //#i n c l u d e " grammar. t a b. h" u s i n g namespace s t d ; %} %o p t i o n noyywrap %% [0 9]+ { r e t u r n NUM; } [ \ t \n ] { / e z e k k e l nem f o g l a l k o z u n k / }. { / b a r m i mas / r e t u r n y y t e x t [ 0 ] ; } %% 5. ábra. Példa flex kódra t y p e d e f u n i o n { i n t number ; c h a r s t r i n g ; } YYSTYPE ; #d e f i n e NUM 258 e x t e r n YYSTYPE y y l v a l ; 6. ábra. A grammar_tab.h állomány
22/26 a szimbólumsorozat a nyelv egy mondata? környezetfüggetlen grammatikákkal oldjuk meg pontosabban kiterjesztett környezetfüggetlen grammatikákkal: A α, A N, α (N T ) Def. Mondatforma Legyen G = (N, T, P, S) egy grammatika. Ha S α, α (N T ), akkor α mondatforma. Ha S x, x T, akkor x az L(G) egy mondata. Def. Rzmondat Legyen a G = (N, T, P, S) grammatikának α = α 1 βα 2 egy mondatformája. A β rzmondat, ha A N úgy, hogy S α 1 Aα 2 A + β. A β egyszer rzmondata α-nak, ha a fentiekben A β teljesül, vagyis (A β) P.
23/26 3. Példa Tekintsük a következ szabályok által deniált grammatikát: E T E + T T F T F F i (E) az E + T i + T F mondatformát. Ennek i + T i + T F nem rzmondata; E + T i, T F T i rzmondata; T F egyszer rzmondata.
24/26 csak egyértelm grammatikákkal foglalkozunk nem egyértelm = több szintaxisfa tartozik hozzá többféle tartozik hozzá többféle tárgykód (!) csak olyan grammatikákkal foglalkozunk, melyek a köv. feltételeket is teljesítik: 1. a grammatika ciklusmentes: nem tartalmaz A + A levezeteket 2. a grammatika redukált: nem tartalmaz felesleges nemterminális szimbólumokat (minden szimbólum szerepel legalább egy S-b l induló levezetben) Def. Nyél Egy mondatforma legbaloldalibb egyszer rzmondatát a mondatforma nyelének nevezzük. 4. Példa A 3. Példában szerepl mondatforma nyele az i.
25/26 balról jobbra haladó ekkel foglalkozunk kétféle : S 1. felülr l-lefelé haladó : az S szimbólumból kiindulva próbáljuk meg felépíteni a szintaxisfát, azaz levezetni a programot 2. alulról-felfelé haladó : a terminálisokból x (a programból) kiindulva próbáljuk felépíteni a szintaxisfát, azaz eljutni az S szimbólumhoz S S x x S x
26/26 %{ #i n c l u d e <i o s t r e a m > #i n c l u d e <f s t r e a m > #i n c l u d e <cmath> u s i n g namespace s t d ; i n t y y e r r o r ( c h a r ) ; i n t y y l e x ( ) ; %} %union { } %t o k e n NUM %s t a r t s %l e f t '+ ' ' ' %l e f t ' ' ' / ' %% s : command command s i n t number ; c h a r s t r i n g ; ; command : e x p r ' ; ' ; expr : NUM ' ( ' e x p r ' ) ' e x p r '+ ' e x p r e x p r ' ' e x p r e x p r ' ' e x p r e x p r ' / ' e x p r ; %% i n t y y e r r o r ( c h a r s ) { c e r r <<s<<" " ; } i n t main ( ) { // yydebug = 1 ; i f ( y y p a r s e ( ) == 0) c e r r <<"OK. \ n" ; } 7. ábra. Példa bison kódra