Procure por "bootstrapping".
Basicamente, você começa com um processo / conjunto de funções mínimo que pode ser usado para compilar o código que define um compilador um pouco mais funcional. Isto cria o seu próximo compilador que então pode ser usado para construir código que pode fazer ainda mais. Você repete esse processo até ter um compilador completo que possa compilar todos os recursos do idioma.
A outra alternativa é escrever a primeira versão do compilador em um idioma diferente e depois escrever a próxima versão em seu idioma de destino.