Làm thế nào một trình biên dịch có thể tự biên dịch?


168

Tôi đang nghiên cứu CoffeeScript trên trang web http://coffeescript.org/ và nó có văn bản

Trình biên dịch CoffeeScript được viết bằng CoffeeScript

Làm thế nào một trình biên dịch có thể tự biên dịch, hoặc câu lệnh này có ý nghĩa gì?


14
Một thuật ngữ khác cho trình biên dịch có thể tự biên dịch là self-hostingtrình biên dịch. Xem lập trình
viên.stackexchange.com/q/263651/6221

37
Tại sao trình biên dịch không thể tự biên dịch?
dùng253751

48
Có ít nhất hai bản sao của trình biên dịch liên quan. Một bản có sẵn biên dịch một bản sao mới. Cái mới có thể giống hoặc không giống với cái cũ.
bdsl

12
Bạn cũng có thể quan tâm đến Git: mã nguồn của nó được theo dõi, tất nhiên, trong kho Git.
Greg d'Eon

7
Điều này giống như hỏi "Làm thế nào một Máy in Xerox có thể in sơ đồ cho chính nó?" Trình biên dịch biên dịch văn bản thành mã byte. Nếu trình biên dịch có thể biên dịch thành bất kỳ mã byte có thể sử dụng nào, bạn có thể viết mã trình biên dịch bằng ngôn ngữ tương ứng và sau đó chuyển mã qua trình biên dịch để tạo đầu ra.
RLH

Câu trả lời:


219

Phiên bản đầu tiên của trình biên dịch không thể được tạo bằng máy từ ngôn ngữ lập trình dành riêng cho nó; sự nhầm lẫn của bạn là dễ hiểu. Phiên bản mới hơn của trình biên dịch có nhiều tính năng ngôn ngữ hơn (với nguồn được viết lại trong phiên bản đầu tiên của ngôn ngữ mới) có thể được trình biên dịch đầu tiên xây dựng. Phiên bản đó sau đó có thể biên dịch trình biên dịch tiếp theo, v.v. Đây là một ví dụ:

  1. Trình biên dịch CoffeeScript đầu tiên được viết bằng Ruby, tạo phiên bản 1 của CoffeeScript
  2. Mã nguồn của trình biên dịch CS được viết lại trong CoffeeScript 1
  3. Trình biên dịch CS gốc biên dịch mã mới (được viết bằng CS 1) thành phiên bản 2 của trình biên dịch
  4. Thay đổi được thực hiện cho mã nguồn trình biên dịch để thêm các tính năng ngôn ngữ mới
  5. Trình biên dịch CS thứ hai (cái đầu tiên được viết bằng CS) biên dịch mã nguồn mới được sửa đổi thành phiên bản 3 của trình biên dịch
  6. Lặp lại các bước 4 và 5 cho mỗi lần lặp

Lưu ý: Tôi không chắc chắn chính xác cách các phiên bản CoffeeScript được đánh số, đó chỉ là một ví dụ.

Quá trình này thường được gọi là bootstrapping . Một ví dụ khác về trình biên dịch bootstrapping là rustctrình biên dịch cho ngôn ngữ Rust .


5
Con đường khác để bootstrapping trình biên dịch là viết một trình thông dịch cho (một tập hợp con) ngôn ngữ của bạn.
Aron

Là một thay thế khác cho bootstrapping với trình biên dịch hoặc trình thông dịch được viết bằng ngôn ngữ khác, tuyến đường rất cũ sẽ là lắp ráp thủ công nguồn trình biên dịch. Chuck Moore tìm hiểu cách thực hiện điều này cho một thông dịch viên Forth trong chương 9, "Các chương trình khởi động", ở phần cuối của Lập trình một Ngôn ngữ hướng đến vấn đề ( web.archive.org/web/20160327044521/www.colorforth.com/POL .htm ), dựa trên việc đã thực hiện hai lần trước đó bằng tay. Nhập mã ở đây được thực hiện thông qua một bảng điều khiển phía trước cho phép lưu trữ trực tiếp các giá trị vào các địa chỉ bộ nhớ được điều khiển bằng các công tắc bật tắt cho các bit.
Jeremy W. Sherman

