it-swarm-vi.com

Tại sao không có người dịch tự động từ ngôn ngữ lập trình này sang ngôn ngữ khác?

Hầu hết các ngôn ngữ lập trình đều hoàn thành Turing, điều đó có nghĩa là bất kỳ tác vụ nào có thể được giải quyết bằng một ngôn ngữ đều có thể được giải quyết bằng ngôn ngữ khác hoặc thậm chí trên máy Turing. Vậy thì tại sao không có người dịch tự động có thể chuyển đổi chương trình từ bất kỳ ngôn ngữ nào sang ngôn ngữ khác? Tôi đã thấy một số nỗ lực cho hai ngôn ngữ, nhưng chúng luôn chỉ hoạt động trên một tập hợp con giới hạn của ngôn ngữ và khó có thể được sử dụng để chuyển đổi các dự án thực.

Có thể, ít nhất là về lý thuyết, có thể viết người dịch đúng 100% giữa tất cả các ngôn ngữ? Những thách thức trong thực tế là gì? Có bất kỳ dịch giả hiện có làm việc?

37
serg

Vấn đề lớn nhất không phải là bản dịch mã chương trình thực tế, mà là việc chuyển API nền tảng.

Hãy xem xét một trình dịch PHP đến Java. Cách khả thi duy nhất để làm điều đó mà không nhúng một phần của nhị phân PHP là thực hiện lại tất cả các mô-đun và API của PHP trong Java. Điều này liên quan đến việc thực hiện hơn 10.000 chức năng. So với công việc thực sự dịch cú pháp thì dễ như ăn bánh. Và thậm chí sau tất cả các công việc bạn sẽ không có mã Java, bạn sẽ có một số thứ quái dị xảy ra để chạy trên nền tảng Java, nhưng nó có cấu trúc như PHP ở bên trong.

Đây là lý do tại sao các công cụ như vậy xuất hiện trong tâm trí là tất cả về dịch mã để triển khai nó, không phải để duy trì nó sau đó. GWT của Google "biên dịch" Java thành JavaScript. Hiphop của Facebook biên dịch PHP thành C.

32
Joeri Sebrechts

Nếu bạn có định dạng trung gian, thì bạn có thể triển khai thứ gì đó dịch chương trình trong Ngôn ngữ X sang định dạng đó định dạng đó và cả từ định dạng sang Ngôn ngữ Y. Thực hiện các chuyển đổi đó cho tất cả các ngôn ngữ bạn quan tâm và bạn đã hoàn thành, phải không?

Vâng bạn biết gì không? Một định dạng như vậy đã tồn tại: Hội. Trình biên dịch đã thực hiện chuyển đổi "Ngôn ngữ X thành hội" và phân tách thành chuyển đổi "Kết hợp thành ngôn ngữ Y".

Bây giờ, hội không phải là một ngôn ngữ tuyệt vời để thực hiện chuyển đổi ngược lại, nhưng MSIL thực sự không phải là xấu. Tải xuống Reflector và bạn sẽ thấy có các tùy chọn để phân tách một hội .NET thành một loạt các ngôn ngữ khác nhau (và các plugin cung cấp nhiều hơn nữa). Vì vậy, hoàn toàn có thể lấy một chương trình trong C #, biên dịch nó thành a DLL (nghĩa là MSIL), sau đó sử dụng bộ phản xạ để phân tách nó thành VB, C++/CLI, F # và toàn bộ Tất nhiên, tất cả các công việc chuyển đổi khác cũng vậy. Lấy tệp F #, biên dịch thành DLL, sử dụng Reflector để chuyển đổi nó thành C #.

