Biên dịch so với các ngôn ngữ được giải thích


284

Tôi đang cố gắng để hiểu rõ hơn về sự khác biệt. Tôi đã tìm thấy rất nhiều lời giải thích trực tuyến, nhưng chúng có xu hướng hướng tới những khác biệt trừu tượng hơn là những ý nghĩa thực tế.

Hầu hết các kinh nghiệm lập trình của tôi là với CPython (động, diễn giải) và Java (tĩnh, được biên dịch). Tuy nhiên, tôi hiểu rằng có các loại ngôn ngữ được biên dịch và biên dịch khác. Ngoài thực tế là các tệp thực thi có thể được phân phối từ các chương trình được viết bằng ngôn ngữ được biên dịch, có bất kỳ ưu điểm / nhược điểm nào đối với từng loại không? Thông thường, tôi nghe mọi người tranh luận rằng các ngôn ngữ được giải thích có thể được sử dụng một cách tương tác, nhưng tôi tin rằng các ngôn ngữ được biên dịch cũng có thể có triển khai tương tác, đúng không?


32
Bạn đã chọn chính xác các ngôn ngữ tồi tệ nhất để so sánh này. Cả hai đều được biên dịch. Sự khác biệt thực sự duy nhất giữa chúng là JITer và thậm chí Python có một phần (psyco).
Ignacio Vazquez-Abrams

1
Một ví dụ điển hình về ngôn ngữ được biên dịch tương tác là Clojure - mọi thứ được biên dịch đầy đủ (đầu tiên là JVM sau đó đến mã gốc thông qua JIT). Tuy nhiên, rất nhiều quá trình biên dịch lại diễn ra linh hoạt và việc phát triển thường được thực hiện trong trình vỏ REPL tương tác nơi bạn có thể đánh giá bất kỳ chức năng nào bạn muốn trong môi trường chạy.
mikera

ML chuẩn là một ngôn ngữ được biên dịch tương tác khác; trình biên dịch tích hợp cũng phát hành mã máy thực sự.
Donal Fellows


Câu trả lời:


459

Một ngôn ngữ được biên dịch là một trong đó chương trình, một khi được biên dịch, được thể hiện trong các hướng dẫn của máy đích. Ví dụ: thao tác "+" bổ sung trong mã nguồn của bạn có thể được dịch trực tiếp sang hướng dẫn "THÊM" trong mã máy.

Ngôn ngữ được dịch là ngôn ngữ mà các lệnh không được thực hiện trực tiếp bởi máy đích, mà thay vào đó, được đọc và thực thi bởi một số chương trình khác (thường được viết bằng ngôn ngữ của máy gốc). Ví dụ, thao tác "+" tương tự sẽ được trình thông dịch nhận ra khi chạy, sau đó sẽ gọi hàm "add (a, b)" của chính nó với các đối số thích hợp, sau đó sẽ thực thi lệnh "ADD" của mã máy .

Bạn có thể làm bất cứ điều gì bạn có thể làm bằng ngôn ngữ được dịch bằng ngôn ngữ được biên dịch và ngược lại - cả hai đều hoàn thành Turing. Tuy nhiên cả hai đều có những ưu điểm và nhược điểm để thực hiện và sử dụng.

Tôi sẽ hoàn toàn khái quát hóa (những người theo chủ nghĩa thuần túy tha thứ cho tôi!), Nhưng, đại khái, đây là những lợi thế của các ngôn ngữ được biên dịch:

  • Hiệu suất nhanh hơn bằng cách sử dụng trực tiếp mã gốc của máy đích
  • Cơ hội để áp dụng tối ưu hóa khá mạnh mẽ trong giai đoạn biên dịch

Và đây là những lợi thế của ngôn ngữ diễn giải:

  • Dễ thực hiện hơn (viết trình biên dịch tốt là rất khó !!)
  • Không cần chạy giai đoạn biên dịch: có thể thực thi mã trực tiếp "nhanh chóng"
  • Có thể thuận tiện hơn cho các ngôn ngữ động

