См. "раскрутка компилятора". Кратко, первый компилятор пишется для минимального подмножества языка на другом языке(или в самом начале веков - на ассемблере, в машкодах), затем на этом подмножестве пишется компилятор, который может компилировать это подмножество, и затем фичи языка наращиваются итеративно. Этакий догфуддинг.