Tất nhiên, hai vấn đề lớn mà bạn sẽ tìm thấy là:

  1. Mã về cơ bản là không thể đọc được. MSIL (ngay cả với thông tin gỡ lỗi) sẽ xóa rất nhiều thông tin khỏi nguồn ban đầu, vì vậy phiên bản dịch không có độ trung thực 100% (về mặt lý thuyết thực hiện chuyển đổi C # -> MSIL-> C # sẽ cung cấp cho bạn mã gốc, nhưng nó sẽ không).
  2. Nhiều ngôn ngữ .NET có thư viện tùy chỉnh riêng (ví dụ: VB, thư viện F #, v.v.) Chúng cũng cần được bao gồm (hoặc chuyển đổi) khi bạn thực hiện chuyển đổi.

Thực sự không có gì để có được khoảng # 2, nhưng bạn có thể có được khoảng # 1 với một số chú thích bổ sung trong MSIL (có thể thông qua các thuộc tính). Đó sẽ là công việc bổ sung, tất nhiên.

20
Dean Harding

Có thể, ít nhất là về lý thuyết, có thể viết người dịch đúng 100% giữa tất cả các ngôn ngữ? Những thách thức trong thực tế là gì?

  • Dịch từ một ngôn ngữ có cấu trúc nhiều hơn sang ngôn ngữ ít cấu trúc hơn mà vẫn hoàn chỉnh Turing, luôn luôn có thể. [.__.]
    • Khiếu nại này nên được xem theo nghĩa kỹ thuật nghiêm ngặt: Điều đó có nghĩa là chương trình dịch sẽ tạo ra kết quả chính xác tương tự khi nó được thực thi.
    • Không có gì được ngụ ý về khả năng đọc mã dịch hoặc bảo toàn cấu trúc chương trình gốc.
  • Có thể dịch từ ngôn ngữ ít cấu trúc sang ngôn ngữ có cấu trúc chặt chẽ hơn, nhưng mã dịch sẽ vẫn ở dạng ít cấu trúc hơn.
20
rwong

Tại sao bạn muốn chuyển đổi một chương trình?

Cả hai ngôn ngữ, nguồn và ngôn ngữ đích đều được biên dịch thành (dù sao) máy móc mã hóa *, vì vậy, vì lý do kỹ thuật, không cần phải có trình biên dịch sang ngôn ngữ cấp cao khác.

Ngôn ngữ là dành cho con người. Vì vậy, yêu cầu ngầm định cho câu hỏi của bạn là: 'tại sao không có người dịch tạo ra mã có thể đọc ' và câu trả lời sẽ là (imho): bởi vì nếu có hai ngôn ngữ khác nhau về mặt hiệu quả, thì cách viết 'mã có thể đọc được' sẽ khác nhau theo cách không chỉ yêu cầu dịch thuật toán, mà sử dụng các thuật toán khác nhau.

Ví dụ, so sánh một lần lặp điển hình trong C và một lần lặp trong LISP. Hoặc trăn 'một cách tốt nhất' với Ruby thành ngữ.

Ở đây, những vấn đề tương tự bắt đầu xuất hiện ở các ngôn ngữ thực, như bạn dịch 'Trời mưa mèo và chó' sang một thứ gì đó với ý nghĩa 'Nó đổ như xô từ' khi dịch từ tiếng Anh sang tiếng Đức, bạn không thể dịch Word bằng Word nữa, nhưng bạn phải tìm nghĩa.

Và "ý nghĩa" không phải là một khái niệm dễ dàng để làm việc.

*) tốt, có cà phê ...

10
keppla

Về mặt lý thuyết là có thể nhưng chủ yếu là vô dụng. Hầu như mọi sự kết hợp giữa ngôn ngữ nguồn và ngôn ngữ đích đều có thể, nhưng trong hầu hết các trường hợp, không ai muốn xem hoặc sử dụng kết quả.

Một số lượng lớn trình biên dịch thực hiện nhắm mục tiêu C, đơn giản vì trình biên dịch C có sẵn cho hầu hết mọi nền tảng tồn tại (và có các trình tạo trình biên dịch tự động sẽ cho phép bạn thiết kế bộ xử lý và tự động tạo trình biên dịch C nhắm vào bộ xử lý mới của bạn). Tất nhiên, cũng có một số lượng triển khai hợp lý nhắm vào các ngôn ngữ được sử dụng bởi các máy ảo khác nhau như .NET, JVM, C-- và LLVM.

Tuy nhiên, điểm mấu chốt là nó thực sự chỉ hữu ích nếu bạn đối xử với mục tiêu về cơ bản là ngôn ngữ hội chỉ được sử dụng như một bước trong quy trình biên dịch. Cụ thể, bạn thường làm không muốn một lập trình viên bình thường đọc hoặc làm việc với kết quả đó; nó thường sẽ không thể đọc được.

6
Jerry Coffin

FWIW, có một người dịch từ Java sang D. Nó được gọi là TioPort và đã được sử dụng trong một nỗ lực khá nghiêm trọng để chuyển SWT sang D. Vấn đề chính mà nó gặp phải là nó sẽ là cần thiết để chuyển các phần lớn của thư viện tiêu chuẩn Java.

5
dsimcha

Mặc dù nó không phải là mã dịch mỗi se, khái niệm bàn làm việc ngôn ngữ cho thấy cách thức một cái gì đó giống với một người dịch chính xác 100% giữa tất cả các ngôn ngữ có thể được thực hiện.

Theo cách tiếp cận hiện tại của chúng tôi, mã nguồn được lưu trữ ở định dạng văn bản. Trong quá trình biên dịch, các tệp văn bản có thể đọc được của con người này được phân tích cú pháp thành một biểu diễn cây cú pháp trừu tượng, lần lượt được sử dụng để tạo mã byte hoặc mã máy. Đại diện trừu tượng này tuy nhiên là tạm thời và nội bộ cho trình biên dịch.

Trong cách tiếp cận bàn làm việc ngôn ngữ, một biểu diễn cây cú pháp trừu tượng tương tự là tạo phẩm được lưu trữ vĩnh viễn. Cả mã máy và mã 'nguồn' văn ​​bản đều được tạo dựa trên biểu diễn trừu tượng này. Một trong những hậu quả của một phương pháp như vậy là sự biểu diễn trừu tượng của chương trình thực sự là bất khả tri về ngôn ngữ và có thể được sử dụng để tạo mã văn bản trong bất kỳ ngôn ngữ được triển khai nào. Có nghĩa là một người có thể tự do làm việc trên các khía cạnh khác nhau của hệ thống bằng cách sử dụng bất kỳ ngôn ngữ nào họ thấy là phù hợp nhất hoặc mỗi thành viên trong nhóm có thể làm việc với dự án được chia sẻ bằng ngôn ngữ mà họ quen thuộc nhất.

Theo tôi biết, công nghệ vẫn còn lâu mới có thể sử dụng được trong phát triển chính thống, tuy nhiên có một số nhóm làm việc độc lập với nó. Thật khó để biết liệu bất kỳ ai trong số họ sẽ thực hiện theo lời hứa của họ, nhưng sẽ rất thú vị khi thấy điều đó xảy ra.

4
scrwtp

đang một số dịch giả tự động. Nếu mục tiêu của bạn là sản xuất mã có thể biên dịch, thay vì mã có thể đọc được, điều đó hoàn toàn có thể và đôi khi hữu ích, chỉ là không thường xuyên. Nổi tiếng, trình biên dịch C++ đầu tiên không thực sự là trình biên dịch, mà đã dịch C++ thành nguồn C (thực sự phức tạp) sau đó được biên dịch bởi trình biên dịch C. Nhiều trình biên dịch có thể tạo mã hội theo yêu cầu - nhưng thay vì phun ra văn bản hội và sau đó dịch mã sang mã máy, thông thường họ có thể tạo mã máy trực tiếp.

Với một đặc điểm kỹ thuật hoàn chỉnh của ngôn ngữ A, về nguyên tắc không khó để viết một chương trình thể hiện các chỉ thị của nó bằng một số ngôn ngữ B. Nhưng thông thường, bất cứ ai gặp rắc rối sẽ chọn một thứ gì đó thực sự ở mức thấp cho "ngôn ngữ B": Mã máy hoặc những ngày này là mã byte: Jython là một triển khai của python tạo ra Java mã byte, được diễn giải bởi Java = VM. Không cần bận tâm viết ra và biên dịch Java!

4
alexis

Điều này được thực hiện tất cả các thời gian.

Mọi trình biên dịch đều dịch "ngôn ngữ chính", như C++, sang ngôn ngữ hội nguyên gốc hoặc mã byte độc ​​lập với kiến ​​trúc trong trường hợp ngôn ngữ được dịch.

Tôi tưởng tượng đó không phải là những gì bạn đang nói về, mặc dù. Bạn có thể muốn một trình dịch chuyển đổi C++ thành một cái gì đó như Java hoặc Python. Mặc dù vậy, điểm tốt nhất là gì? Kết quả cuối cùng sẽ có hiệu quả chính xác như nguồn ban đầu. ( Thực tế, nó sẽ tồi tệ hơn nhiều.)

Nếu bạn chỉ muốn mã được dịch để bạn có thể đọc nó như một ngôn ngữ bạn hiểu, thì một dịch giả sẽ có tác dụng ngược lại với hiệu ứng mong muốn. Bạn sẽ bị bỏ lại với một loạt mã khó hiểu, không trực quan và không thể đọc được.

Điều này là do chỉ những điều tầm thường nhất dịch trực tiếp từ ngôn ngữ này sang ngôn ngữ khác. Thông thường, những gì đơn giản trong một ngôn ngữ đòi hỏi các thư viện lớn cho ngôn ngữ khác - hoặc có thể hoàn toàn không thể. Vì thế:

  1. Nếu chương trình là tầm thường, bạn có thể nhận được một kết quả tốt. Nhưng sau đó, nếu nó đơn giản, thì điều gì thậm chí là điều hành nó thông qua một dịch giả?
  2. Nếu chương trình không cần thiết, mã sẽ có chất lượng thấp.

Cuối cùng, cách duy nhất để viết mã tốt là thực sự viết nó. Máy tính đơn giản là không thể - ít nhất là chưa - phù hợp với con người về các vấn đề dễ đọc, thực hành tốt nhất và giải pháp thanh lịch.

Nói tóm lại, thật không đáng.

3
Maxpm

Không có người dịch ngôn ngữ cho các ngôn ngữ lập trình vì ngôn ngữ lập trình rất phức tạp. Trong khi nó là giả thuyết có thể, có nhiều thách thức.

Thách thức đầu tiên chỉ đơn thuần là trong thực tiễn ngôn ngữ được chấp nhận. Chuyển đổi giữa hai ngôn ngữ hướng đối tượng như Java và C++ rất phức tạp và cả hai đều dựa trên C. Chương trình dịch sẽ phải có kiến ​​thức hoàn hảo về thư viện chuẩn cho cả hai ngôn ngữ và có thể Bạn sẽ phải tạo ra một từ điển lớn và thậm chí sau đó, sự khác biệt trong phong cách lập trình từ lập trình viên đến lập trình viên có nghĩa là nó sẽ phải đoán về cách thực hiện một số thay đổi.

Khi bạn đã dịch được cú pháp xuống, sau đó bạn phải tìm ra cách chuyển đổi một cấu trúc trong ngôn ngữ đầu tiên sang một cấu trúc trong ngôn ngữ thứ hai. Điều này tốt nếu bạn chuyển một đối tượng trong C++ sang một đối tượng trong Java (tương đối dễ) nhưng bạn sẽ làm gì với các cấu trúc C++ của mình? Hoặc các chức năng bên ngoài các lớp C++ ? Quyết định làm thế nào để xử lý việc này có thể khó khăn vì nó có thể dẫn đến một vấn đề khác, đó là việc tạo ra một đối tượng blob. Blob là một antipotype đủ phổ biến.

Đây không phải là một danh sách đầy đủ các vấn đề, nhưng đó chỉ là hai và chúng là những vấn đề lớn. Một trong những giáo sư của tôi đã đề cập rằng ai đó đã thuyết phục chủ nhân của mình rằng họ có thể tạo một từ mã máy đến C trong những năm 80, nhưng sau đó nó không hoạt động. Tôi nghi ngờ sẽ có một cái hoạt động đầy đủ.

1
indyK1ng

Điểm biên dịch là để có được một cái gì đó hữu ích cho máy tính. tức là một cái gì đó có thể chạy. Tại sao biên dịch thành một cái gì đó thậm chí có thể cao hơn những gì bạn đã viết nó?

Tôi thích chiến lược của .NET hơn. Biên dịch mọi thứ thành một ngôn ngữ chung. Điều này mang lại lợi ích của các ngôn ngữ có thể giao tiếp mà không cần phải tạo (N ^ 2) -N trình biên dịch ngôn ngữ chéo.

Ví dụ: nếu bạn có 10 ngôn ngữ lập trình, bạn sẽ chỉ cần viết 10 trình biên dịch theo mô hình .NET và tất cả chúng có thể giao tiếp với nhau. Nếu bạn thực hiện tất cả các trình biên dịch ngôn ngữ chéo có thể, bạn sẽ cần phải viết 90 trình biên dịch. Đó là rất nhiều công việc làm thêm vì lợi ích nhỏ.

1
mike30