Tại sao trình biên dịch tự lưu trữ được coi là một nghi thức thông qua cho các ngôn ngữ mới?


30

Bây giờ tôi đã nghe nói ở một số nơi mà mọi người mong đợi các ngôn ngữ sẽ sử dụng hoặc ít nhất là có một trình biên dịch tự lưu trữ để xứng đáng được tôn trọng.

Tôi tò mò về lý do tại sao điều này là. Một trình biên dịch có vẻ như là một phần mềm rất quan trọng để viết và tôi tưởng tượng không phải tất cả các ngôn ngữ đều phù hợp để tạo ra chúng. Sẽ không có ý nghĩa hơn khi dành nỗ lực làm việc trong một cái gì đó sẽ cho kết quả tốt hơn?


17
"Trình biên dịch có vẻ như là một phần mềm rất quan trọng để viết và tôi tưởng tượng rằng không phải tất cả các ngôn ngữ đều phù hợp để tạo ra chúng.": Tôi sẽ coi đây là một lý do rất tốt để cố gắng viết trình biên dịch sang ngôn ngữ mới, cụ thể là để chứng minh rằng ngôn ngữ là tùy theo nhiệm vụ.
Giorgio

13
Trừ khi đó là ngôn ngữ có mục đích đặc biệt, một ngôn ngữ không phù hợp để viết trình biên dịch có lẽ không phù hợp với những gì tôi muốn làm.
CodeInChaos

3
AFAIK, điều này không phải lúc nào cũng đúng với Fortran. Một số trình biên dịch Fortran (ví dụ gfortrantừ GCC ...) không được mã hóa trong Fortran.
Basile Starynkevitch

Câu trả lời:


29

Sẽ không có ý nghĩa hơn khi dành nỗ lực làm việc trong một cái gì đó sẽ cho kết quả tốt hơn?

Như thế nào?

Điều hay ho về trình biên dịch là chúng không có nhiều phụ thuộc. Điều này làm cho họ trở thành ứng cử viên tốt cho một ngôn ngữ mới có khả năng chưa có thư viện tiêu chuẩn rất lớn hoặc đa dạng.

Tốt hơn nữa, họ đòi hỏi nhiều thứ, trong khi cũng được nghiên cứu kỹ lưỡng. Sự đa dạng giúp đảm bảo rằng ví dụ của bạn kiểm tra các phần khác nhau của ngôn ngữ. Được nghiên cứu tốt có nghĩa là bạn có các trình biên dịch khác để so sánh với - cũng như tạo thêm uy tín cho các loại học thuật mà bạn biết bạn đang làm gì.

Và trong khi các trình biên dịch có vẻ như là một tấn công việc, thì chúng khá nhỏ trong sơ đồ lớn. Nếu những người thực hiện ngôn ngữ thậm chí không thể làm điều gì đó họ đã làm trước đây bằng ngôn ngữ mới, thì họ sẽ làm những điều mới lạ như thế nào? Làm thế nào họ sẽ xử lý những thứ thực sự lớn như thư viện tiêu chuẩn hoặc IDE?


Cũng như một ghi chú bên lề, tôi muốn đề cập rằng mặc dù đẹp, nhưng vẫn có nhiều lý do mà trình biên dịch có thể được viết bằng ngôn ngữ khác. Chẳng hạn, hầu hết các công cụ javascript không được viết bằng javascript. Có nhiều lý do cho việc này: tích hợp với phần mềm khác, liên kết với các thư viện / phụ thuộc hiện có, công cụ ưu việt, hiệu suất, mã kế thừa ... Đôi khi, tự biên dịch ngôn ngữ là tốt, nhưng vẫn hợp lý để duy trì trình biên dịch lõi khác. Tuy nhiên, ngôn ngữ tự nó có ý nghĩa. Chỉ là bạn thường không đủ khả năng để phát triển lại toàn bộ hệ sinh thái.
dagnelies

2
@arnaud Và thực tế là trình biên dịch Javascript sẽ yêu cầu môi trường Javascript, không thể viết bằng Javascript vì Javascript yêu cầu môi trường Javascript, <lặp lại nghịch lý> , vì môi trường Javascript không được cung cấp bởi hệ điều hành (và nếu là, nó sẽ không được viết bằng Javascript).
Qix

