Syntactische preprocessoren werden geïntroduceerd met de Lisp-familie van talen. Hun taak is syntaxisbomen te transformeren volgens een aantal door de gebruiker gedefinieerde regels. Bij sommige programmeertalen worden de regels in dezelfde taal geschreven als het programma (compile-time reflection). Dit is het geval bij Lisp en OCaml. Sommige andere talen vertrouwen op een volledig externe taal om de transformaties te definiëren, zoals de XSLT preprocessor voor XML, of zijn statisch getypeerde tegenhanger CDuce.
Syntactische preprocessoren worden typisch gebruikt om de syntaxis van een taal aan te passen, een taal uit te breiden door nieuwe primitieven toe te voegen, of een domeinspecifieke programmeertaal (DSL) in te bedden in een taal voor algemeen gebruik.
Aanpassing van de syntaxisEdit
Een goed voorbeeld van aanpassing van de syntaxis is het bestaan van twee verschillende syntaxis in de programmeertaal Objective Caml. Programma’s kunnen onverschillig worden geschreven met de “normale syntaxis” of de “herziene syntaxis”, en kunnen op verzoek met een van beide syntaxis worden bijgewerkt.
Op soortgelijke wijze passen een aantal in OCaml geschreven programma’s de syntaxis van de taal aan door toevoeging van nieuwe operatoren.
Uitbreiding van een taalEdit
De beste voorbeelden van taaluitbreiding door middel van macro’s zijn te vinden in de Lisp-familie van talen. Hoewel de talen op zichzelf eenvoudige dynamisch getypeerde functionele kernen zijn, staan de standaard distributies van Scheme of Common Lisp imperatief of object-georiënteerd programmeren toe, evenals statische typering. Bijna al deze eigenschappen worden geïmplementeerd door syntactische voorbewerking, hoewel opgemerkt moet worden dat de “macro expansie” fase van compilatie in Lisp door de compiler wordt afgehandeld. Dit kan nog steeds beschouwd worden als een vorm van preprocessing, omdat het plaatsvindt voor andere fasen van compilatie.
Het specialiseren van een taalEdit
Eén van de ongebruikelijke eigenschappen van de Lisp taalfamilie is de mogelijkheid om macro’s te gebruiken om een interne DSL te maken. In een groot op Lisp gebaseerd project kan een module worden geschreven in een aantal van dergelijke minilanguages, een die misschien een SQL-gebaseerd dialect van Lisp gebruikt, een andere geschreven in een dialect gespecialiseerd voor GUIs of pretty-printing, enz. De standaard bibliotheek van Common Lisp bevat een voorbeeld van dit niveau van syntactische abstractie in de vorm van de LOOP macro, die een Algol-achtige minilanguage implementeert om complexe iteratie te beschrijven, terwijl toch het gebruik van standaard Lisp operatoren mogelijk blijft.
De MetaOCaml preprocessor/taal biedt vergelijkbare mogelijkheden voor externe DSLs. Deze preprocessor neemt de beschrijving van de semantiek van een taal (d.w.z. een interpreter) en, door een combinatie van compile-time interpretatie en code generatie, verandert die definitie in een compiler naar de OCaml programmeertaal-en vanuit die taal, hetzij naar bytecode of naar native code.