Lưu ý rằng các kỹ thuật hiện đại như biên dịch mã byte thêm một số phức tạp thêm - điều xảy ra ở đây là trình biên dịch nhắm vào một "máy ảo" không giống với phần cứng bên dưới. Các hướng dẫn máy ảo này sau đó có thể được biên dịch lại ở giai đoạn sau để lấy mã gốc (ví dụ như được thực hiện bởi trình biên dịch JIT Java JVM).


1
Không phải tất cả các ngôn ngữ biên dịch cần một giai đoạn biên dịch chậm. Các triển khai Lisp phổ biến nghiêm trọng là các trình biên dịch và chúng thường không bận tâm với một thông dịch viên, chỉ thích biên dịch thực sự nhanh chóng. Mặt khác, Java không cần một bước biên dịch và nó thường hiển thị.
David Thornley

2
@Kareem: trình biên dịch JIT chỉ thực hiện 1) và 2) một lần - sau đó tất cả đều là mã gốc. Trình thông dịch cần thực hiện cả 1) và 2) mỗi khi mã được gọi (có thể nhiều, nhiều lần ...). Vì vậy, theo thời gian, trình biên dịch JIT chiến thắng với một biên độ dài.
mikera

3
Có mã byte được dịch sang mã máy tại một số điểm trong quá trình thực thi chương trình tổng thể (trái ngược với trước khi thực hiện chương trình, như trường hợp với trình biên dịch truyền thống). Nhưng một đoạn mã nhất định có thể được thực thi 10 triệu + lần trong khi thực hiện chương trình tổng thể. Nó (có lẽ) chỉ được biên dịch một lần từ mã byte sang mã máy. Do đó, tổng thời gian chạy của JIT là nhỏ và có thể bỏ qua cho các chương trình chạy dài. Sau khi trình biên dịch JIT hoàn thành công việc của nó, bạn sẽ thực sự chạy mã máy thuần túy.
mikera

2
Đây thực sự là một sự phân đôi giả. Không có gì nội tại đối với một ngôn ngữ làm cho nó biên dịch chúng tôi giải thích. Nó không có gì hơn một quan niệm sai lầm được tổ chức rộng rãi. Nhiều ngôn ngữ có cả hai triển khai và tất cả các ngôn ngữ có thể có một trong hai.
mmachenry

2
@mmachenry nó không phải là sự phân đôi giả. "Ngôn ngữ lập trình" bao gồm cả thiết kế và triển khai. Mặc dù trong ý nghĩa lý thuyết, một định nghĩa ngôn ngữ nhất định có thể được biên dịch và giải thích, trong thực tế thế giới thực có sự khác biệt đáng kể trong việc thực hiện. Chẳng có ai giải quyết được cách biên dịch hiệu quả các cấu trúc ngôn ngữ nhất định, chẳng hạn - đó là một vấn đề nghiên cứu mở.
mikera

99

Một ngôn ngữ tự nó không được biên dịch cũng không được giải thích, chỉ có một triển khai cụ thể của ngôn ngữ. Java là một ví dụ hoàn hảo. Có một nền tảng dựa trên mã byte (JVM), trình biên dịch gốc (gcj) và một trình thông dịch cho một siêu bộ của Java (bsh). Vậy bây giờ Java là gì? Bytecode được biên dịch, biên dịch gốc hoặc giải thích?

Các ngôn ngữ khác, được biên soạn cũng như diễn giải, là Scala, Haskell hoặc Ocaml. Mỗi ngôn ngữ này có một trình thông dịch tương tác, cũng như trình biên dịch mã byte hoặc mã máy riêng.

Vì vậy, nói chung việc phân loại các ngôn ngữ theo "biên dịch" và "diễn giải" không có nhiều ý nghĩa.