3
@Qix en.wikipedia.org/wiki/Bootstrapping_%28compilers%29 Nhưng chủ yếu không có lý do để sử dụng nó. Nó được biết đến rộng rãi như một ngôn ngữ nghèo nàn, các trình duyệt thoát khỏi việc không sử dụng nó để biên dịch vì chúng kiểm soát được tình hình :), trong khi những người còn lại không có lựa chọn nào trên web.
Den

3
Tôi không chắc lắm về việc những người khác không có nhiều sự phụ thuộc. Điều đó có thể đúng với front-end của trình biên dịch . Nhưng ngay khi bạn có AST, việc tối ưu hóa trình tạo mã và trình tạo mã của riêng bạn không giống như một tuyến đường đầy hứa hẹn. Ngoài thực tế là các kỹ thuật tối ưu hóa hiện đại đòi hỏi các công cụ logic chính thức tinh vi mà người ta có thể muốn sử dụng thư viện của bên thứ ba, không có lý do gì để phát minh lại bánh xe cho mọi ngôn ngữ mới thay vì xây dựng nền tảng sức mạnh công nghiệp như GCC hoặc LLVM.
5gon12eder

30

Mục tiêu của việc có một trình biên dịch bằng ngôn ngữ đang được biên dịch thường là một phần của việc thực hành " ăn thức ăn cho chó của riêng bạn ". Nó cho thế giới thấy rằng bạn coi ngôn ngữ, trình biên dịch và hệ sinh thái của các mô-đun và công cụ hỗ trợ là "đủ tốt cho công việc nghiêm túc" hoặc "sẵn sàng sản xuất".

Nó cũng có tác dụng đạo đức khi buộc những người gần gũi nhất với ngôn ngữ, trình biên dịch và thiết kế thời gian chạy phải đối mặt trực tiếp với các tác động của tất cả các quyết định mà họ đã đưa ra và các ưu tiên phát triển mà họ đã chọn - mụn cóc và tất cả. Điều này thường dẫn đến một nhóm cốt lõi không chỉ hiểu môi trường ngôn ngữ trong lý thuyết, mà còn có kinh nghiệm thực tế sâu rộng bằng cách sử dụng ngôn ngữ / công cụ trong các điều kiện khó khăn của từ thực tế.


1
cho đầy đủ: ăn thức ăn cho chó của riêng bạn ; xem dog fed (adj.) hoặc dogfooding (động từ)
Qix

17

Mọi người tạo ra các ngôn ngữ có mục đích chung mới vì một lý do chính: họ ghét ít nhất một điều về mọi ngôn ngữ khác ngoài kia. Đây là lý do tại sao rất nhiều ngôn ngữ không được khởi đầu. Bạn có một ý tưởng tuyệt vời cho một ngôn ngữ sẽ cải thiện cuộc sống lập trình của bạn, nhưng bạn phải thực hiện lần đầu tiên bằng một ngôn ngữ gây khó chịu cho bạn theo ít nhất một cách. Tự lưu trữ có nghĩa là bạn không còn phải làm việc trong ngôn ngữ gây phiền nhiễu cũ. Đó là lý do tại sao những người sáng tạo ngôn ngữ làm việc theo bước đó và xem đó là một cột mốc quan trọng.

Rất nhiều tính năng ngôn ngữ có vẻ tốt trên giấy, nhưng khi bạn bắt đầu sử dụng chúng trong một dự án thực tế, bạn bắt đầu thấy những hạn chế của chúng. Ví dụ, rất nhiều ngôn ngữ lúc đầu không có hỗ trợ unicode. Hoàn thành một dự án lớn giúp đảm bảo rất nhiều tình huống đã gặp phải và xử lý, và một trình biên dịch tự lưu trữ cũng là một dự án tốt như bất kỳ. Đó là lý do tại sao những người khác ngoài những người sáng tạo ngôn ngữ coi đó là một cột mốc quan trọng.

Điều đó không có nghĩa đó là cột mốc duy nhất đáng chú ý. Có các chức năng không được trình biên dịch thực hiện, chẳng hạn như tích hợp cơ sở dữ liệu, giao diện đồ họa, mạng, v.v.