59

Trong bài viết Refl Refl on Trusting Trust , Ken Thompson, một trong những người khởi tạo Unix, viết một cái nhìn tổng quan hấp dẫn (và dễ đọc) về cách trình biên dịch C tự biên dịch. Các khái niệm tương tự có thể được áp dụng cho CoffeeScript hoặc bất kỳ ngôn ngữ nào khác.

Ý tưởng về một trình biên dịch để biên dịch mã riêng của nó là mơ hồ tương tự như một Quine : Mã nguồn đó, khi thực hiện, sản xuất như đầu ra mã nguồn gốc. Đây là một ví dụ về một quine CoffeeScript. Thompson đã đưa ra ví dụ này về một câu hỏi C:

char s[] = {
    '\t',
    '0',
    '\n',
    '}',
    ';',
    '\n',
    '\n',
    '/',
    '*',
    '\n',
    … 213 lines omitted …
    0
};

/*
 * The string s is a representation of the body
 * of this program from '0'
 * to the end.
 */

main()
{
    int i;

    printf("char\ts[] = {\n");
    for(i = 0; s[i]; i++)
        printf("\t%d,\n", s[i]);
    printf("%s", s);
}

Tiếp theo, bạn có thể tự hỏi làm thế nào trình biên dịch được dạy rằng một chuỗi thoát như '\n'đại diện cho mã ASCII 10. Câu trả lời là ở đâu đó trong trình biên dịch C, có một thói quen diễn giải các ký tự, chứa một số điều kiện như thế này để nhận ra các chuỗi dấu gạch chéo ngược:

…
c = next();
if (c != '\\') return c;        /* A normal character */
c = next();
if (c == '\\') return '\\';     /* Two backslashes in the code means one backslash */
if (c == 'r')  return '\r';     /* '\r' is a carriage return */
…

Vì vậy, chúng ta có thể thêm một điều kiện vào đoạn mã trên

if (c == 'n')  return 10;       /* '\n' is a newline */

Để tạo ra một trình biên dịch '\n'đại diện cho ASCII 10. Thật thú vị, trình biên dịch đó và tất cả các trình biên dịch tiếp theo được biên dịch bởi nó , "biết" ánh xạ đó, vì vậy trong thế hệ tiếp theo của mã nguồn, bạn có thể thay đổi dòng cuối cùng thành

if (c == 'n')  return '\n';

Sôi và nó sẽ làm đúng! Xuất 10phát từ trình biên dịch và không còn cần phải được xác định rõ ràng trong mã nguồn của trình biên dịch. 1

Đó là một ví dụ về tính năng ngôn ngữ C được triển khai trong mã C. Bây giờ, lặp lại quy trình đó cho mọi tính năng ngôn ngữ duy nhất và bạn có trình biên dịch "tự lưu trữ": trình biên dịch C được viết bằng C.


1 Vòng xoắn cốt truyện được mô tả trong bài báo là vì trình biên dịch có thể được "dạy" các sự kiện như thế này, nên cũng có thể bị dạy sai để tạo ra các thực thi trojan theo cách khó phát hiện và hành động phá hoại như vậy có thể tồn tại trong tất cả các trình biên dịch được tạo ra bởi trình biên dịch bị nhiễm độc.


7
Mặc dù đây là một thông tin thú vị, tôi không nghĩ rằng nó trả lời câu hỏi. Các ví dụ của bạn cho rằng bạn đã có trình biên dịch bootstrapping, hoặc ngôn ngữ nào là trình biên dịch C được viết?
Arturo Torres Sánchez

9
@ ArturoTorresSánchez Giải thích khác nhau hoạt động tốt cho những người khác nhau. Tôi không định nhắc lại những gì đã được nói trong các câu trả lời khác. Thay vào đó, tôi thấy các câu trả lời khác nói ở mức cao hơn so với cách tôi muốn nghĩ. Cá nhân tôi thích một minh họa cụ thể về cách một tính năng duy nhất được thêm vào và để người đọc ngoại suy từ đó, thay vì một tổng quan nông cạn.
200_success

