Preprocesor: Porovnání verzí

Odebrány 2 bajty ,  před 11 lety
m
Oprava překlepů a některých výrazů
(Formulace)
m (Oprava překlepů a některých výrazů)
'''Preprocesor''' je [[počítačový program]], který zpracovává vstupní data tak, aby výstup mohl dále zpracovávat jiný program. Preprocesor je často používán pro předzpracování [[zdrojový kód|zdrojového kódu]] před vlastnímvlastní [[Překladač|kompilací]]. Druh a míra předzpracování závisí zejména na schopnostech preprocesoru. Většina preprocesorů je relativně jednoduchá, zvládá nahrazování textu a jednoduchá [[Makro (software)|makra]]. Existují též sofistikované preprocesory, případně plně rozvinuté [[Programovací jazyk|programovací jazyky]].
 
Některé programovací jazyky (například [[C (programovací jazyk)|jazyk C]]) vždy používají preprocesor ve fázi, která se nazývá ''preprocesing''.
 
== Lexikální preprocesory ==
Lexikální preprocesory jsou nejnižším stupněm preprocesorů. Pro svoji činnost využívají pouze [[lexikální analýza|lexikální analýzu]], tzn. že, pracují se zdrojovým kódem pouze jako s obyčejným textem. Ve vstupním textu provádějí úpravy typu: najít a nahradit, použít makro, připojit externí soubor, atd.
 
=== Preprocesing v jazyce C/C++ ===
nebo
<source lang="c">#include <...></source>
Rozdíl mezi těmito příkazy je pouze v umístění, kde bude preprocesor zadaný soubor hledat. "..." značí lokalnílokální hlavičkový soubor v projektu. <...> znamená soubor umístěný v některém společném úložišti hlavičkových souborů pro všechny projekty.
Na ukázku, připojení souborů <code><[[math.h]]></code> a <code><[[stdio.h]]></code> ze standardní C/C++ knihovny umožňuje využívat matematické a I/O operace.
 
Avšak takovýtoZmíněný lexikální preprocesor není schopný ohlídat vícenásobné připojení jednoho hlavičkového souboru nebo dokonce cyklické připojování hlavičkových souborů. Mimo jiné je takovýtotento přístup pomalý, neboť je nutné před každou kompilací připojovat hlavičkové soubory, ikdyž se v nich nic nezměnilo.
 