Tôi cảm thấy như ngôn ngữ (bản địa) là ngôn ngữ khi nó có thể tự biên dịch hạt nhân linux có thể được chuyển sang ngôn ngữ đó (vì nó bao gồm hầu hết / tất cả các tác vụ cần thiết cho hầu hết các hệ điều hành hiện đại hoạt động).
Qix

Mặc dù vậy, hỗ trợ Unicode Decent không thực sự cần thiết để viết trình biên dịch.
Paŭlo Ebermann

11

Steve Yegge đã viết một bài đăng blog tuyệt vời rằng, phần nào gián tiếp, giải quyết điều này.

Điểm lớn # 1: trình biên dịch bao gồm khá nhiều khía cạnh của khoa học máy tính. Chúng là một khóa học cấp cao hơn bởi vì bạn cần biết tất cả những điều khác bạn học trong chương trình khoa học máy tính chỉ để bắt đầu. Cấu trúc dữ liệu, tìm kiếm và sắp xếp, hiệu suất tiệm cận, tô màu đồ thị? Tất cả đều ở đó.

Có một lý do Knuth đã làm việc với "Nghệ thuật lập trình máy tính" hoành tráng (và không bao giờ kết thúc) của mình trong nhiều thập kỷ, mặc dù nó bắt đầu như (chỉ) một cuốn sách giáo khoa biên dịch. Cũng giống như cách Carl Sagan nói "Nếu bạn muốn tạo ra một chiếc bánh táo từ đầu, trước tiên bạn phải phát minh ra vũ trụ", nếu bạn muốn viết một trình biên dịch, trước tiên bạn phải đối phó với gần như mọi khía cạnh của khoa học máy tính.

Điều đó có nghĩa là nếu trình biên dịch tự lưu trữ, thì nó khá chắc chắn để có thể làm những gì tôi cần, bất kể tôi đang làm gì. Ngược lại, nếu bạn không viết trình biên dịch bằng ngôn ngữ của mình, rất có thể nó sẽ bỏ lỡ điều gì đó thực sự quan trọng đối với ai đó, bởi vì những người thực hiện ngôn ngữ không bao giờ phải viết một chương trình đòi hỏi họ phải suy nghĩ về tất cả những vấn đề đó.

Điểm lớn thứ 2: từ 30.000 feet, một số vấn đề đáng ngạc nhiên trông giống như trình biên dịch.

Trình biên dịch lấy một luồng các ký hiệu, tìm ra cấu trúc của chúng theo một số quy tắc được xác định trước theo miền cụ thể và chuyển đổi chúng thành một luồng ký hiệu khác. Nghe có vẻ khá chung chung phải không? À vâng.

Cho dù bạn có thuộc nhóm Visual C ++ hay không, bạn sẽ rất thường xuyên thấy mình cần phải làm một cái gì đó trông giống như một phần của trình biên dịch. Tôi làm điều đó theo nghĩa đen mỗi ngày.

Không giống như hầu hết các ngành nghề khác, lập trình viên không chỉ sử dụng các công cụ, mà xây dựng các công cụ của riêng họ. Một lập trình viên không thể (do thiếu kỹ năng hoặc thiếu công cụ có thể sử dụng để xây dựng các công cụ khác) công cụ viết sẽ mãi mãi bị vô hiệu hóa, giới hạn trong các công cụ mà người khác cung cấp.

Nếu một ngôn ngữ "không phù hợp để tạo" các chương trình có thể lấy một luồng ký hiệu, áp dụng quy tắc cho chúng và biến nó thành một luồng ký hiệu khác, thì âm thanh đó có vẻ là một ngôn ngữ khá hạn chế và không phải là ngôn ngữ hữu ích với tôi.

(May mắn thay, tôi không nghĩ rằng có nhiều ngôn ngữ lập trình không phù hợp với việc chuyển đổi các biểu tượng. C có lẽ là một trong những ngôn ngữ tồi tệ nhất được sử dụng ngày nay, tuy nhiên trình biên dịch C thường tự lưu trữ, do đó không bao giờ dừng bất kỳ ai.)