5
OK, tôi hiểu quan điểm của bạn. Đó chỉ là câu hỏi có nhiều hơn nữa, làm thế nào trình biên dịch có thể tự biên dịch nếu trình biên dịch biên dịch trình biên dịch không tồn tại và không có cách nào để thêm các tính năng mới vào trình biên dịch bootstrapping.
Arturo Torres Sánchez

17
Câu hỏi tự nó là mơ hồ và kết thúc mở. Dường như một số người giải thích nó có nghĩa là "làm thế nào trình biên dịch CoffeeScript có thể tự biên dịch?". Phản hồi flippant, như được đưa ra trong một bình luận, là "tại sao nó không thể tự biên dịch, giống như nó biên dịch bất kỳ mã nào?" Tôi giải thích nó có nghĩa là "làm thế nào một trình biên dịch tự lưu trữ có thể tồn tại?", Và đã đưa ra một minh họa về cách trình biên dịch có thể được dạy về một trong những tính năng ngôn ngữ của chính nó. Nó trả lời câu hỏi theo một cách khác, bằng cách cung cấp một minh họa cấp thấp về cách nó được thực hiện.
200_success

1
@ ArturoTorresSánchez: "[I] n ngôn ngữ nào là trình biên dịch C được viết?" Từ lâu, tôi đã duy trì trình biên dịch C gốc được ghi chú trong phụ lục K & R cũ (bản dành cho IBM 360.) Nhiều người biết rằng đầu tiên có BCPL, sau đó là B và C là phiên bản cải tiến của B. Thực tế, có rất nhiều các phần của trình biên dịch cũ vẫn được viết bằng B và chưa bao giờ được viết lại thành C. Các biến có dạng một chữ cái / chữ số, số học con trỏ không được coi là tự động được thu nhỏ, v.v. bootstrapping từ B đến C. Trình biên dịch "C" đầu tiên được viết bằng B.
Eliyahu Skoczylas

29

Bạn đã nhận được một câu trả lời rất tốt, tuy nhiên tôi muốn cung cấp cho bạn một quan điểm khác, hy vọng sẽ được khai sáng cho bạn. Trước tiên chúng ta hãy thiết lập hai sự thật mà cả hai chúng ta có thể đồng ý:

  1. Trình biên dịch CoffeeScript là một chương trình có thể biên dịch các chương trình được viết bằng CoffeeScript.
  2. Trình biên dịch CoffeeScript là một chương trình được viết bằng CoffeeScript.

Tôi chắc chắn rằng bạn có thể đồng ý rằng cả # 1 và # 2 đều đúng. Bây giờ, hãy nhìn vào hai tuyên bố. Bây giờ bạn có thấy trình biên dịch CoffeeScript hoàn toàn bình thường để có thể biên dịch trình biên dịch CoffeeScript không?

Trình biên dịch không quan tâm những gì nó biên dịch. Miễn là nó là một chương trình được viết bằng CoffeeScript, nó có thể biên dịch nó. Và trình biên dịch CoffeeScript chỉ là một chương trình như vậy. Trình biên dịch CoffeeScript không quan tâm rằng chính trình biên dịch CoffeeScript mà nó đang biên dịch. Tất cả những gì nó nhìn thấy là một số mã CoffeeScript. Giai đoạn = Stage.

Làm thế nào một trình biên dịch có thể tự biên dịch, hoặc câu lệnh này có ý nghĩa gì?

Vâng, đó chính xác là những gì câu nói đó có nghĩa, và tôi hy vọng bạn có thể thấy bây giờ câu nói đó đúng như thế nào.


2
Tôi không biết nhiều về kịch bản cà phê nhưng bạn có thể làm rõ điểm 2 bằng cách nói rằng nó được viết bằng kịch bản cà phê nhưng đã được biên dịch và sau đó là mã máy. Và dù sao đi nữa, bạn có thể vui lòng giải thích vấn đề gà và trứng sau đó. Nếu trình biên dịch được viết bằng ngôn ngữ mà trình biên dịch chưa được viết, thì làm thế nào trình biên dịch thậm chí có thể chạy hoặc được biên dịch?
barlop