Od roku 1970, bylo vymyšleno mnoho alternativ hlavičkových souborů používanýchz v jazycejazyka C/C++. Tyto alternativy jsou mnohdy efektivnější, rychlejší a použití je přehlednější. Vybrané implementace zdílených souborů: [[Java_(programovací_jazyk)|Java]] a [[Common Lisp]] používají balíčky, [[Pascal_(programovací_jazyk)|Pascal]] má unity, [[Modula-2|Modula]], [[OCaml]], [[Haskell_(programovací_jazyk)|Haskell]] a [[Python]] mají moduly a [[C_Sharp|C#]] podobněvyužívá jakoimporty Javajmených využíváprostorů importyz připojených balíčkůknihoven.
 
==== Makra ====
<source lang="c">#define max(a,b) a > b ? a : b</source>
definuje makro <tt>max</tt> se dvěma parametry <tt>a</tt> a <tt>b</tt>. Takovéto makro může být "voláno" jako funkce (stejnou syntaxí).
Využití maker je v C/C++ velmi významné hlavně při debuginguladění, kdy je možné rychle předefinovat makro a měnit tak kód na mnoha místech zaroveň.
 
To, že se makra nechovají stejně jako funkce si ukážeme na následujícím příkladu, kde <tt>f</tt> a <tt>g</tt> jsou dvě funkce vracející integerInteger. Zavolání <source lang="c">z = max(f(), g());</source>
nevyčíslí <tt>f()</tt>jednou a <tt>g()</tt> taky jednou jak by se dalo čekat iu funkce, nýbrž jedna z fukcí <tt>f</tt> nebo <tt>g</tt> bude vyčíslena dvakrát (v závislosti na tom, která vrací větší číslo). Toto chování může mít za následek katastrofální chování v případě, že záleží na počtu volání <tt>f</tt> nebo <tt>g</tt>.
 
Většina moderních programovacích jazyků již nevyužívá tyto možnosti maker, právě z těchto nejednoznačných důvodů a snadného zaměnění za funkce. Z toho důvodu existují v dnešních jazycích pouze funkce nebo metody.
 
==== Podmíněný překlad ====
Preprocesor jazyka C/C++ podporuje podmíněnou kompilaci. To umožňuje mít více verzí stejného kódu, který se například liší ve výpisu logovacích informací anebo podobněje platformě závislý. Takto je možné do jednoho zdrojového kódu napsat program kompilovatelný na více platforem, či různé jazykové mutace, ...
 
Nejčastěji se používá následující konstrukce:
<source lang="c">
#ifndef FOO_HSOUBOR_H
#define FOO_HSOUBOR_H
...(headerzdrojový filekód codehlavičkového souboru)...
#endif
</source>
Programátor tím zabraňuje mnohonásobnému připojení hlavičkového souboru. Tímto problémem smejsme se zabývali výše.
 
PodmínkyPodmíněný preprocesurupřeklad je možné využít v kompexnějších případech jako je tento:
<source lang="c">
#ifdef DEBUG
</source>
 
Naneštěstí většina moderních programovacích jazyků odstraňuje tuto schopnost a uchyluje se k tradičnímu použití <code>if...then...else...</code>. To má ale za následek pomalejší běh programu, neboť tato podmínka musí být vyhodnocena za běhu programu a nikoliv pouze při kompilaci.
 
== Syntaktické preprocesory ==
Syntaktické preprocesory byly poprvé představeny v jazyce [[Lisp]]. Jejich úkolem je převést syntaktickésyntaktický strom na sérii uživatelem definovaných přepisovacích pravidel. V několika jazycích jsou pravidla napsána ve stejném jazyce jako program (compile-time reflection), případ právě jazyka [[Lisp]] a [[OCaml]]. Ostatní jazyky mají tyto pravidla definovanádefinována v jiných jazycích jako například [[XSLT]] preprocesor pro [[XML]] nebo statické [[CD]].
 
Syntaktické preprocesory jsou typicky použity pro individuální přizpůsobení jazyka, doplnění nových primitiv, atd. Takto je možné dosáhnout všeobecně použitelného programovacího jazyka.
 
=== Přizpůsobení syntaxe ===
Dobrý příklad se nachází na adrese http://caml.inria.fr/pub/docs/manual-camlp4/manual007.html. Program může být zapsán dvěma různými syntaxemi při zachování stejné funkčnosti a záleží hlavně na subjektivním posouzení programátoraprogramátorem.
 
Velký počet programů napsaných v [[OCaml]] přispůsobuje syntaxi doplněním nových operátorů. Definici vlastních operátorů podporuje i jazyk C++.
 
=== Specializace jazyka ===
Jedna z neobvyklých vlastností jazyka [[Lisp]] je možnost použít makra k vytvoření vlastního minijazyka uvnitř projektu. Typicky ve velkých projektech bývají některé moduly napsány v takovýchto minijazycích. Modul pro přístup k [[SQL]] databázi využívá dialekt se základem právě v SQL příkazech. Jiné moduly mohou využívat jiné minijazyky, například modul pro práci s [[GUI]], tiskem, atd. Standardní knihovna [[Common Lisp]] obsahuje příklad tohoto typu, kdy se k využívá ke složitému iterování v cyklu minijazyk založený na jazyce [[Algol]].
 
== Všeobecně použitelné preprocesory ==
Drtivá většina preprocesorů je zaměřena na jeden konkrétní jazyk, resp. spolupracuje s konkrétním kompilátorem. Ale existují také tzv. ''všeobecně použitelné'' preprocesory, které nejsou svázány s konkrétním jazykem. V takovýchtotakových případech je možné preprocesor "programovat" vlastními pravidly pro každý konkrétní programovací jazyk.
 
== Související články ==