# vim:wrap:spell:spelllang=cs,en # # DO NOT EDIT! This file is generated automatically! # # __SOURCE(⟦intro.mc⟧, ⟦20210120-19:33:09⟧, ⟦801a2ed⟧, ⟦d01fc8e⟧) 8 Generování kódu v M4: úvod # number of characters in perex (200 ±10 is recommended): 226 18 Makro procesor M4 se používá ke generování libovolně složitého kódu z jednoduchého zdrojového kódu. Úvodní díl seriálu obsahuje jeho historii, základní principy jazyka, příklady použití a nutné předpoklady pro jeho zvládnutí. 26 Úvod 33 Čtenáři tohoto seriálu se naučí psát skripty pro strojové generování kódu. Strojově generovaný kód může být libovolně složitý a může obsahovat další vnitřní závislosti. Vzájemně závislé soubory se složitým kódem jsou pro člověka jen těžce udržitelné v konzistentním stavu. Je už nutné použít nějaký mechanismus pro generování kódu. Generování kódu provádí nástroj určený pro transformaci textu – makro procesor. 48 Seriál je zaměřen na praktické použití univerzálního makro procesoru M4 (dále jen M4) pomocí malých příkladů. Popisuje také teoretický základ všech implementací. Cílem seriálu je seznámit čtenáře s tímto nástrojem (m4 – je program příkazové řádky) a také programovacím jazykem (M4 – je programovací jazyk). Na co se používá, jak se v něm programuje a jaké jsou jeho výhody a nevýhody. 62 [poznámka] 62 Vícejazyčný seriál „Generování kódu v M4“ je generován M4 skripty, které (možná) usnadní psaní článků a seriálů pro www.root.cz (Root.cz – informace nejen ze světa Linuxu) také jiným autorům. Výsledkem seriálu je také sada ukázkových skriptů pro generování kódu. 64 Úvodní díl popisuje základní principy jazyka na jednoduchých příkladech. Všechny příklady používají přepisovací pravidla bezkontextové gramatiky. Později se naučíme používat výstupní fronty, automaty, asociativní paměti, zásobníky a zásobníkové automaty. Naučíme se také psát testovací automaty pro testování vstupních dat. 80 Příklady pro čtenáře 87 Příklady pro čtenáře tvoří komplementární část seriálu a budou do jisté míry vytvářeny na základě podnětů v diskuzi pod článkem. Na začátku každého dílu je popsána nějaká část jazyka M4 doplněná sadou příkladů na konci. Každý díl je možné číst v libovolném pořadí. 98 Příklady generování kódu 98 Příklady preprocesoru 98 M4: příklady 98 Proč používat M4 a proč ne? 98 http://github.com/jkubin/m4root (Generování kódu v M4) – projekt generující tento seriál 118 Historie makro jazyků 125 Makro jazyky byly vynalezeny v době, kdy dominoval jazyk symbolických adres – JSA (Jazyk Symbolických Adres – assembler). Zdrojový kód JSA velmi často obsahuje shodné sekvence instrukcí odlišující se pouze hodnotami operandů. Shodné sekvence instrukcí je možné seskupit do jednoho slova, nebo-li makro instrukce. Jméno obvykle popisuje účel skryté sekvence instrukcí. Makro instrukce se přeloží makro procesorem na původní sekvenci instrukcí, která se posléze přeloží do spustitelného strojového kódu. Programování v JSA pomocí makro instrukcí je jednodušší, rychlejší a méně náchylné k lidským chybám. 142 Později byly makro jazyky použity k rozšíření kompilovaných programovacích jazyků, protože umožnily psát zdrojový kód na vyšší úrovni abstrakce než jakou poskytuje samotný programovací jazyk. Rychlost, výkonnost a efektivita složitého programovacího jazyka nižší úrovně je zachována díky makro jazykům. Avšak je důležité dobře rozumět všem vrstvám kódu. 153 GPM (General Purpose Macro-generator) 157 Základní myšlenku přepisování textových řetězců s argumenty, které se přepíší do dalších rekurzivně přepisovatelných řetězců, představil Christopher Strachey (Wikipedie) ve svém GPM (General Purpose Macro-generator) v roce 1965. Další generace makro procesorů M3 a M4 původní GPM (General Purpose Macro-generator) v podstatě už jen rozšiřovaly. Základní myšlenka původního návrhu ale zůstala stejná. 171 M3 175 Dennis Ritchie (Wikipedie) převzal základní myšlenku GPM (General Purpose Macro-generator) a napsal vylepšený makro procesor pro generování zdrojového kódu programovacího jazyka C (1972), který sám navrhl. Nový makro procesor napsal pro minipočítač AP-3, odtud jméno M3. Tento přímý předchůdce současného M4 dokázal výrazně ušetřit těžkou a časově náročnou práci, čímž zaujal vývojáře programující v jiných jazycích (FORTRAN (FORmula TRANslation), COBOL (COmmon Business-Oriented Language), PL/I (Programming Language One), …). Vývojáři upravovali M3 pro tyto jazyky čímž ho proměnili na univerzálně použitelný makro procesor M4. 188 [m4 ∈ {množina nástrojů UNIX-u}] 188 Dennis Ritchie byl také spolutvůrcem operačního systému UNIX a proto: 188 M4 je minimalistický a rychlý, dělá jednu věc a tu dělá dobře (Filosofie UNIX-u Wikipedie) 188 výhradně spoléhá na neinteraktivní rozhraní příkazové řádky 188 parametry a závislosti M4 skriptů popisuje 188 znakem začíná jednořádkový komentář jako v UNIX-ovém shell-u 188 proměnné , , , , , , , … mají podobný význam jako v shell-u 188 oddělovač argumentů je čárka 247 Makro procesor M3 rozšířil také Jim E. Weythman, autor programové konstrukce, která se používá téměř v každém M4 skriptu: 263 [poznámka] 263 Klíčové slovo (divert(-1), divert(0), divert(1), …, divert(2147483647)) přepíná výstupní fronty. Argument zcela vypne jakýkoliv textový výstup. Argument přepne výstup na (standardní výstup). 274 M4 278 Brian Kernighan (Wikipedie) makro procesor M3 rozšířil na preprocesor (Wikipedie) jazyka FORTRAN 66, aby mohl vytvořit hybridní jazykovou nadstavbu pojmenovanou RATFOR (RATional FORtran). Základní programové konstrukce této nadstavby (podmínky, cykly) jsou stejné jako v jazyce C. Programování v RATFOR-u se tak podobá programování v „céčku“. Makro procesor zdrojový kód překládá zpátky do FORTRAN-u, poté kompilátor provede překlad do strojového kódu. 293 [jazyk M4 doplňuje jazyk C] 293 Všimněte si téměř dokonalé symbiózy s jazykem C 293 direktivy CPP (Preprocesor jazyka C) , , , … jsou pro M4 komentáře 293 klíčová slova oddělená od závorek mezerou, ztrácí svůj původní význam M4 například ignoruje funkci 293 argumenty maker oddělují čárky stejně jako argumenty funkcí jazyka C je-li definováno makro , jeho proměnné jsou: , , , 293 levý řídící znak není součástí syntaxe rodiny jazyků C 293 pravý řídící znak nevadí, není-li součástí makra oba řídící znaky lze skrýt do uživatelských maker , 293 makra se píší , stejně jako neterminální symboly (Wikipedie) tím je vymezen jejich jmenný prostor 362 Uživatelský manuál zmiňuje ještě další, zde neuvedené spoluautory. Bylo by tedy značně nespravedlivé napsat, že autory makro procesoru M4 (1977) jsou pouze dva lidé. 371 [Christopher Strachey, Dennis Ritchie, Brian Kernighan] 371 Christopher Strachey, Dennis Ritchie, Brian Kernighan 388 GNU M4 392 Dnes existuje několik implementací lišící se od původní implementace spíše drobnostmi. Nejrozšířenější implementace M4 je GNU M4 používaná pro Autotools (Wikipedie) a pro překlad jednoduchého konfiguračního souboru na složitý . Autorem této implementace z roku 1990 je René Seindal. Následující příkaz nainstaluje m4 (s malým „m“): 407 [příkaz nainstaluje také další důležité balíčky] 411 Podrobný popis klíčových slov se nachází v dokumentaci: 425 Základy jazyka M4 432 Základem jazyka M4 je bezkontextová gramatika, automaty, zásobníky a výstupní fronty. Pro pochopení jazyka M4 je proto velmi důležité rozumět základním pojmům teorie formálních jazyků – co jsou terminální symboly (Wikipedie) (stručně terminály) a neterminální symboly (stručně neterminály). Zmíněné pojmy si podrobněji vysvětlíme někdy později. Cílem tohoto úvodního dílu je hlavně ukázat praktické použití M4 na příkladech. 447 Bezkontextová gramatika 454 Bezkontextová gramatika (krátce CFG (Context-Free Grammar – bezkontextová gramatika)) je formální gramatika, ve které mají všechna přepisovací pravidla tvar . Neterminál se přepíše na libovolně dlouhý řetězec (pravá strana přepisovacího pravidla) složený z neterminálů nebo terminálů . Kleeneho hvězda (Wikipedie) znamená, že se neterminál může přepsat na (epsilon – prázdný symbol) (přepisovací pravidlo ). 465 [přepisovací pravidla bezkontextové gramatiky] 471 Přepisovací pravidla M4 478 Přepisovací pravidla M4 jsou stejná jako přepisovací pravidla bezkontextové gramatiky. 485 [přepisovací pravidla M4] 494 Všechna klíčová slova M4 jsou neterminály (makra), provedou nějakou akci a přepíší se na (epsilon – prázdný symbol) nebo jiný symbol. Všechna klíčová slova lze přejmenovat nebo úplně vypnout. Tato vlastnost je velmi důležitá pro režim preprocesoru. 505 [klíčová slova M4 jsou neterminály] 513 Řízení expanze neterminálů 520 Výchozí dvojice znaků v M4 řídí expanzi neterminálů. Klíčové slovo je může změnit na jiné znaky, například {(hranaté závorky), (netisknutelné znaky), (UTF-8 znaky)}. Neterminály, které nechceme (ihned) expandovat, jsou obklopeny touto dvojicí znaků. Při průchodu makro procesorem jsou všechny symboly mezi touto dvojicí znaků terminálními symboly a vnější dvojice znaků je odstraněna. Další průchod již způsobí expanzi původně chráněných neterminálů. Dvojice řídících znaků se nastavuje na začátku kořenového souboru. 538 Automaty 545 Automaty slouží jako „přepínače“ pravidel gramatiky. Používají přepisovací pravidla gramatiky jako uzly a mění své stavy podle vstupních symbolů. Aktuálně používané přepisovací pravidlo produkuje do výstupní fronty (nebo do několika výstupních front) specifický kód, dokud automat nepřejde do jiného uzlu s jiným přepisovacím pravidlem. Příklady generujících automatů jsou ukázány v příloze. 560 Výstupní fronty 567 Výstupní fronty jsou dočasné úložiště pro části výsledného kódu. Tyto části výsledného kódu jsou produkovány přepisovacími pravidly gramatiky, které přepisují vstupní symboly. Klíčové slovo nastavuje aktuální výstupní frontu. Na závěr jsou všechny neprázdné fronty vypsány ve vzestupném pořadí na standardní výstup a složí výsledný kód z částí kódu. Výstupní fronty jsou ukázány v příloze. 582 [pro informaci] 582 Zásobníky si ukážeme později. 590 Hlavní použití M4 597 M4 se používá ke generování zdrojového kódu libovolného programovacího jazyka nebo jako preprocesor jakéhokoliv zdrojového kódu. 605 Generování kódu 612 M4 transformuje vstupní data ze souborů (Macro Configuration) na výsledná data následujícím příkazem: 619 [← nejobecnější.m4 … nejspeciálnější.m4 →] 623 Během načítání souborů jsou prováděny dvě základní operace: 630 čtení transformačních pravidel ze souborů s příponou 630 expanze maker uvnitř souborů s příponou 648 Soubory a obsahují vstupní data ve specifickém formátu, který umožňuje jejich transformaci na výstupní data podle pravidel v předchozích souborech. Datové soubory obvykle neobsahují žádná transformační pravidla. 657 Vstupní data mohou také přicházet z kolony: 664 [vstupní kód → generování zdrojového kódu → soubor] 668 [vstupní kód → generování zdrojového kódu → program] 672 Vyzkoušejte: Příklady generování kódu 680 Preprocesor 687 M4 může pracovat v režimu preprocesoru a může být také součástí kolony. Vstupní zdrojový kód jím prochází beze změny s výjimkou neterminálních symbolů. Nalezené neterminály jsou expandovány na terminály a odchází spolu se zdrojovým kódem na výstup. M4 může rozšířit jakýkoliv jiný jazyk, kde je preprocesor nedostatečný (bez rekurze) nebo žádný. Důležité je zvolit vhodný levý znak pro řízení expanze neterminálů, který nesmí kolidovat se znakem vstupního zdrojového kódu. Kolize znaku je ale snadno řešitelná regulárním výrazem. 704 [M4 jako preprocesor – obecně] 708 [M4 jako preprocesor – bez dočasného souboru] 713 Výchozí znaky 720 Konfliktní znak ze vstupního zdrojového kódu je skryt do makra . Prázdný pár řídících znaků před makrem slouží jako oddělovač symbolů. Při průchodu zdrojového kódu makro procesorem se makro přepíše zpátky na původní znak a prázdný pár je odstraněn. 734 [M4 jako preprocesor s řídícími znaky: `'] 738 Vyskytují-li se ve vstupním kódu komentáře nebo , je nutné je skrýt. Znaky vypnou původní význam komentářů a budou odebrány při průchodu makro procesorem. Komentáře M4 a jsou skryty mezi výchozí znaky: 749 [M4 jako preprocesor s řídícími znaky: `'] 753 [M4 jako preprocesor s řídícími znaky jinak: `'] 758 Hranaté závorky 765 Použijeme-li pro řízení expanze neterminálů hranaté závorky, stejným způsobem je skryta levá hranatá závorka. Vše ostatní platí jako pro výchozí znaky . 774 [M4 jako preprocesor s řídícími znaky: []] 778 Komentáře M4 a jsou skryté mezi závorkami: 785 [M4 jako preprocesor s řídícími znaky: []] 789 [M4 jako preprocesor s řídícími znaky jinak: []] 794 Netisknutelné znaky 801 Pro řízení expanze neterminálů lze použít netisknutelné znaky () a (). Tyto znaky nemohou kolidovat s tisknutelnými znaky zdrojového kódu. 810 [M4 jako preprocesor s řídícími znaky: ␂␆] 814 Komentáře M4 a jsou skryty mezi netisknutelné znaky: 821 [M4 jako preprocesor s řídícími znaky: ␂␆] 825 [M4 jako preprocesor s řídícími znaky jinak: ␂␆] 830 UTF-8 znaky 837 Expanzi neterminálů může také řídit vhodně zvolený pár UTF-8 znaků. Běžný zdrojový kód takové znaky neobsahuje, proto nemusíme řešit kolizi levého řídícího znaku. UTF-8 znaky nabízí podobné výhody jako netisknutelné znaky. 848 [M4 jako preprocesor s řídícími znaky: ⟦⟧] 852 Komentáře M4 a jsou skryty mezi UTF-8 znaky: 859 [M4 jako preprocesor s řídícími znaky: ⟦⟧] 863 [M4 jako preprocesor s řídícími znaky jinak: ⟦⟧] 869 Vyzkoušejte: Příklady preprocesoru 873 Smíšený režim 880 Smíšený režim je kombinací předchozích režimů a je používán hlavně na pokusy. Data nejsou oddělena od transformačních pravidel. Listový soubor obsahuje definice těchto pravidel spolu se vstupními daty. 891 [jak se naučit M4] 895 Vyzkoušejte: M4: příklady 900 Předpoklady pro zvládnutí M4 907 Pro úspěšné zvládnutí tohoto makro jazyka je důležité splnit několik předpokladů. M4 není jednoduchý jazyk, protože není možné v něm myslet a programovat jako v běžném programovacím jazyce. Nejdůležitější je uvědomit si, že se v něm programují přepisovací pravidla gramatiky. Každý řetězec je buď terminální nebo neterminální symbol včetně všech klíčových slov jazyka (symboly a jsou speciální případy neterminálů). 920 [poznámka] 920 M4 záměrně nemá klíčová slova pro cykly (/), protože jeho základ je zcela jiný, než jaký mají procedurální nebo funkcionální jazyky. 920 cykly jsou pouze levorekurzivní nebo pravorekurzivní 920 větví se řetězením symbolů nebo klíčovými slovy , 952 Základy gramatik 959 Základem všech gramatik jsou přepisovací pravidla, jejichž podobu obecně popisuje: 966 Formální gramatika (Chomského typu) 984 Formální gramatika (Wikipedie) popisuje podmnožiny (Chomského hierarchie (Wikipedie)) přepisovacích pravidel formálního jazyka (Wikipedie). Jedna z podmnožin se jmenuje bezkontextová gramatika (Wikipedie), krátce CFG (Context-Free Grammar – bezkontextová gramatika). Jak již bylo dříve zmíněno, přepisovací pravidla CFG pracují stejně jako přepisovací pravidla jazyka M4. Některý z následujících dílů seriálu se podrobněji zaměří na formální gramatiky. 1004 Základy automatů 1011 Schopnost používat převážně dvoustavové automaty je zásadní věc pro psaní jednoduchých M4 skriptů, protože převážná většina skriptů používá malé automaty. 1018 Testovací automat 1025 Pořadí vstupních symbolů nebo jejich kontext lze otestovat automatem. Splňují-li vstupní symboly požadované vlastnosti, automat skončí v uzlu s dvojitým kroužkem, kterým se označuje akceptující stav. 1034 [deterministický konečný automat (DFA)] 1034 Příklad automatu akceptující sudý počet (žádný je také sudý) symbolů , ignorující symboly . Automat je shodný s regulárním výrazem . 1049 Předchozí automat lze zapsat jako ASCII art doprovázející M4 skript: 1056 [ASCII art jako dokumentace M4 kódu] 1065 Generující automat 1072 Vstupní symboly mění uzly automatu, čímž zároveň mění přepisovací pravidla pro generování kódu. Příklad generujícího automatu naleznete v příloze: 1081 [ASCII art generujícího automatu] 1099 (GNU) make 1106 Dobře navržený generátor kódu se obvykle skládá z několika menších souborů, jejichž pořadí, závislosti a parametry se zapisují do souboru . Dobrá znalost tvorby je proto základním předpokladem pro zvládnutí M4. Čtení a údržba zdrojového kódu celkově zabere vždy více času než jeho tvorba. Dobře strukturovaný proto zásadním způsobem přispívá k celkové přehlednosti výsledného generátoru kódu. 1119 [tímto tématem se budeme zabývat jindy] 1119 Spouštění z editoru kódu pomocí vhodné klávesové zkratky zásadně urychluje vývoj M4 kódu. Soubor obsahuje . 1129 Vim 1136 Zvládnutí editoru Vim je důležitým předpokladem pro pohodlí a rychlost psaní kódu M4. Vim zkratky, definované klíčovým slovem , ušetří velké množství zbytečně napsaného textu. Tyto zkratky také významně snižují výskyt téměř neviditelných chyb způsobených nepárovou závorkou, čímž šetří ztracený čas vynaložený na ladění kódu. 1148 Talent a čas 1155 M4 obvykle nejde zcela zvládnout přes víkend, zvláště chybí-li základy teorie automatů (Wikipedie) a formálních gramatik (Wikipedie). Ke zvládnutí jazyka M4 je nutné v něm programovat delší období a napsat množství špatného (složitého) M4 kódu, který z vlastní vůle přepíšete kvůli lepšímu nápadu. Tímto způsobem je možné postupně získat praxi. 1172 Příklady generování kódu 1172 [pro informaci] 1172 Znaky {(uvozovky), (hranaté závorky), (netisknutelné znaky), (UTF-8 znaky)} v názvu příkladu řídí expanzi neterminálů. 1179 [poznámka] 1179 Příklady v této příloze jsou složitější a jejich cílem je ukázat praktické použití jazyka M4. Podrobněji budou vysvětleny později. 1189 Vstupní zdrojový kód 1196 Vstupní zdrojový kód je podobný CSV (Comma Separated Values), který se převede na libovolně složitý cílový kód jiného jazyka pomocí CFG (Context-Free Grammar – bezkontextová gramatika), automatů a výstupních front. Zásobníky v příkladech nejsou použity. Vstupní zdrojový kód obsahuje speciální znaky, které je nutné skrýt: 1207 [] 1209 [poznámka] 1209 Vstupní soubor může také obsahovat poznámky, které nemusí být skryté v komentářích , , nebo . 1217 CSV: nejjednodušší příklad 1224 Tento příklad nepoužívá výstupní fronty, pouze vypisuje CSV (Comma Separated Values) oddělené znakem na standardní výstup. 1231 [] 1236 CSV: počítadlo 1243 Příklad používá makro ze souboru , jehož (pravá strana přepisovacího pravidla) se zkopíruje do pravé strany makra . Během první expanze proběhne inicializace jeho startovací hodnoty. Další expanze vrátí číselný terminální symbol a proběhne zvýšení vnitřního pomocného (globálního) symbolu o jedničku. je malý automat. 1256 [] 1261 [] 1266 (jak se to dělá) Úpravy speciálních znaků 1273 Každý typ výstupního kódu vyžaduje úpravu speciálních znaků. Klíčové slovo jazyka M4 je nevhodné pro tento úkol. Všechny speciální znaky vstupního souboru proto napřed skryjeme do vhodně pojmenovaných maker pomocí regulárních výrazů. 1284 Upravený vstupní kód 1291 [všechny speciální znaky jsou skryty do maker] 1305 Převodní soubor pro XML, XSLT, HTML 1309 [převodní soubor pro značkovací jazyky] 1312 Převodní soubor pro C, JSON, INI: 1319 [převodní soubor pro zdrojový kód] 1322 Převodní soubor pro Bash: 1329 [převodní soubor pro Bash "řetězce v uvozovkách"] 1331 Převodní soubor pro Bash: 1338 [převodní soubor pro Bash 'řetězce v apostrofech'] 1340 Převodní soubor pro CSV, M4 (vrátí všechny znaky zpátky) 1347 [převodní soubor vrátí všechny speciální znaky zpátky] 1350 C: výstupní fronta 1357 Příklad používá jednu výstupní frontu na znaky pro uzavření pole na konci skriptu. 1369 INI: externí příkaz 1376 Příklad spustí externí příkaz a jeho výstup umístí do hranatých závorek. Výstupem externího příkazu jsou dvě položky oddělené čárkou. Makro vybere první položku, protože druhá položka obsahuje nežádoucí znak nového řádku (). 1387 [] 1399 .h: hex počítadlo 1406 Příklad používá makro pro číslování výsledných CPP (Preprocesor jazyka C) maker a jednu výstupní frontu. Fronta číslo obsahuje direktivu preprocesoru pro zakončení hlavičkového souboru. Převod dekadické hodnoty počítadla na dvoumístné hex-a číslo provádí klíčové slovo . 1417 [] 1428 C: malý automat 1435 Příklad používá malý automat pro generování znaku nového řádku a jednu výstupní frontu číslo do které se vloží znaky pro uzavření výsledného řetězce. Poprvé se přepíše na (epsilon – prázdný symbol), podruhé a dále se přepíše na . 1444 [] 1451 [] 1456 C: malý automat 2 1463 Tento příklad je podobný předchozímu, avšak každý řetězec je na novém řádku. 1470 [] 1472 [] 1475 HTML: výstupní fronty 1482 Příklad používá dvě výstupní fronty. Fronta číslo obsahuje odstavce, fronta číslo uzavírací značky HTML stránky. Navigační odkazy nemusí být nikde uloženy, jdou přímo na výstup. Zprávy typu a jsou zpracovány stejně jako zprávy typu . 1502 Větvení gramatikou 1509 Příklad ukazuje větvení gramatikou, argumenty maker se ignorují. Vstupní neterminály se přepisují na terminály (🐛), (🐜), (🐝). 1524 [] 1530 Větvení gramatikou – základní princip 1537 Proměnná se nahradí za jméno makra a zřetězí se s dalším symbolem. Nově vzniklý neterminál se přepíše na odpovídající terminální symbol (číslo fronty nebo jméno). 1546 [větvení gramatikou v M4] 1557 JSON: generující automat 1564 Příklad používá dvě výstupní fronty a jeden generující automat. První chybová zpráva ve stavu vygeneruje záhlaví se závorkami a vypíše na výstup první záznam. Automat přejde do stavu což je pravidlo (takové pravidlo se používá jako pravá strana jiného přepisovacího pravidla). Následující chybové zprávy ve stavu pouze vypisují na výstup jednotlivé záznamy. Na závěr výstupní fronty číslo a vypíšou znaky a čímž zakončí výsledný JSON. 1584 JSON: pojmenované fronty 1591 Příklad zpracovává další zprávy typu a . Používá tři automaty a šest výstupních front. Generujeme-li složitější zdrojový kód, brzy narazíme na problém udržení konzistence indexů pro výstupní fronty. Abychom se vyhnuli zmatku, pojmenujeme si fronty a místo čísel používáme jména. Abychom nemuseli definovat podobná pravidla, zkopírujeme si pravou stranu (je to také pravidlo (takové pravidlo se používá jako pravá strana jiného přepisovacího pravidla)) do pravé strany pravidel a . 1611 JSON: generované indexy front 1618 Během vývoje se často mění pořadí a počet výstupních front, což také vyžaduje častou změnu jejich indexů. Indexy je proto vhodné generovat. Můžeme pak používat prakticky neomezený počet front. Následující příklad ukazuje, jak se tyto indexy generují. 1631 [] 1637 INI: nespojitý index front 1644 Příklad používá tři automaty a dvě výstupní fronty číslo a definované v odděleném souboru. Názvy INI sekcí jsou generovány řetězením symbolů (viz. větvení). Příklad používá stejný soubor pro výstupní fronty jako příklad pro generování JSON. 1655 [] 1660 XML: smíšené zprávy 1667 Příklad používá jednu výstupní frontu číslo pro uzavírací značku . 1679 XML: oddělené zprávy 1686 Příklad seskupuje zprávy podle jejich typu pomocí výstupních front. 1698 Bash 1710 Bash 1722 Příklady preprocesoru 1722 [pro informaci] 1722 Znaky {(uvozovky), (hranaté závorky), (netisknutelné znaky), (UTF-8 znaky)} v názvu příkladu řídí expanzi neterminálů. 1729 Preprocesor jazyka C a M4 1736 Direktivy CPP (Preprocesor jazyka C) jsou pro M4 jednořádkový komentář, což brání nežádoucí expanzi stejně pojmenovaných maker. Definujeme-li bezpečnější makro , stejně pojmenované makro nebude přepsáno. Jmenný prostor CPP (Preprocesor jazyka C) tak může být zcela oddělen od jmenného prostoru M4. Problematický znak je skryt do makra . Apostrof ve zdrojovém kódu ničemu nevadí. Apostrof uvnitř makra je skryt do makra . Všimněte si jmen funkcí nebo a kde je expandován . 1755 [] 1759 [] 1765 [] 1771 CSS: vložení souboru, komentář 1778 CSS používá znak pro kódy barev, což je také začátek jednořádkového M4 komentáře. Klíčové slovo nastaví víceřádkový komentář a přepíše se na (epsilon – prázdný symbol). Komentáře se vypínají stejným klíčovým slovem bez parametrů. 1789 [soubor vložený makro procesorem] 1790 [] 1791 [] 1793 [] 1796 Bash: netisknutelné znaky 1803 Bash používá oba znaky, a . Nechceme-li je skrývat do makra , můžeme použít pro řízení expanze neterminálů netisknutelné znaky (zobrazené jako UTF-8 znaky), viz. příklad: 1812 [] 1813 [] 1818 M4: příklady 1818 [pro informaci] 1818 Znaky {(uvozovky), (hranaté závorky), (netisknutelné znaky), (UTF-8 znaky)} v názvu příkladu řídí expanzi neterminálů. 1826 JSON: levá závorka 1833 Uvnitř hranatých závorek . Proto je levá hranatá závorka nahrazena makrem z kořenového souboru. 1847 Bash: počítadla 1854 Počítadla a jsou definována v souboru . Neterminály nebudou expandovány, pouze se odeberou vnější závorky. Nutno použít makro z kořenového souboru. 1865 [] 1874 .h: závorky , , , 1881 Prázdný pár (nebo prázdný symbol v závorkách ) slouží jako oddělovač symbolů. Závorky kolem znaku komentáře vypnou jeho původní význam, stejně jako vypnou význam silnějšího M4 komentáře . Vypnou také původní význam čárky jako oddělovače argumentů maker. Tyto symboly se stanou obyčejnými terminálními symboly bez jakéhokoliv vedlejšího efektu. 1896 [] 1902 [] 1908 AWK: příklady bezpečnějších maker 1915 Univerzální výstraha se ignoruje bez závorek, stejně jako , , … Taková makra explicitně vytváří vývojář skriptů, prohlédněte si kořenový soubor . 1924 [] 1931 [] 1941 Proč používat M4 a proč ne? 1941 [pro informaci] 1941 Znaky {(uvozovky), (hranaté závorky), (netisknutelné znaky), (UTF-8 znaky)} v názvu příkladu řídí expanzi neterminálů. 1950 Proč generovat kód v M4 1957 přímé použití bezkontextové gramatiky (rekurze zdarma) pro transformaci dat stačí napsat minimum M4 kódu 1957 přímé použití automatů možnost vymodelovat si potřebné algoritmy (M4 nepotřebuje verze) 1957 přímé použití zásobníků zásobníky propojené s automaty rozšiřují možnosti generátoru kódu 1957 přímé použití výstupních front pro dočasné uložení výsledných částí kódu jednotlivé fronty jsou na závěr vypsány na výstup ve vzestupném pořadí 1957 výrazně vyšší rychlost generování kódu (ve srovnání s XSLT) nízké nároky na výpočetní zdroje 2007 Proč se vyhnout M4 2014 univerzální jazyk nízké úrovně (podobně jako jazyk C) což výměnou poskytuje ohromnou flexibilitu jako UNIX 2014 téměř neexistující komunita vývojářů (podzim 2019) M4 je zapomenutý jazyk, málo existujících projektů 2014 neobvyklé programovací paradigma vyžadující splnění několika předpokladů právě proto lze M4 považovat za náročný jazyk 2014 produktivita značně závisí na zkušenostech (možný problém s termíny) psaní M4 skriptů vyžaduje základní znalost automatů a gramatik 2014 údržba špatně napsaného M4 kódu není jednoduchá existující M4 kód je snadné proměnit ve zmatek (nutný dohled!) --- 62 Generování kódu v M4 šablona s příklady pro www.root.cz (Root.cz – informace nejen ze světa Linuxu) 157 A General Purpose Macro-generator Computer Journal 8, 3 (1965), 225–41 278 RATFOR — A Preprocessor for a Rational Fortran Brian W. Kernighan 362 The M4 Macro Processor Bell Laboratories (1977) 371 Christopher Strachey Computer Hope – Free computer help since 1998 371 Dennis Ritchie Zomrel tvorca Unixu a jazyka C 371 Brian Kernighan An Interview with Brian Kernighan 411 GNU M4 - GNU macro processor Free Software Foundation 1034 Teorie automatů From Wikipedia, the free encyclopedia 1119 GNU Make Manual Free Software Foundation 1136 Vim – všudypřítomný textový editor který edituje text rychlostí myšlenky 1155 Automaty a formální jazyky I Učební text FI MU 1169 Automaty a gramatiky Michal Chytil, 1. vydání, Praha, 331 s. 1984.