6
Tuyên bố 2 của bạn không đầy đủ / không chính xác và rất sai lệch. vì như câu trả lời đầu tiên nói, câu đầu tiên không được viết bằng kịch bản cà phê .. Điều đó rất phù hợp với câu hỏi của anh ấy. Và như "Làm thế nào một trình biên dịch có thể tự biên dịch, hoặc câu lệnh này có ý nghĩa gì?" Bạn nói "Có" Tôi cho là như vậy (mặc dù tâm trí của tôi hơi nhỏ), tôi thấy nó được sử dụng để biên dịch các phiên bản trước đó của chính nó, chứ không phải là chính nó. Nhưng nó có được sử dụng để tự biên dịch không? Tôi cho rằng nó là vô nghĩa.
barlop

2
@barlop: Thay đổi câu lệnh 2 thành " Hôm nay , trình biên dịch CoffeeScript là một chương trình được viết bằng CoffeeScript." Điều đó có giúp bạn hiểu nó hơn không? Trình biên dịch là "chỉ" một chương trình dịch một đầu vào (mã) thành đầu ra (chương trình). Vì vậy, nếu bạn có trình biên dịch cho ngôn ngữ Foo, thì hãy viết mã nguồn cho trình biên dịch Foo bằng chính ngôn ngữ Foo và cung cấp nguồn đó cho trình biên dịch Foo đầu tiên của bạn, bạn sẽ nhận được trình biên dịch Foo thứ hai làm đầu ra. Điều này được thực hiện bởi rất nhiều ngôn ngữ (ví dụ, tất cả các trình biên dịch C mà tôi biết đều được viết bằng Từ C).
DarkDust

3
Trình biên dịch không thể tự biên dịch. Tệp đầu ra không giống với trình biên dịch tạo tệp đầu ra. Tôi hy vọng bạn có thể thấy bây giờ tuyên bố đó là sai.
pabram

3
@pabrams Tại sao bạn lại cho rằng? Đầu ra cũng có thể giống hệt với trình biên dịch được sử dụng để sản xuất nó. Chẳng hạn, nếu tôi biên dịch GCC 6.1 với GCC 6.1, tôi nhận được một phiên bản GCC 6.1 được biên dịch với GCC 6.1. Và sau đó nếu tôi sử dụng nó để biên dịch GCC 6.1, tôi cũng nhận được một phiên bản GCC 6.1 được biên dịch với GCC 6.1, giống hệt nhau (bỏ qua những thứ như dấu thời gian).
dùng253751

9

Làm thế nào một trình biên dịch có thể tự biên dịch, hoặc câu lệnh này có ý nghĩa gì?

Nó có nghĩa chính xác đó. Trước hết, một số điều cần xem xét. Có bốn đối tượng chúng ta cần xem xét:

  • Mã nguồn của bất kỳ chương trình CoffeScript tùy ý
  • Tập hợp (được tạo) của bất kỳ chương trình CoffeScript tùy ý
  • Mã nguồn của trình biên dịch CoffeScript
  • Tập hợp (được tạo) của trình biên dịch CoffeScript

Bây giờ, rõ ràng là bạn có thể sử dụng tập hợp được tạo - tệp thực thi - của trình biên dịch CoffeScript để biên dịch bất kỳ chương trình CoffeScript tùy ý nào và tạo tập hợp cho chương trình đó.

Bây giờ, trình biên dịch CoffeScript tự nó chỉ là một chương trình CoffeScript tùy ý, và do đó, nó có thể được biên dịch bởi trình biên dịch CoffeScript.

Dường như sự nhầm lẫn của bạn bắt nguồn từ thực tế là khi bạn tạo ngôn ngữ mới của riêng mình, bạn chưa trình biên dịch nhưng bạn có thể sử dụng để biên dịch trình biên dịch của mình. Điều này chắc chắn trông giống như một vấn đề trứng gà , phải không?