Một lý do thứ ba tôi sẽ kết thúc, từ kinh nghiệm cá nhân, không được đề cập bởi Yegge (vì anh ta không viết về "tại sao tự lưu trữ"): nó loại bỏ các lỗi. Khi bạn đang viết một trình biên dịch, điều đó có nghĩa là mỗi khi bạn xây dựng nó (không chỉ mỗi lần bạn chạy nó), bạn phụ thuộc vào nó để làm việc và hoạt động chính xác với một cơ sở mã có kích thước phù hợp (chính trình biên dịch).

Tháng này tôi đã sử dụng một trình biên dịch không tự lưu trữ tương đối mới và nổi tiếng (bạn có thể đoán được cái nào) và tôi không thể đi 2 ngày mà không làm hỏng việc. Tôi tự hỏi bao nhiêu nhà thiết kế thực sự phải sử dụng nó.


8

Nếu bạn muốn có một trình biên dịch cho ngôn ngữ X là tự lưu trữ, trước tiên bạn phải triển khai nó bằng một số ngôn ngữ khác, ví dụ như Y, nó lấy đầu vào cho ngôn ngữ X và phun ra mã lắp ráp, hoặc một số mã trung gian hoặc thậm chí mã đối tượng cho máy mà trình biên dịch đang chạy. Bạn muốn chọn ngôn ngữ Y giống với ngôn ngữ X nhất có thể, vì tại một số điểm, bạn sẽ dịch mã được viết bằng Y sang X.

Nhưng bạn không muốn viết thêm bất kỳ trình biên dịch nào bằng ngôn ngữ Y hơn mức cần thiết, vì vậy, để bắt đầu, bạn chỉ thực hiện một tập hợp con của ngôn ngữ - loại bỏ các cấu trúc dư thừa. Trong trường hợp ngôn ngữ loại 'C', trong khi nhưng không cho hoặc làm trong khi . nếu nhưng không có trường hợp hoặc đại học op. Không có cấu trúc hoặc công đoàn hoặc liệt kê. V.v. Những gì bạn còn lại chỉ đủ ngôn ngữ để viết trình phân tích cú pháp và trình tạo mã thô sơ cho ngôn ngữ X. Sau đó kiểm tra đầu ra. Lần nữa.

Khi bạn đã làm việc này, bạn có thể viết lại nguồn trình biên dịch được viết bằng ngôn ngữ Y thành ngôn ngữ X và biên dịch nguồn ngôn ngữ X bằng trình biên dịch được viết bằng ngôn ngữ Y. Đầu ra sẽ là trình biên dịch mới được viết bằng ngôn ngữ X mới. biên dịch ngôn ngữ X, tức là hiện đang tự lưu trữ. Tuy nhiên, nó không hoàn thành vì bạn chỉ thực hiện một tập hợp con của ngôn ngữ trong ngôn ngữ Y.

Vì vậy, bây giờ bạn thêm vào các tính năng còn thiếu, kiểm tra từng tính năng (hoặc nhóm tính năng) mà chúng tạo mã chính xác. tức là một khi tính năng được triển khai trong trình biên dịch, bạn có thể viết chương trình kiểm tra bằng cách sử dụng (các) tính năng mới, biên dịch và kiểm tra chúng, nhưng bạn chưa nên sử dụng chúng trong nguồn trình biên dịch. Khi (các) tính năng mới được xác minh, bạn có thể sử dụng các tính năng mới này trong chính nguồn biên dịch - có thể thay thế một số mã gốc được viết trong tập hợp ngôn ngữ - biên dịch lại nguồn trình biên dịch bằng phiên bản với các tính năng mới.

Bây giờ bạn có một cơ chế để thêm các tính năng mới vào ngôn ngữ - và, khi việc tạo mã cho các tính năng đã được xác minh chính xác, chúng có thể được sử dụng trong thế hệ tiếp theo của chính trình biên dịch.

