Hlavní navigace

Makro procesor GNU m4 (2)

Michal Burda

V dnešním dílu si pod drobnohledem prohlédneme proces expanze maker.

Expanze maker

Proces expanze maker je v činnosti m4 zásadní událostí, proto si jej popíšeme podrobněji. Předpokládejme, že m4 ze své vstupní pásky přečetlo slovo, které má přiřazenu definici makra. Procesor ve svých útrobách tuto definici v podobě řetězce znaků vyhledá, „přilepí“ ji na začátek vstupní pásky a pokračuje ve čtení vstupu od počátku. To znamená, že výsledek po expanzi makra je pokaždé znovu podroben zpracování procesorem. Klidně se v něm mohou objevit volání dalších maker nebo dokonce sebe sama a podobně.

Řekněme, že máme definováno makro makro1 tak, aby expandovalo na text „nazdar“. Takhle se m4 zachová:

   Volám makro1!
=> Volám nazdar!

Kdybychom navíc měli definováno makro nazdar na hodnotu „ahoj světe“, konečná podoba výstupu by vypadala takto:

   Volám makro1!
=> Volám ahoj světe!

Co se ve druhém případě přesně stalo? Procesor dostal do vínku vstupní pásku s řetězcem „Volám makro1“. Začne tuto pásku zpracovávat a nalezne token „Vol“. K němu není přiřazena žádná definice makra, proto slovo pouze vypíše v nezměněné podobě na výstup a pokračuje ve své práci. Znak „á“ je speciální, proto rovnou putuje na výstup. Následuje načtení tokenu „m“. Po kontrole svého vnitřního slovníku m4 zjistí, že se nejedná o žádné makro – znak zapíše na výstupní pásku. Za ním následuje mezera jakožto speciální znak. Následně procesor konečně načte slovo „makro1“, které je identifikátorem makra. K makru makro1 má m4 uloženu definici „nazdar“. Řetězec určený k nahrazení názvu makra vloží na počátek vstupní pásky. (Vstup v této chvíli vypadá asi takhle: „nazdar!“.) Pokračuje ve zpracovávání modifikované vstupní pásky a narazí na slovo „nazdar“. To je také identifikátorem makra, proto se celý postup opakuje. Řetězec „nazdar“ je na vstupu nahrazen jeho expanzí, totiž dvouslovím „ahoj světe“. Procesor jej znovu čte, ale žádné další makro už nenajde, proto vše kopíruje na výstup. Ve chvíli, kdy narazí na konec vstupní pásky, skončí.

Jednou z možností, jak zabránit expandování makra, je vložit řetězec do uvozovek:

   `makro1'
=> makro1

Pamatujete? Uvozený řetězec m4 neprohledává na výskyt maker, ale jednoduše jej posílá rovnou na výstup – a to je přesně to, co v téhle chvíli chceme.

Druhým způsobem je tohle:

   ma`'kro1
=> makro1

Procesor načte token „ma“, který ale neznamená nic, zapíše jej tedy na výstup. Druhým tokenem bude prázdný řetězec a pak token „kro1“, jenž rovněž nemá přiřazen žádný význam. – Heuréka! Slůvko „makro1“ je na výstupu!

Lehce přijdete i na další možnosti. Ale ty jsou jen variací těch předchozích:

   `m'akro1
=> makro1
   ma`kro'1
