Syntaktiska preprocessorer introducerades med Lisp-familjen av språk. Deras roll är att omvandla syntaxträd enligt ett antal användardefinierade regler. För vissa programmeringsspråk är reglerna skrivna på samma språk som programmet (kompilationstidsreflektion). Detta är fallet med Lisp och OCaml. Vissa andra språk förlitar sig på ett helt externt språk för att definiera omvandlingarna, t.ex. preprocessorn XSLT för XML eller dess statiskt typade motsvarighet CDuce.
Syntaktiska preprocessorer används vanligen för att anpassa ett språks syntax, utöka ett språk genom att lägga till nya primitiver eller för att bädda in ett domänspecifikt programmeringsspråk (DSL) i ett allmängiltigt språk.
Anpassning av syntaxEdit
Ett bra exempel på syntaxanpassning är förekomsten av två olika syntaxer i programmeringsspråket Objective Caml. Program kan skrivas likgiltigt med hjälp av den ”normala syntaxen” eller den ”reviderade syntaxen”, och kan på begäran skrivas ut vackert med endera syntaxen.
På liknande sätt anpassar ett antal program skrivna i OCaml språkets syntax genom att lägga till nya operatörer.
Utvidgning av ett språkRedigera
De bästa exemplen på språkutvidgning med hjälp av makron finns i Lisp-familjen av språk. Även om språken i sig själva är enkla dynamiskt typade funktionella kärnor, tillåter standarddistributionerna av Scheme eller Common Lisp imperativ eller objektorienterad programmering samt statisk typning. Nästan alla dessa funktioner implementeras genom syntaktisk förbehandling, även om det är värt att notera att kompileringsfasen ”makroexpansion” hanteras av kompilatorn i Lisp. Detta kan fortfarande betraktas som en form av förbehandling, eftersom det sker före andra faser av kompileringen.
Specialisera ett språkRedigera
En av de ovanliga egenskaperna hos Lisp-familjen av språk är möjligheten att använda makron för att skapa en intern DSL. Typiskt för ett stort Lisp-baserat projekt är att en modul kan skrivas i en mängd sådana minispråk, där en modul kanske använder en SQL-baserad dialekt av Lisp, en annan är skriven i en dialekt som är specialiserad för grafiska gränssnitt eller för att skriva ut vackra utskrifter, osv. Common Lisps standardbibliotek innehåller ett exempel på denna nivå av syntaktisk abstraktion i form av LOOP-makrot, som implementerar ett Algol-liknande minispråk för att beskriva komplexa iterationer, samtidigt som det fortfarande gör det möjligt att använda standardoperatorer från Lisp.
Preprocessorn/språket MetaOCaml tillhandahåller liknande funktioner för externa DSL:er. Denna preprocessor tar beskrivningen av ett språks semantik (dvs. en tolk) och genom att kombinera tolkning vid kompilering och kodgenerering förvandlar den definitionen till en kompilator för OCaml-programmeringsspråket – och från det språket, antingen till bytekod eller till inhemsk kod.