# Zk. 5.6. pisemka

<{ForumPost(poster="Munch", timestamp=2006-06-05 15:31:32)}>
Jako maly priklad jsem dostal prunik dvou spojaku.  
  
Dnesni velky priklad byl Macroprocesor.  
  
Mame nakej text a ten muze obsahovat mimo jine i:  
  
&MACRO jmeno_makra(parametr1, parametr2, ...)  
-telo definice makra  
-muze obsahovat #parametr#  
&ENDM  
  
&jmeno_makra(neco, neco, neco, ...) - volani makra, misto toho se ma objevit telo toho makra  
  
-Pocet maker byl nak omezen, ale telo mohlo byt dlouhe jak chtelo.  
-Makro se muze predefinovat, vzdy se pouziva ta definice ktera je zrovna posledni.  
-Uvnitr makra muze byt nova definice, popr. volani makra.  
-Definice se uvadi v platnost v dobe, kdy probiha, tj. definice makra v definici makra se uvede v platnost po prvnim zavolani toho vnejsiho makra.  
-Jako parametr muze byt makru predavano cokoliv (tj. definice, volani maker atd.)  
-Musi se vychytat mozne zacykleni.  
  
Vystup byl kupodivu soubor, ktery neobsahoval zadne definice a volani a byl strukturovan podle tech maker.  
  
  
Moje reseni (rozhodne netvrdim, ze je spravne natoz optimalni):  
  
udelal sem si striktury:  
  
Makro - obsahuje: jmeno, pocet parametru, pozici zacatku tela v souboru, nazvy parametru, ukazatel na dalsi prvek (je to spojak)  
  
volani - nazev, pocet parametru, pole pozic zacatku parametru, ukazatel na dalsi prvek  
  
Zaklad tvori tri fce:  
Main - otevre soubory a ve while(not(EOF)) cte ze vstupu:  
  
-pokud nacte definici makra: nacte ho do struktury, ta se prida do spojaku, preskoci telo a jede dal  
-pokud nacte volani: nacte volani do struktury, zapamatuje si momentalni pozici a spusti fci zpracujmakro, pak se vrati na pozici a smaze volani  
  
jinak zapise do vystupu  
  
fce zpracujmakro - nacte si pozici v souboru ze struktury makra, kterou dostane na vstupu  
-cte ve while(not(&ENDM))  
-pokud nacte definice, tak nacte, prida do spojaku a jede dal  
-pokud volani tak se nacte, ulozi volani do struktury, ta se prida do spojaku, zavola rekurzivne zpracuj makro, pak ze spojaku odeberu to volani a nastavim pozici zpet  
-pokud najde parametr tak se podiva do spojaku maker, tam najde kterej parametr to je, a podiva se do spojaku volani na pozici zacatku toho parametru, ulozi si pozici v souboru, zavola fci zpacujparametr, nacte pozici a jede dal  
  
  
fce zpracujparametr dela v podstate to samy, jako zpracujmakro, ale ve whilu ceka na ','  
  
  
Doufam, ze to (aspon) nekdo  pochopi  :) .  
Mohli byste sem napsat taky naky jiny reseni at muzu na zkouseni rict i jinou alternativu :lol:
<{/ForumPost}>

<{ForumPost(poster="Myshaak", timestamp=2006-06-05 21:10:00)}>
Zajimave! :) Akorat jsem nepochopil, jak zabranis tomu, aby se to zacyklilo?  
  
Pokud jde o me (spatne) reseni:  
  
-vse vlastne resila procedura Zpracuj (vstup_s,vystup_s: string; hloubka: Integer; param: Uk_p);   ... to Uk_p je ukazatel na LSS parametru a hloubka je hloubka vnoreni (Topfer rikal, ze ji muzem omezit, jestli chceme)  
  
-uvnitr otevru vystupni soubor (pomoci append) ctu vstupni soubor a znak po znaku kopiruju do vystupniho  
  
-kdyz narazim na &MACRO jm_makra -> vytvorim soubor jm_makra.$$$ a tam zacnu kopirovat vse az do uzaviraciho &ENDM - ! musim si hlidat to spravny &ENDM, muzou tam byt vnoreny definice (tema se ale ted nezabyvam, jen je kopiruju do jm_makra.$$$), na to staci jeden Integer !  
  
-kdyz najdu &jm_makra -> otevru soubor jm_makra.$$$ (pokud neexistuju -> chyba! ja jsem vynadal a nahrazoval prazdnym retezcem) - obsah tohoto souboru zkopiruju do souboru jm_makra.$i a jm_makra.$$$ zavru (to $i je hloubka rekurze) -> pak ZAVRU VYSTUPNI soubor a rekurzivne zavolam Zpracuj('jm_makra.$i','vystupni_soubor',hloubka+1,seznam parametru)  
  
Parametry: protoze se nevejde jejich obsah do stringu, tak si jejich obsah zkopiruju do souboru, jmena tech souboru hodim do spojaku, ktery pak predavam ty proc. Zpracuj  
+zapomnel jsem rict, ze u kazdy definice (=> v souboru jm_makra.$$$ na 1. radce) mam jmena formalnich parametru - z tech pak vzdy pri cteni toho souboru vytvorim dalsi spojak. Pak kdyz najdu #par#, tak projizdim tento spojak (jmen formalnich parametru) a zaroven predany spojak jmen souboru, ktere odpovidaji skutecnym parametrum -> kdyz najdu, tak proste zas zavru vystup a zavolam Zpracuj('soubor_toho_parametru','vystupni_soubor',hloubka+1,nil);  
  
Osetreni zacykleni:  
to je trochu haluzarna, ale lip me to nenapadlo: Protoze pocet maker je pry take omezeny (treba 100, nebo 1000 to je fuk), tak si muzu dovolit udelat pole T: array \[1..#maker] of longint. To bude globalni promenna. Budu si tam zapisovat pocet ms, ktery ubehl od startu programu do posl. modifikace souboru jm_makra.$$$ (nekde vedle si pamatuju ktere makro odpovida ktere polozce v T). Pak si vzdy na zacatku Zpracuj poznamenam cas, kdy jsem vstoupil do teto procedury. Kdyz potom nekde chci rozbalit to samy makro (uvnitr &MACRO abc je nekde &abc), tak porovnam cas vstupu do Zpracuj a T\[x] (kde T\[x] odpovida posl modifikaci souboru abc.$$$) no a pokud to T\[x] je mensi, tak se mi to chce zacyklit, ja uzivateli sproste vynadam a zacnu formatovat disk. :)  
  
jeste tam byly dalsi "vychytavky", ale uz se mi nechce vzpominat. Uvidime jak dopadnu zitra.  
  
ufff, asi to neni moc srozumitelny a navic je to blbe, ale mas cas chtel. ;~)  
  
PS: Prunik dvou spojaku je asi jejich oblibeny priklad, ja to mel taky. :))
<{/ForumPost}>

<{ForumPost(poster="Munch", timestamp=2006-06-05 23:45:19)}>
Dik za tve reseni.  
  
U toho zacykleni jsem napsal, ze by to slo resit tak, ze bych si pamatoval, jestli jsem v tele makra predefinoval to makro v kterym jsem a zase ho v tom tele volam, pokud ne tak to nejspis vede k zacykleni. Nejspis to nevychyta vsechny pripady a mozna to vychyta i pripady kdy se to nezacykli.  
Jinak me napada jen kontrolovat hloubku. Tusim, ze rikal, ze hloubku muzem nak omezit, takze kdyz proste klesnu hloubeji, tak zformatuju harddisk  :)
<{/ForumPost}>

