Syntaktické preprocesory byly zavedeny s jazyky rodiny Lisp. Jejich úkolem je transformovat syntaktické stromy podle řady uživatelem definovaných pravidel. U některých programovacích jazyků jsou pravidla zapsána ve stejném jazyce jako program (reflexe při kompilaci). To je případ jazyků Lisp a OCaml. Některé jiné jazyky se při definování transformací spoléhají na zcela externí jazyk, například preprocesor XSLT pro XML nebo jeho staticky typovaný protějšek CDuce.
Syntaktické preprocesory se obvykle používají k přizpůsobení syntaxe jazyka, k rozšíření jazyka přidáním nových primitiv nebo k vložení doménově specifického programovacího jazyka (DSL) do jazyka pro obecné použití.
Přizpůsobení syntaxeEdit
Dobrým příkladem přizpůsobení syntaxe je existence dvou různých syntaxí v programovacím jazyce Objective Caml. Programy mohou být napsány lhostejně pomocí „normální syntaxe“ nebo „revidované syntaxe“ a mohou být na požádání hezky vytištěny s oběma syntaxemi.
Podobně řada programů napsaných v jazyce OCaml přizpůsobuje syntaxi jazyka přidáním nových operátorů.
Rozšíření jazykaEdit
Nejlepší příklady rozšíření jazyka pomocí maker najdeme v rodině jazyků Lisp. Zatímco tyto jazyky samy o sobě jsou jednoduchá dynamicky typovaná funkcionální jádra, standardní distribuce jazyků Scheme nebo Common Lisp umožňují imperativní nebo objektově orientované programování a také statické typování. Téměř všechny tyto vlastnosti jsou implementovány syntaktickým předzpracováním, i když je třeba poznamenat, že fázi kompilace „expanze maker“ v jazyce Lisp zajišťuje překladač. Tu lze stále považovat za formu preprocessingu, protože probíhá před ostatními fázemi kompilace.
Specializace jazykaEdit
Jednou z neobvyklých vlastností rodiny jazyků Lisp je možnost použití maker k vytvoření vnitřního DSL. Typicky v rozsáhlém projektu založeném na jazyku Lisp může být modul napsán v různých takových minijazycích, přičemž jeden může používat dialekt jazyka Lisp založený na SQL, jiný je napsán v dialektu specializovaném na grafické uživatelské rozhraní nebo hezký tisk atd. Standardní knihovna Common Lispu obsahuje příklad této úrovně syntaktické abstrakce v podobě makra LOOP, které implementuje minijazyk podobný Algolu pro popis složité iterace, přičemž stále umožňuje používat standardní operátory Lispu.
Preprocesor/jazyk MetaOCaml poskytuje podobné funkce pro externí DSL. Tento preprocesor přebírá popis sémantiky jazyka (tj. interpretu) a kombinací interpretace v době kompilace a generování kódu mění tuto definici na překladač do programovacího jazyka OCaml – a z tohoto jazyka buď na bajtový kód, nebo na nativní kód.