Giới thiệu quá trình gọi là bootstrapping .

  1. Bạn viết trình biên dịch bằng ngôn ngữ đã có sẵn (trong trường hợp của CoffeScript, trình biên dịch gốc được viết bằng Ruby) có thể biên dịch một tập hợp con của ngôn ngữ mới
  2. Bạn viết một trình biên dịch có thể biên dịch một tập hợp con của ngôn ngữ mới trong chính ngôn ngữ mới. Bạn chỉ có thể sử dụng các tính năng ngôn ngữ mà trình biên dịch từ bước trên có thể biên dịch.
  3. Bạn sử dụng trình biên dịch từ bước 1 để biên dịch trình biên dịch từ bước 2. Điều này cho bạn một hội đồng ban đầu được viết bằng một tập hợp con của ngôn ngữ mới và có thể biên dịch một tập hợp con của ngôn ngữ mới.

Bây giờ bạn cần thêm các tính năng mới. Giả sử bạn chỉ thực hiện while-loops, nhưng cũng muốn for-loops. Đây không phải là một vấn đề, vì bạn có thể viết lại bất kỳ for-loop theo cách mà nó là một while-loop. Điều này có nghĩa là bạn chỉ có thể sử dụng while-loop trong mã nguồn của trình biên dịch của mình, vì phần lắp ráp bạn có trong tay chỉ có thể biên dịch chúng. Nhưng bạn có thể tạo các hàm bên trong trình biên dịch có thể tạo và biên dịch for-loop với nó. Sau đó, bạn sử dụng hội đồng bạn đã có và biên dịch phiên bản trình biên dịch mới. Và bây giờ bạn có một tập hợp của một trình biên dịch cũng có thể phân tích cú pháp và biên dịch for-loops! Bây giờ bạn có thể quay lại tệp nguồn của trình biên dịch của mình và viết lại bất kỳ while-loops nào bạn không muốn vào for-loops.

Rửa sạch và lặp lại cho đến khi tất cả các tính năng ngôn ngữ mong muốn có thể được biên dịch bằng trình biên dịch.

whileforrõ ràng chỉ là ví dụ, nhưng điều này hoạt động cho bất kỳ tính năng ngôn ngữ mới nào bạn muốn. Và sau đó bạn đang ở trong tình huống CoffeScript hiện tại: Trình biên dịch tự biên dịch.

Có nhiều tài liệu ngoài kia. Phản ánh về niềm tin Tin tưởng là một tác phẩm kinh điển mà mọi người quan tâm đến chủ đề đó nên đọc ít nhất một lần.


5
(Câu "Trình biên dịch CoffeeScript được viết bằng CoffeeScript", là đúng, nhưng "Trình biên dịch có thể tự biên dịch" là sai.)
pabrams

4
Không, nó hoàn toàn đúng. Trình biên dịch có thể tự biên dịch. Nó chỉ không có ý nghĩa. Giả sử bạn có tệp thực thi có thể biên dịch Phiên bản X của ngôn ngữ. Bạn viết một trình biên dịch có thể biên dịch Phiên bản X + 1 và biên dịch nó với trình biên dịch bạn có (đó là phiên bản X). Bạn kết thúc với một tệp thực thi có thể biên dịch phiên bản X + 1 của ngôn ngữ. Bây giờ bạn có thể đi và sử dụng tệp thực thi mới đó để biên dịch lại trình biên dịch. Nhưng đến cuối cùng thì sao? Bạn đã khả năng thực thi mà làm những gì bạn muốn. Trình biên dịch có thể biên dịch bất kỳ chương trình hợp lệ nào , vì vậy nó hoàn toàn có thể tự biên dịch!
Polygnome

1
Thật vậy, không có gì lạ khi xây dựng khá nhiều lần, iirc freepascal hiện đại xây dựng trình biên dịch tổng cộng 5 lần.
cắm vào