Cách đây 60 năm hoặc lâu hơn khi máy tính xuất hiện lần đầu tiên (và sau đó là lần đầu tiên khi bộ vi xử lý đến), không có ngôn ngữ nào khác Y phù hợp để thực hiện trình biên dịch ban đầu. Vì vậy, các trình biên dịch đầu tiên phải được viết bằng mã lắp ráp, và sau đó khi đủ trình biên dịch đang chạy, mã lắp ráp sẽ được thay thế bằng phiên bản được viết bằng ngôn ngữ mới. Không có trình biên dịch nào? Toàn bộ bộ xử lý giảm xuống một cấp độ khác, với trình biên dịch ban đầu được viết bằng mã máy .


2

Có thể tạo ra một ngôn ngữ lập trình không được thiết kế tốt để viết trình biên dịch nhưng được thiết kế tốt cho một số mục đích khác không?

Nhìn vào một ngôn ngữ như SQL tôi cho rằng câu trả lời là có. Nhưng ngôn ngữ có tính chất đó không phải là mục đích chung.


1
Thách thức được chấp nhận: Viết trình biên dịch C bằng SQL.
Qix

2

Ai nói vậy? ... Dù sao, đó chỉ là một ý kiến. Một số có thể đồng ý, một số có thể không, không có đúng hay sai ở đây. Một số ngôn ngữ có trình biên dịch được viết bằng chính nó, những ngôn ngữ khác thì không. Bất cứ điều gì.

Tuy nhiên, tôi nghĩ rằng đó là một bài tập hay bằng chứng khái niệm tốt đẹp nếu một ngôn ngữ có thể "tự biên dịch" ... nó chỉ ... tốt ... và nó cho phép ngôn ngữ phù hợp để làm một số thứ phức tạp.

Tôi cũng muốn đề cập rằng mặc dù đẹp, nhưng vẫn có nhiều lý do một trình biên dịch có thể được viết bằng ngôn ngữ khác. Chẳng hạn, hầu hết các công cụ javascript không được viết bằng javascript. Có nhiều lý do cho việc này: tích hợp với phần mềm khác, liên kết với các thư viện / phụ thuộc hiện có, công cụ ưu việt, hiệu suất, mã kế thừa ... Đôi khi, tự biên dịch ngôn ngữ là tốt, nhưng vẫn hợp lý để duy trì trình biên dịch lõi khác. Tuy nhiên, ngôn ngữ tự nó có ý nghĩa. Chỉ là bạn thường không đủ khả năng để phát triển lại toàn bộ hệ sinh thái.


2

Clang được viết bằng C ++. Sẽ không quá khó để viết lại trình biên dịch Clang Objective-C trong Objective-C, nhưng sau đó nó sẽ khá vô dụng. Mọi thay đổi trong trình biên dịch C ++ sẽ phải được làm lại trong Objective-C và ngược lại. Vậy tại sao?

Giờ đây đã có trình biên dịch Clang Swift. Chắc chắn trình biên dịch đó có thể được viết lại trong Swift. Nhưng mục đích của nó là gì? Để chứng minh rằng ngôn ngữ đủ mạnh để viết trình biên dịch trong đó? Không ai quan tâm nếu bạn có thể viết trình biên dịch trong Swift. Người ta quan tâm nếu bạn có thể viết các giao diện người dùng trong Swift, và bạn được trình diễn có thể.

Nếu bạn có một trình biên dịch được kiểm tra tốt có thể dễ dàng điều chỉnh để biên dịch các ngôn ngữ khác nhau, việc viết lại nó thành các ngôn ngữ khác nhau là vô nghĩa, trừ khi việc viết lại bằng một ngôn ngữ khác sẽ giúp làm việc với trình biên dịch dễ dàng hơn. Và nếu nó có ý nghĩa để viết Clang trong Swift, chẳng hạn, thì các trình biên dịch Clang C, C ++ và Objective-C đều sẽ được viết bằng Swift.

Có nhiều việc quan trọng hơn là chứng minh rằng bạn có thể viết trình biên dịch bằng một số ngôn ngữ lập trình.


1

Nó cho thấy rằng ngôn ngữ có khả năng xử lý xử lý chuỗi phức tạp và dịch sang ngôn ngữ khác / phiên dịch chính nó.

Trong quá trình tạo một trình biên dịch (dự án lớn đầu tiên) sẽ có vấn đề xảy ra.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.