構文プリプロセッサはLisp系列の言語から導入された。 その役割は、ユーザが定義したいくつかの規則に従って構文木を変換することである。 いくつかのプログラミング言語では、ルールはプログラムと同じ言語で書かれている(コンパイル時反映)。 LispやOCamlがそうである。 他のいくつかの言語は、XML用のXSLTプリプロセッサやその静的型付けされた対応するCDuceのように、変換を定義するために完全に外部言語に依存している。
構文プリプロセッサは通常、言語の構文をカスタマイズするため、新しいプリミティブを追加して言語を拡張するため、または汎用言語の内部にドメイン特有プログラミング言語(DSL)を組み込むために使われる。
シンタックスのカスタマイズEdit
シンタックスのカスタマイズの良い例は、プログラミング言語 Objective Caml に 2 つの異なる構文が存在することである。
同様に、OCamlで書かれた多くのプログラムは、新しい演算子を追加することによって言語の構文をカスタマイズしている。 この言語自体は単純な動的型付けされた関数型コアであるが、 SchemeやCommon Lispの標準配布版は、静的型付けだけでなく、命令型やオブジェクト指向プログラミングも可能である。 これらの機能はほとんど構文前処理によって実現されているが、 Lispではコンパイル時の「マクロ展開」フェーズがコンパイラによって処理されることは特筆すべき点である。 3541>
言語の特殊化編集
Lispファミリーの言語の珍しい特徴の1つは、マクロを使って内部DSLを作ることができる点である。 一般に、大規模なLispベースのプロジェクトでは、モジュールは、SQLベースのLispの方言を使用するもの、GUIやプリティープリンティングに特化した方言で書かれたものなど、様々なミニランゲージで書かれることがある。 Common Lispの標準ライブラリは、LOOPマクロという形でこのレベルの構文抽象化の例を含んでおり、これは複雑な反復を記述するAlgolライクなミニ言語を実装しているが、同時に標準Lisp演算子の使用も可能にしている。 このプリプロセッサは言語(すなわちインタプリタ)の意味論の記述を取り、 コンパイル時の解釈とコード生成を組み合わせることにより、 その定義をOCamlプログラミング言語へのコンパイラに変え、 その言語からバイトコードまたはネイティブコードへの変換を行う。