1
@pabrams Viết "Không chạm" và "Đối tượng nóng. Không chạm" không tạo ra sự khác biệt cho thông điệp dự định của cụm từ. Miễn là đối tượng dự định của tin nhắn (Lập trình viên) hiểu thông điệp dự định của cụm từ (Bản dựng của trình biên dịch có thể biên dịch nguồn của nó) bất kể nó được viết như thế nào, cuộc thảo luận này là vô nghĩa. Hiện tại, lập luận của bạn không hợp lệ. Trừ khi bạn có thể chỉ ra rằng đối tượng dự định của tin nhắn là người không lập trình, thì, và chỉ sau đó, bạn mới đúng.
DarkDestry

2
@pabrams 'Tiếng Anh tốt' là tiếng Anh truyền đạt ý tưởng rõ ràng đến đối tượng dự định và theo cách mà người viết hoặc người nói dự định. Nếu đối tượng dự định là lập trình viên, và lập trình viên hiểu nó, tiếng Anh tốt của nó. Nói "Ánh sáng tồn tại như cả hạt và sóng" về cơ bản tương đương với "Ánh sáng tồn tại dưới dạng cả photon và sóng điện từ". Đối với một nhà vật lý, họ có nghĩa đen là điều tương tự. Điều đó có nghĩa là chúng ta nên luôn luôn sử dụng thời gian dài hơn và rõ ràng hơn? Không! Bởi vì nó làm phức tạp việc đọc khi ý nghĩa đã rõ ràng cho đối tượng dự định.
DarkDestry

7

Một sự làm rõ nhỏ nhưng quan trọng

Ở đây thuật ngữ trình biên dịch nhấn mạnh đến thực tế là có hai tệp liên quan. Một là một tệp thực thi, lấy các tệp đầu vào được viết bằng CoffeScript và tạo ra như tệp đầu ra của nó một tệp thực thi khác, tệp đối tượng có thể liên kết hoặc thư viện dùng chung. Cái còn lại là một tệp nguồn CoffeeScript chỉ xảy ra để mô tả quy trình biên dịch CoffeeScript.

Bạn áp dụng tệp thứ nhất cho tệp thứ hai, tạo tệp thứ ba có khả năng thực hiện cùng một hành động biên dịch như tệp thứ nhất (có thể nhiều hơn, nếu tệp thứ hai xác định các tính năng không được triển khai trước) và do đó có thể thay thế tệp đầu tiên nếu bạn mong muốn như vậy.


4
  1. Trình biên dịch CoffeeScript được viết lần đầu tiên bằng Ruby.
  2. Trình biên dịch CoffeeScript sau đó được viết lại bằng CoffeeScript.

Do phiên bản Ruby của trình biên dịch CoffeeScript đã tồn tại, nên nó được sử dụng để tạo phiên bản CoffeeScript của trình biên dịch CoffeeScript.

nhập mô tả hình ảnh ở đây Điều này được biết đến như là một trình biên dịch tự lưu trữ .

Nó cực kỳ phổ biến và thường xuất phát từ mong muốn của tác giả sử dụng ngôn ngữ của chính họ để duy trì sự phát triển của ngôn ngữ đó.


3

Đây không phải là vấn đề của trình biên dịch ở đây, mà là vấn đề về tính biểu cảm của ngôn ngữ, vì trình biên dịch chỉ là một chương trình được viết bằng một số ngôn ngữ.

Khi chúng tôi nói rằng "một ngôn ngữ được viết / triển khai", chúng tôi thực sự có nghĩa là trình biên dịch hoặc trình thông dịch cho ngôn ngữ đó được triển khai. Có các ngôn ngữ lập trình trong đó bạn có thể viết các chương trình thực hiện ngôn ngữ (là trình biên dịch / trình thông dịch cho cùng một ngôn ngữ). Những ngôn ngữ này được gọi là ngôn ngữ phổ quát .

Để có thể hiểu điều này, hãy nghĩ về một máy tiện kim loại. Nó là một công cụ được sử dụng để định hình kim loại. Có thể, chỉ sử dụng công cụ đó, để tạo một công cụ khác, giống hệt nhau, bằng cách tạo các phần của nó. Do đó, công cụ đó là một cỗ máy vạn năng. Tất nhiên, cái đầu tiên được tạo ra bằng các phương tiện khác (các công cụ khác) và có lẽ có chất lượng thấp hơn. Nhưng cái đầu tiên được sử dụng để chế tạo những cái mới với độ chính xác cao hơn.