=> makro1
   mak`ro1'
=> makro1

Makra s argumenty

Používat makra jenom tak, jak jsme si dosud řekli, by bylo trochu chabé – nahrazovat text jiným umí i sed nebo podobné nástroje. Makra v m4 mohou však být volána navíc i s parametry, což uživateli přináší další aplikační možnosti. Žádost o expanzi makra s parametry se zapisuje takto:

nazev_makra(parametr1, parametr2, ..., parametrN)

Makra mohou mít libovolný počet argumentů. Jednotlivé parametry se oddělují čárkou. Otevírací závorka („(“) musí následovat přímo za názvem makra, bez oddělujících mezer, jinak bude makro zavoláno bez argumentů.

Vyžaduje-li volané makro více parametrů, než mu je dodáno, dostanou chybějící argumenty hodnotu prázdného řetězce. Je-li naopak makro voláno s nadbytkem parametrů, bude m4 ty přebývající jednoduše ignorovat.

Text:

nazev_makra()

je žádost o expanzi makra s jedním zadaným argumentem, který má hodnotu prázdného řetězce. Abyste zavolali makro bez argumentů, musíte jeho název napsat bez závorek:

nazev_makra

Při shromažďování argumentů dochází k expanzi maker, takže výsledek jednoho makra může být argumentem pro jiný. Jinými slovy, narazí-li m4 na název makra následovaný levou závorkou, přejde do speciálního stavu čtení argumentů. Název makra, které se má expandovat, si zapamatuje a pokračuje ve čtení vstupní pásky až po odpovídající uzavírací závorku. Přitom každé další makro, na které narazí, expanduje rekurzivně stejným postupem. Teprve když má načten celý řetězec tvořící všechny parametry, rozdělí jej podle čárek („,“) na jednotlivé argumenty a zapamatované makro expanduje.

Tedy například, jestliže „param“ expanduje na řetězec „, b, c“, volání makra:

makro(a param, d, e)

je žádostí o expanzi makra „makro“ s pěti parametry „a ", "b“, „c“, „d“ a „e“. Všimněte si, že první argument obsahuje mezeru, ale ostatní ne. Je to proto, že m4 ignoruje všechny „bílé znaky“ na začátku každého argumentu, zatímco všechny „bílé znaky“ na konci do hodnoty parametru zahrne. Chcete-li přesto mezeru na začátek argumentu dostat, musíte to procesoru m4 sdělit jejím uzavřením do uvozovek.

Aby to nebylo tak jednoduché, je zde navíc ještě jedno pravidlo týkající se výskytu neuvozených závorek uvnitř argumentů. Procesor si hlídá počty levých a pravých závorek v prostoru pro parametry makra, a ty se musí shodovat. Načítání parametrů tedy neskončí na prvním výskytu pravé závorky, ale až v místě odpovídající pravé závorky.

Volání:

makro((()

s největší pravděpodobností skončí s chybou „konec souboru v seznamu argumentů“ (EOF in argument list), protože m4 ke třem levým závorkám nikdy nenalezne jejich pravé ekvivalenty. Správný zápis je:

makro(`((')

Tímto jsme probrali celou problematiku čtení vstupu procesorem. Příště začneme s výkladem a popisem vestavěných maker. U dalšího pokračování se těší

Našli jste v článku chybu?
Vitalia.cz: Když přijdete o oko, přijdete na rok o řidičák

Když přijdete o oko, přijdete na rok o řidičák

Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

Měšec.cz: mBank cenzuruje, zrušila mFórum

mBank cenzuruje, zrušila mFórum

Vitalia.cz: Znáte „černý detox“? Ani to nezkoušejte

Znáte „černý detox“? Ani to nezkoušejte

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Podnikatel.cz: Zavře krám u #EET Malá pokladna a Teeta?

Zavře krám u #EET Malá pokladna a Teeta?

Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá

Vitalia.cz: I církev dnes vyrábí potraviny

I církev dnes vyrábí potraviny

Lupa.cz: Teletext je „internetem hipsterů“

Teletext je „internetem hipsterů“

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

Vitalia.cz: Mondelez stahuje rizikovou čokoládu Milka

Mondelez stahuje rizikovou čokoládu Milka

Vitalia.cz: 9 největších mýtů o mase

9 největších mýtů o mase

Vitalia.cz: Proč vás každý zubař posílá na dentální hygienu

Proč vás každý zubař posílá na dentální hygienu

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Podnikatel.cz: EET: Totálně nezvládli metodologii projektu

EET: Totálně nezvládli metodologii projektu

Podnikatel.cz: 1. den EET? Problémy s pokladnami

1. den EET? Problémy s pokladnami

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Podnikatel.cz: Udávání kvůli EET začalo

Udávání kvůli EET začalo