Có thể (nếu tẻ nhạt) để viết mã máy trực tiếp. Có thể bạn viết chương trình xuống trình biên dịch trên một tờ giấy và sau đó bạn dịch nó bằng tay vào các hướng dẫn mã số máy mà bạn nhập vào bộ nhớ máy. Bạn thậm chí có thể bỏ qua bước biên dịch trên trình biên dịch nếu bạn đã ghi nhớ các giá trị số của tất cả các hướng dẫn mã máy - không phổ biến trong những ngày đó, tin hay không!
Các máy tính đầu tiên được lập trình trực tiếp dưới dạng nhị phân bằng cách chuyển đổi các công tắc vật lý. Đó là một cải tiến năng suất tuyệt vời khi phần cứng phát triển để cho phép lập trình viên (hoặc trợ lý nhập dữ liệu) nhập mã theo số thập lục phân thông qua bàn phím!
Trình biên dịch phần mềm chỉ trở nên có liên quan khi có nhiều bộ nhớ hơn (vì mã trình biên dịch chiếm nhiều dung lượng hơn mã máy thô) và phần cứng được phát triển để cho phép nhập chữ và số. Vì vậy, các bộ lắp ráp đầu tiên được viết trực tiếp bởi những người thông thạo mã máy.
Khi bạn có trình biên dịch chương trình, bạn có thể viết trình biên dịch cho ngôn ngữ cấp cao hơn trong trình biên dịch chương trình.
Câu chuyện cho C có nhiều bước. Trình biên dịch C đầu tiên được viết bằng B (tiền thân của C), lần lượt được viết bằng BCPL. BCPL là một ngôn ngữ khá đơn giản (ví dụ: nó hoàn toàn không có loại), nhưng vẫn là một bước tiến từ trình biên dịch thô. Vì vậy, bạn thấy các ngôn ngữ phức tạp hơn dần dần được xây dựng bằng các ngôn ngữ đơn giản hơn tất cả các cách quay lại trình biên dịch. Và bản thân C là một ngôn ngữ khá nhỏ và đơn giản theo tiêu chuẩn ngày nay.
Ngày nay, trình biên dịch đầu tiên cho một ngôn ngữ mới thường được viết bằng C, nhưng khi ngôn ngữ đạt đến độ chín nhất định, nó thường được viết lại "trong chính nó". Trình biên dịch Java đầu tiên được viết bằng C, nhưng sau đó được viết lại bằng Java. Trình biên dịch C # đầu tiên được viết bằng C ++, nhưng gần đây nó đã được viết lại bằng C #. Trình biên dịch / trình thông dịch Python được viết bằng C, nhưng dự án PyPy là một nỗ lực để viết lại nó trong Python.
Mặc dù không phải lúc nào cũng có thể viết trình biên dịch / trình thông dịch cho một ngôn ngữ bằng chính ngôn ngữ đó. Trình thông dịch JavaScript được viết bằng JavaScript tồn tại, nhưng trình biên dịch / trình thông dịch trong các trình duyệt hiện tại vẫn được viết bằng C hoặc C ++ vì lý do hiệu suất. JavaScript được viết bằng JavaScript đơn giản là quá chậm.
Nhưng bạn không phải sử dụng C làm "ngôn ngữ bắt đầu" cho trình biên dịch. Trình biên dịch F # đầu tiên được viết bằng OCaml, đây là ngôn ngữ khác có liên quan chặt chẽ nhất với F #. Khi trình biên dịch hoàn tất, nó đã được viết lại trong F #. Trình biên dịch đầu tiên cho Perl 6 được viết bằng Haskell (một ngôn ngữ chức năng thuần túy rất khác với Perl) nhưng giờ đây có một trình biên dịch được viết bằng C.
Một trường hợp thú vị là Rust, nơi trình biên dịch đầu tiên được viết bằng OCaml (bây giờ nó được viết lại trong Rust). Điều này là đáng chú ý vì OCaml thường được coi là cấp cao hơn Rust, là ngôn ngữ hệ thống gần gũi với kim loại hơn. Vì vậy, không phải lúc nào các ngôn ngữ cấp cao hơn cũng được triển khai bằng các ngôn ngữ cấp thấp hơn, nó cũng có thể là cách khác.