Một máy in 3D gần như là một cỗ máy vạn năng. Bạn có thể in toàn bộ máy in 3D bằng máy in 3D (bạn không thể tạo mẹo làm nóng chảy nhựa).


Tôi thích sự tương tự máy tiện. Tuy nhiên, không giống như sự tương tự máy tiện, các khiếm khuyết trong lần lặp trình biên dịch đầu tiên được truyền cùng với tất cả các trình biên dịch tiếp theo. Ví dụ, một câu trả lời ở trên đề cập đến việc thêm một tính năng vòng lặp trong đó trình biên dịch gốc chỉ sử dụng các vòng lặp. Đầu ra hiểu các vòng lặp for, nhưng việc thực hiện là với các vòng lặp while. Nếu việc thực hiện vòng lặp while ban đầu là thiếu sót hoặc không hiệu quả, thì nó sẽ luôn như vậy!

@ Vật lý - Tính toán đơn giản là sai. Trong trường hợp không có lỗi khiếm khuyết, thường không lan truyền khi biên dịch trình biên dịch.
cắm vào

Bản dịch lắp ráp chắc chắn được chuyển từ lần lặp sang lần lặp cho đến khi bản dịch lắp ráp được cố định. Các tính năng mới xây dựng các tính năng cũ không thay đổi việc triển khai cơ bản. Hãy suy nghĩ về nó trong một thời gian.

@plugwash Xem "Phản ánh về niềm tin tin cậy" của Ken Thompson - ece.cmu.edu/~ganger/712.fall02/ con / p761

3

Chứng minh bằng cảm ứng

Bước quy nạp

Phiên bản thứ n + 1 của trình biên dịch được viết bằng X.

Do đó, nó có thể được biên dịch bởi phiên bản thứ n của trình biên dịch (cũng được viết bằng X).

Trường hợp cơ sở

Nhưng phiên bản đầu tiên của trình biên dịch được viết bằng X phải được biên dịch bởi trình biên dịch cho X được viết bằng ngôn ngữ khác X. Bước này được gọi là bootstrapping trình biên dịch.


1
Trình biên dịch trình biên dịch đầu tiên cho ngôn ngữ X có thể dễ dàng được viết bằng X. Làm thế nào có thể là trình biên dịch đầu tiên này có thể được diễn giải . (Bởi một thông dịch viên X được viết bằng ngôn ngữ khác X).
Kaz

0

Trình biên dịch lấy một đặc tả cấp cao và biến nó thành một triển khai cấp thấp, chẳng hạn như có thể được thực thi trên phần cứng. Do đó, không có mối quan hệ giữa định dạng của đặc tả và thực thi thực tế bên cạnh ngữ nghĩa của ngôn ngữ được nhắm mục tiêu.

Trình biên dịch chéo chuyển từ hệ thống này sang hệ thống khác, trình biên dịch ngôn ngữ chéo biên dịch một đặc tả ngôn ngữ thành một đặc tả ngôn ngữ khác.

Về cơ bản biên dịch là một bản dịch đơn thuần, và cấp độ thường là cấp độ ngôn ngữ cao hơn đến cấp độ ngôn ngữ thấp hơn, nhưng có nhiều biến thể.

Tất nhiên, trình biên dịch bootstrapping khó hiểu nhất vì chúng biên dịch ngôn ngữ mà chúng được viết. Đừng quên bước đầu tiên trong bootstrapping đòi hỏi ít nhất một phiên bản hiện có tối thiểu có thể thực thi được. Nhiều trình biên dịch bootstrapping hoạt động trên các tính năng tối thiểu của ngôn ngữ lập trình trước tiên và thêm các tính năng ngôn ngữ phức tạp bổ sung trong tương lai miễn là tính năng mới có thể được thể hiện bằng các tính năng trước đó. Nếu đó không phải là trường hợp, nó sẽ yêu cầu phải có một phần của "trình biên dịch" được phát triển bằng ngôn ngữ khác.

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.