Tady je trochu chyba v úhlu pohledu. Na kompilaci jazyka C (zřejmě platí pro většinu jazyků) do strojového kódu není potřeba kompilátor. Ten překlad se dá udělat s tužkou, papírem, referenční příručkou procesoru a trochou času a zkušeností.
Pro jazyk C se to běžně učilo na VŠ a dodnes se to i dělá v oboru "embedded zařízení". Vezme se program v C a některé jeho funkce se ručně "zkompilují" do assembleru. Takže i dnes může vzniknout "první kompilátor" tím, že ho někdo napíše v assembleru a ten pak ručně převede do strojového kódu. V rámci studia se to dodnes dělá, akorát už ne na PC, ale na něčem jiném. Strojový kód 8086 ještě šel, ale pro nové procesory už je to šílenost. Proto se to učí třebas na mikrořadičích, případně na emulátorech starých procesorů/počítačů (ZX Spectrum, MC68000, PC AT epod.) Starý vtip: opravdový programátor používá "copy con myapp.com".
Další krok je pak "evoluce". V assembleru udělám jen nezbytně nutnou funkcionalitu. Překladač, který vezme zdroják v C a vygeneruje fungující program. Bez optimalizací, bez linkování knihoven atd. V té chvíli mám překladač jazyka C a můžu začít programovat překladač jazyka C, tentokrát nikoliv v assembleru, ale v C. Tím, že to je v C, je snažší do toho implementovat všelijaké optimalizace, linkování atd. Ve chvíli, kdy tenhle nový překladač bude fungovat uspokojivě, můžu začít svůj překladač překládat v tom novém překladači a začít využívat všelijaké optimalizace, dynamické linkování atd. To mi dá ještě větší volnost a možnosti a kolo se roztáčí. Poslední verze překladače pak už nejde přeložit tím "prvním překladačem", protože ten takhle složitý dialekt C nezvládal.