3
Tôi đồng ý. Hoặc giả sử: Có trình biên dịch gốc (tạo mã máy cho CPU để ăn) và trình biên dịch không phải là trình biên dịch gốc (tạo công cụ mã thông báo, tức là mã trung gian, một số trình biên dịch chỉ kịp thời biên dịch thành mã máy trước đó ( hoặc trong thời gian chạy ONCE) và có các trình biên dịch "thực" không bao giờ tạo mã máy và không bao giờ để CPU chạy mã. Sau này là thông dịch viên. Ngày nay, các trình biên dịch riêng sản xuất trực tiếp mã máy (CPU) tại thời gian biên dịch ngày càng trở nên hiếm hơn. Delphi / Codegear là một trong những người sống sót tốt nhất.
TheBlastOne

57

Bắt đầu suy nghĩ về một: vụ nổ từ quá khứ

Ngày xửa ngày xưa, từ lâu, đã sống ở vùng đất của những người phiên dịch và biên dịch máy tính. Tất cả các loại ồn ào xảy ra sau các công đức của nhau. Ý kiến ​​chung tại thời điểm đó là một cái gì đó dọc theo dòng:

  • Thông dịch viên: Phát triển nhanh (chỉnh sửa và chạy). Chậm thực thi vì mỗi câu lệnh phải được diễn giải thành mã máy mỗi lần nó được thực thi (nghĩ về điều này có nghĩa là gì đối với một vòng lặp được thực thi hàng ngàn lần).
  • Trình biên dịch: Chậm phát triển (chỉnh sửa, biên dịch, liên kết và chạy. Các bước biên dịch / liên kết có thể mất thời gian nghiêm trọng). Nhanh chóng thực hiện. Toàn bộ chương trình đã có trong mã máy riêng.

Một hoặc hai thứ tự chênh lệch cường độ trong hiệu năng thời gian chạy đã tồn tại giữa một chương trình được giải thích và một chương trình được biên dịch. Ví dụ, các điểm phân biệt khác, tính biến đổi thời gian chạy của mã cũng được quan tâm nhưng sự khác biệt chính xoay quanh các vấn đề về hiệu năng thời gian chạy.

Ngày nay, phong cảnh đã phát triển đến mức độ khác biệt được biên dịch / giải thích là không liên quan nhiều. Nhiều ngôn ngữ được biên dịch gọi theo các dịch vụ thời gian chạy không hoàn toàn dựa trên mã máy. Ngoài ra, hầu hết các ngôn ngữ được giải thích được "biên dịch" thành mã byte trước khi thực hiện. Trình thông dịch mã byte có thể rất hiệu quả và cạnh tranh với một số mã trình biên dịch được tạo từ quan điểm tốc độ thực thi.

Sự khác biệt kinh điển là trình biên dịch tạo mã máy gốc, trình thông dịch đọc mã nguồn và mã máy được tạo nhanh chóng bằng cách sử dụng một số hệ thống thời gian chạy. Ngày nay, có rất ít trình thông dịch cổ điển còn lại - hầu hết tất cả chúng đều được biên dịch thành mã byte (hoặc một số trạng thái được biên dịch bán khác) sau đó chạy trên một "máy" ảo.


1
Nice - tóm tắt tuyệt vời trong đoạn cuối - cảm ơn!
ckib16

26

Các trường hợp cực đoan và đơn giản:

  • Một trình biên dịch sẽ tạo ra một tệp thực thi nhị phân ở định dạng thực thi riêng của máy đích. Tệp nhị phân này chứa tất cả các tài nguyên cần thiết ngoại trừ các thư viện hệ thống; Nó đã sẵn sàng để chạy mà không cần chuẩn bị và xử lý nữa và nó chạy như chớp vì mã là mã gốc cho CPU trên máy đích.

  • Một thông dịch viên sẽ đưa ra cho người dùng một dấu nhắc trong một vòng lặp để anh ta có thể nhập các câu lệnh hoặc mã, và khi nhấn RUNhoặc tương đương, trình thông dịch sẽ kiểm tra, quét, phân tích và thực thi từng dòng cho đến khi chương trình chạy đến điểm dừng hoặc lỗi . Bởi vì mỗi dòng được xử lý riêng và trình thông dịch không "học" bất cứ điều gì từ việc nhìn thấy dòng trước đó, nên nỗ lực chuyển đổi ngôn ngữ có thể đọc được của con người sang hướng dẫn máy mỗi lần phát sinh, vì vậy nó chậm. Về mặt sáng sủa, người dùng có thể kiểm tra và tương tác với chương trình của mình bằng mọi cách: Thay đổi biến, thay đổi mã, chạy trong chế độ theo dõi hoặc gỡ lỗi ... bất cứ điều gì.

Với những điều đó, hãy để tôi giải thích rằng cuộc sống không còn đơn giản nữa. Ví dụ,

  • Nhiều thông dịch viên sẽ biên dịch trước mã mà họ đưa ra để bước dịch thuật không phải lặp đi lặp lại nhiều lần.
  • Một số trình biên dịch biên dịch không theo hướng dẫn máy cụ thể của CPU mà là mã byte, một loại mã máy nhân tạo cho máy giả tưởng. Điều này làm cho chương trình được biên dịch trở nên linh hoạt hơn một chút, nhưng yêu cầu trình thông dịch mã byte trên mọi hệ thống đích.
  • Các trình thông dịch mã byte (tôi đang xem Java ở đây) gần đây có xu hướng biên dịch lại mã byte mà họ nhận được cho CPU của phần đích ngay trước khi thực hiện (được gọi là JIT). Để tiết kiệm thời gian, điều này thường chỉ được thực hiện đối với mã chạy thường xuyên (điểm nóng).
  • Một số hệ thống trông và hoạt động như trình thông dịch (chẳng hạn Clojure) biên dịch bất kỳ mã nào họ nhận được, ngay lập tức, nhưng cho phép truy cập tương tác vào môi trường của chương trình. Về cơ bản, đó là sự tiện lợi của trình thông dịch với tốc độ biên dịch nhị phân.
  • Một số trình biên dịch không thực sự biên dịch, chúng chỉ cần mã hóa trước và nén mã. Tôi đã nghe một lúc trước đó là cách Perl hoạt động. Vì vậy, đôi khi trình biên dịch chỉ làm một chút công việc và hầu hết vẫn là giải thích.

Cuối cùng, những ngày này, phiên dịch so với biên dịch là một sự đánh đổi, với thời gian (một lần) biên dịch thường được thưởng bằng hiệu năng thời gian chạy tốt hơn, nhưng môi trường diễn giải mang lại nhiều cơ hội hơn cho tương tác. Biên dịch so với phiên dịch chủ yếu là vấn đề làm thế nào công việc "hiểu" chương trình được phân chia giữa các quy trình khác nhau và dòng này hơi mờ trong những ngày này khi các ngôn ngữ và sản phẩm cố gắng cung cấp tốt nhất cho cả hai thế giới.


23

Từ http://www.quora.com/What-is-the-difference-b between-compiled-and-interpratted-program-ngôn ngữ

Không có gì khác biệt, bởi vì ngôn ngữ lập trình được biên soạn bởi Cameron và ngôn ngữ lập trình được diễn giải là những khái niệm có ý nghĩa. Bất kỳ ngôn ngữ lập trình, và tôi thực sự có nghĩa là bất kỳ, có thể được giải thích hoặc biên dịch. Do đó, giải thích và biên dịch là các kỹ thuật triển khai, không phải là thuộc tính của ngôn ngữ.

Phiên dịch là một kỹ thuật trong đó một chương trình khác, thông dịch viên, thực hiện các hoạt động thay mặt cho chương trình được diễn giải để chạy nó. Nếu bạn có thể tưởng tượng việc đọc một chương trình và thực hiện những gì nó nói để làm từng bước một, hãy nói trên một mảnh giấy nháp, đó chỉ là những gì một thông dịch viên làm. Một lý do phổ biến để giải thích một chương trình là thông dịch viên tương đối dễ viết. Một lý do khác là một thông dịch viên có thể theo dõi những gì một chương trình cố gắng làm khi nó chạy, để thực thi một chính sách, nói, để bảo mật.

Biên dịch là một kỹ thuật trong đó một chương trình được viết bằng một ngôn ngữ (ngôn ngữ nguồn của Hồi giáo) được dịch sang một chương trình bằng ngôn ngữ khác (ngôn ngữ đối tượng của người Hồi giáo), hy vọng có nghĩa tương tự như chương trình gốc. Trong khi thực hiện dịch, thông thường trình biên dịch cũng cố gắng chuyển đổi chương trình theo cách sẽ làm cho chương trình đối tượng nhanh hơn (mà không thay đổi ý nghĩa của nó!). Một lý do phổ biến để biên dịch chương trình là có một số cách tốt để chạy các chương trình bằng ngôn ngữ đối tượng một cách nhanh chóng và không cần phải giải thích ngôn ngữ nguồn trên đường đi.

Bạn có thể đã đoán, dựa trên các định nghĩa trên, rằng hai kỹ thuật thực hiện này không loại trừ lẫn nhau, và thậm chí có thể bổ sung cho nhau. Theo truyền thống, ngôn ngữ đối tượng của trình biên dịch là mã máy hoặc một cái gì đó tương tự, dùng để chỉ bất kỳ số ngôn ngữ lập trình nào được hiểu bởi các CPU máy tính cụ thể. Mã máy sau đó sẽ chạy trên hệ thống kim loại (mặc dù người ta có thể thấy, nếu nhìn đủ kỹ, thì kim loại kim loại hoạt động rất giống như một trình thông dịch). Tuy nhiên, ngày nay, việc sử dụng một trình biên dịch để tạo mã đối tượng có nghĩa là được hiểu là ví dụ, đây là cách mà Java đã sử dụng (và đôi khi vẫn hoạt động). Có các trình biên dịch dịch các ngôn ngữ khác sang JavaScript, thường được chạy trong trình duyệt web, có thể diễn giải JavaScript, hoặc biên dịch nó một máy ảo hoặc mã gốc. Chúng tôi cũng có các thông dịch viên cho mã máy, có thể được sử dụng để mô phỏng một loại phần cứng trên một loại phần cứng khác. Hoặc, người ta có thể sử dụng trình biên dịch để tạo mã đối tượng, sau đó là mã nguồn cho trình biên dịch khác, thậm chí có thể biên dịch mã trong bộ nhớ ngay khi nó chạy. . . bạn có được ý tưởng Có nhiều cách để kết hợp các khái niệm này.


Bạn có thể sửa câu này không: "Có các trình biên dịch dịch các ngôn ngữ khác sang JavaScript, thường được chạy trong trình duyệt web, có thể diễn giải JavaScript hoặc biên dịch nó thành máy ảo hoặc mã gốc."
Koray Tugay

Đóng đinh nó Một lỗi phổ biến khác là quy sự hữu ích của ngôn ngữ đối với các API hiện có.
Little Endian

10

Ưu điểm lớn nhất của mã nguồn được giải thích so với mã nguồn được biên dịch là PORTABILITY .

Nếu mã nguồn của bạn được biên dịch, bạn cần biên dịch một tệp thực thi khác nhau cho từng loại bộ xử lý và / hoặc nền tảng mà bạn muốn chương trình của mình chạy (ví dụ: cho Windows x86, một cho Windows x64, một cho Linux x64, v.v. trên). Hơn nữa, trừ khi mã của bạn hoàn toàn tuân thủ tiêu chuẩn và không sử dụng bất kỳ chức năng / thư viện dành riêng cho nền tảng nào, bạn thực sự sẽ cần phải viết và duy trì nhiều cơ sở mã!

Nếu mã nguồn của bạn được diễn giải, bạn chỉ cần viết nó một lần và nó có thể được thông dịch và thực thi bởi một trình thông dịch thích hợp trên bất kỳ nền tảng nào! Nó là hàng xách tay ! Lưu ý rằng bản thân trình thông dịch là một chương trình thực thi được viết và biên dịch cho một nền tảng cụ thể.

Một lợi thế của mã được biên dịch là nó ẩn mã nguồn từ người dùng cuối (có thể là tài sản trí tuệ ) vì thay vì triển khai mã nguồn gốc có thể đọc được của con người, bạn triển khai một tệp thực thi nhị phân khó hiểu.


1
về mặt này, java không thể được coi là "ngôn ngữ được biên dịch", nhưng giai đoạn biên dịch này mang lại lợi thế cho việc biên dịch (kiểm tra kiểu, phát hiện lỗi sớm, v.v.) và tạo mã byte có thể chạy trên mọi HĐH, với Java máy ảo cung cấp.
Rogelio Triviño

7

Trình biên dịch và trình thông dịch thực hiện cùng một công việc: dịch ngôn ngữ lập trình sang ngôn ngữ pgoramming khác, thường gần với phần cứng hơn, thường là mã máy thực thi trực tiếp.

Theo truyền thống, "được biên dịch" có nghĩa là bản dịch này xảy ra trong một lần, được thực hiện bởi nhà phát triển và kết quả thực thi được phân phối cho người dùng. Ví dụ thuần túy: C ++. Quá trình biên dịch thường mất khá nhiều thời gian và cố gắng thực hiện nhiều phương pháp tối ưu hóa đắt tiền để kết quả thực thi chạy nhanh hơn. Người dùng cuối không có công cụ và kiến ​​thức để tự biên dịch nội dung và trình thực thi thường phải chạy trên nhiều loại phần cứng, do đó bạn không thể thực hiện nhiều tối ưu hóa cụ thể cho phần cứng. Trong quá trình phát triển, bước biên dịch riêng biệt có nghĩa là một chu kỳ phản hồi dài hơn.

Theo truyền thống, "diễn giải" có nghĩa là bản dịch xảy ra "nhanh chóng", khi người dùng muốn chạy chương trình. Ví dụ thuần túy: vanilla PHP. Một thông dịch viên ngây thơ phải phân tích và dịch từng đoạn mã mỗi khi nó chạy, điều này làm cho nó rất chậm. Nó không thể thực hiện tối ưu hóa phức tạp, tốn kém vì chúng mất nhiều thời gian hơn thời gian thực hiện. Nhưng nó hoàn toàn có thể sử dụng các khả năng của phần cứng mà nó chạy. Việc thiếu một bước biên dịch tách biệt làm giảm thời gian phản hồi trong quá trình phát triển.

Nhưng ngày nay "biên dịch so với giải thích" không phải là vấn đề đen trắng, có những sắc thái ở giữa. Ngây thơ, thông dịch viên đơn giản là tuyệt chủng khá nhiều. Nhiều ngôn ngữ sử dụng quy trình hai bước trong đó mã cấp cao được dịch sang mã byte độc ​​lập với nền tảng (nhanh hơn nhiều để diễn giải). Sau đó, bạn có "trình biên dịch đúng lúc", biên dịch mã nhiều nhất một lần cho mỗi lần chạy chương trình, đôi khi kết quả bộ đệm và thậm chí quyết định thông minh để giải thích mã chạy hiếm khi và tối ưu hóa mạnh mẽ cho mã chạy nhiều. Trong quá trình phát triển, trình gỡ lỗi có khả năng chuyển đổi mã bên trong một chương trình đang chạy ngay cả đối với các ngôn ngữ được biên dịch theo truyền thống.


1
Tuy nhiên, mô hình biên dịch của C ++ được kế thừa từ C và được thiết kế mà không xem xét các tính năng như mẫu. Sự lúng túng này góp phần vào thời gian biên dịch dài của C ++ nhiều hơn bất kỳ yếu tố nào khác - và khiến nó trở thành một ví dụ tồi.

4

Đầu tiên, làm rõ, Java không được biên dịch tĩnh hoàn toàn và được liên kết theo cách C ++. Nó được biên dịch thành mã byte, sau đó được JVM giải thích. JVM có thể thực hiện và biên dịch đúng lúc sang ngôn ngữ máy gốc, nhưng không phải làm điều đó.

Thêm vào điểm: Tôi nghĩ rằng tương tác là sự khác biệt thực tế chính. Vì mọi thứ đều được diễn giải, bạn có thể lấy một đoạn trích mã nhỏ, phân tích cú pháp và chạy nó theo trạng thái hiện tại của môi trường. Do đó, nếu bạn đã thực thi mã đã khởi tạo một biến, bạn sẽ có quyền truy cập vào biến đó, v.v. Nó thực sự cho vay theo cách của nó cho những thứ như kiểu chức năng.

Phiên dịch, tuy nhiên, chi phí rất nhiều, đặc biệt là khi bạn có một hệ thống lớn với nhiều tài liệu tham khảo và bối cảnh. Theo định nghĩa, thật lãng phí vì mã giống hệt nhau có thể phải được giải thích và tối ưu hóa hai lần (mặc dù hầu hết các thời gian chạy đều có một số bộ nhớ đệm và tối ưu hóa cho điều đó). Tuy nhiên, bạn phải trả chi phí thời gian chạy và thường cần một môi trường thời gian chạy. Bạn cũng ít có khả năng nhìn thấy tối ưu hóa liên vùng phức tạp vì hiện tại hiệu suất của chúng không đủ tương tác.

Do đó, đối với các hệ thống lớn sẽ không thay đổi nhiều và đối với một số ngôn ngữ nhất định, việc biên dịch trước và sắp xếp lại mọi thứ sẽ hợp lý hơn, thực hiện tất cả các tối ưu hóa mà bạn có thể làm. Điều này kết thúc với một thời gian chạy rất nạc đã được tối ưu hóa cho máy đích.

Đối với việc tạo các tệp thực thi, điều đó ít liên quan đến nó, IMHO. Bạn thường có thể tạo một tệp thực thi từ một ngôn ngữ được biên dịch. Nhưng bạn cũng có thể tạo một tệp thực thi từ một ngôn ngữ được thông dịch, ngoại trừ việc trình thông dịch và thời gian chạy đã được đóng gói trong phần ngoại lệ và ẩn khỏi bạn. Điều này có nghĩa là bạn thường vẫn phải trả chi phí thời gian chạy (mặc dù tôi chắc chắn rằng đối với một số ngôn ngữ, có nhiều cách để dịch mọi thứ sang một cây có thể thực thi được).

Tôi không đồng ý rằng tất cả các ngôn ngữ có thể được thực hiện tương tác. Một số ngôn ngữ nhất định, như C, gắn liền với máy và toàn bộ cấu trúc liên kết đến mức tôi không chắc bạn có thể xây dựng một phiên bản tương tác đầy đủ ý nghĩa


C không thực sự gắn liền với một "cỗ máy". Cú pháp và ngữ nghĩa của C khá đơn giản. Không nên đặc biệt khó thực hiện trình thông dịch C, chỉ tốn rất nhiều thời gian (vì thư viện chuẩn cũng phải được triển khai). Và btw, Java có thể được biên dịch thành mã máy gốc (sử dụng gcj).
lunaryorn

@lunaryorn: Tôi không đồng ý về GCJ. GCJ chỉ cung cấp cho bạn một môi trường dựa trên thực thi. "Các ứng dụng được biên dịch được liên kết với thời gian chạy GCJ, libgcj, cung cấp các thư viện lớp lõi, trình thu gom rác và trình thông dịch mã byte"
Uri

2
GCJ không tạo mã máy riêng, và không chỉ là một môi trường thực thi với trình thông dịch nhúng và mã byte. libgcj cung cấp một trình thông dịch mã byte để hỗ trợ các cuộc gọi từ mã gốc vào mã byte Java, không phải để giải thích chương trình được biên dịch. Nếu libgcj không cung cấp trình thông dịch mã byte, thì GCJ sẽ không tuân thủ thông số Java.
lunaryorn

@lunaryorn: À. Ok, tôi đánh giá cao sự làm rõ và đứng chính xác. Chúng tôi chủ yếu sử dụng Java trong môi trường windows nên tôi đã không thử gcj trong nhiều năm.
Uri


2

Thật khó để đưa ra một câu trả lời thực tế bởi vì sự khác biệt là về chính định nghĩa ngôn ngữ. Có thể xây dựng trình thông dịch cho mọi ngôn ngữ được biên dịch, nhưng không thể xây dựng trình biên dịch cho mọi ngôn ngữ được dịch. Đó là rất nhiều về định nghĩa chính thức của một ngôn ngữ. Vì vậy, tin học lý thuyết thứ noboby thích ở trường đại học.


1
Chắc chắn bạn có thể xây dựng một trình biên dịch cho một ngôn ngữ được dịch, nhưng mã máy đã biên dịch tự nó là một bản sao của thời gian chạy.
Aiden Bell

2

Sách Python © 2015 Imagine Publishing Ltd, chỉ đơn giản là phân biệt sự khác biệt bằng gợi ý sau được đề cập trong trang 10 như:

Một ngôn ngữ được thông dịch như Python là một ngôn ngữ nơi mã nguồn được chuyển đổi thành mã máy và sau đó được thực thi mỗi khi chương trình chạy. Điều này khác với ngôn ngữ được biên dịch, chẳng hạn như C, trong đó mã nguồn chỉ được chuyển đổi thành mã máy một lần - mã máy kết quả sau đó được thực thi mỗi khi chương trình chạy.


1

Biên dịch là quá trình tạo ra một chương trình thực thi từ mã được viết bằng ngôn ngữ lập trình được biên dịch. Biên dịch cho phép máy tính chạy và hiểu chương trình mà không cần phần mềm lập trình được sử dụng để tạo ra nó. Khi một chương trình được biên dịch, nó thường được biên dịch cho một nền tảng cụ thể (ví dụ như nền tảng IBM) hoạt động với các máy tính tương thích của IBM, nhưng không phải là các nền tảng khác (ví dụ như nền tảng của Apple). Trình biên dịch đầu tiên được phát triển bởi Grace Hopper khi làm việc trên máy tính Harvard Mark I. Ngày nay, hầu hết các ngôn ngữ cấp cao sẽ bao gồm trình biên dịch riêng hoặc có sẵn bộ công cụ có thể được sử dụng để biên dịch chương trình. Một ví dụ điển hình về trình biên dịch được sử dụng với Java là Eclipse và một ví dụ về trình biên dịch được sử dụng với C và C ++ là lệnh gcc.


0

Định nghĩa ngắn (không chính xác):

Ngôn ngữ tổng hợp: Toàn bộ chương trình được dịch sang mã máy cùng một lúc, sau đó mã máy được CPU chạy.

Giải thích ngôn ngữ: Chương trình được đọc từng dòng một và ngay khi một dòng được đọc, các hướng dẫn máy cho dòng đó được CPU thực thi.

Nhưng thực sự, rất ít ngôn ngữ ngày nay được biên soạn hoàn toàn hoặc hoàn toàn diễn giải, nó thường là một hỗn hợp. Để biết mô tả chi tiết hơn với hình ảnh, xem chủ đề này:

Sự khác biệt giữa biên dịch và giải thích là gì?

Hoặc bài viết sau này của tôi:

https://orangejuiceliberationfront.com/the-difference-b between-compiler-and-interpreter /

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.