En informatique, un compilateur de compilateur est un programme capable de produire la totalité ou certaines parties du code source d'un compilateur (partie analyse lexicale, partie analyse syntaxique, partie analyse sémantique, partie synthèse, partie de gestion des erreurs, etc.) pour former en un tout cohérent, le code source du compilateur souhaité.
Comme un compilateur classique, il accepte un langage source, par exemple une grammaire couplée à un ensemble d'actions. Il crée un langage cible, le plus souvent des parties d'analyse lexicale et syntaxique. Les parties d'analyse sémantique et de synthèse sont généralement trop proches du langage cible pour être produites automatiquement et leur réalisation est laissée à la charge de l'utilisateur. Certains compilateurs de compilateur permettent de créer également une partie de gestion des erreurs.
De façon plus radicale, le principe de van Wijngaarden « une grammaire est un langage de programmation » permet de voir les grammaires comme des spécifications exécutables. De fait, non seulement les grammaires sont nécessaires, mais les grammaires à deux niveaux peuvent avoir la puissance d'une machine de Turing (M. Sintzoff, C.H.A. Koster, Cleaveland, Uzgalis). Les notions paramétrées par des métanotions (resp. des affixes) et la distinction entre notion possible et notion nécessaire permettent de définir précisément des grammaires de transformation contextuelles, couvrant les quatre aspects des langages : syntaxe de surface (ou syntaxe concrète), syntaxe abstraite, sémantique statique (contrôle de cohérence) et sémantique dynamique. Elles facilitent concrètement la détection des erreurs et le pilotage de la génération.
L'utilisation, en Prolog, des definite clause grammars (DCG) s'inscrit partiellement dans cette voie.
Typiquement, un compilateur de compilateur est alors un compilateur CC de grammaire à deux niveaux G dans un langage usuel U.
Un nouveau compilateur d'un langage S en un langage K étant écrit dans le formalisme grammatical G, CC produit un compilateur de S dans K, écrit dans le langage U.