Điều đó có nghĩa là ngôn ngữ A được viết bằng ngôn ngữ BÙA?


31

Tôi thường nghe thuật ngữ ngôn ngữ A được viết bằng ngôn ngữ B. Ví dụ: PHP đã được viết C , C # được viết bằng C ++ .

Ai đó có thể vui lòng giải thích điều đó có nghĩa là gì và nếu nó thậm chí là chính xác? Điều đó có liên quan gì đến trình biên dịch trình thông dịch được sử dụng bởi ngôn ngữ không?

Ngoài ra, các yếu tố mà sự lựa chọn của ngôn ngữ thực hiện được xây dựng dựa trên những yếu tố nào?


19
Nói đúng ra, "PHP đã được viết bằng C" là sai. Một ngôn ngữ là một định nghĩa chính thức, do đó nó không được viết bằng ngôn ngữ lập trình viên khác (mà là tiếng Anh); chỉ trình biên dịch, trình thông dịch và / hoặc thư viện có thể được viết bằng C, C ++ hoặc bất cứ thứ gì. Trong thực tế, đối với nhiều ngôn ngữ, có một trình biên dịch hoặc trình thông dịch chiếm ưu thế và sự khác biệt giữa định nghĩa và thực hiện ngôn ngữ không được thực hiện.
user281377

Điều thú vị là BCPL chủ yếu được viết bằng BCPL
OldCurmudgeon

7
PHP "per se", không phải là một định nghĩa chính thức. Đây là một chương trình C.
Kaz

8
s/written/implemented/và nó rõ ràng hơn nhiều.
TMN

2
@ugoren Có rất nhiều trình biên dịch C được viết bằng cách lắp ráp. Thế kỷ này không nhiều lắm.
Ross Patterson

Câu trả lời:


30

Hầu hết các ngôn ngữ lập trình thuộc hai loại: ngôn ngữ được giải thích và ngôn ngữ được biên dịch.

Một ngôn ngữ được biên dịch được dịch bởi một trình biên dịch thành mã máy , ngôn ngữ mà CPU trực tiếp thực hiện từng bước. Mặt khác, một ngôn ngữ thông dịch sử dụng một trung gian, một thông dịch viên , để chạy mã ngôn ngữ. Trình thông dịch là một chương trình khác, thường được biên dịch thành mã máy.

PHP là một ngôn ngữ được giải thích. Bạn cần một chương trình riêng để chạy mã PHP, máy tính không chạy chương trình trực tiếp. Chương trình riêng biệt đó, trình thông dịch PHP, được viết bằng C.

C # là một ngôn ngữ được biên dịch, nhưng nó không được biên dịch thành mã máy. Thay vào đó, nó được biên dịch sang ngôn ngữ chuyên gia, mã byte, để được chạy trên máy ảo. Java là một ví dụ khác về thiết lập như vậy. Bạn có thể thấy nó như một sự kết hợp giữa biên dịch và giải thích, trong đó máy ảo là một trình thông dịch. Máy ảo cho C # (CLI hoặc Cơ sở hạ tầng ngôn ngữ chung ) được viết bằng C ++.

Các ví dụ khác là:

  • Python: Trình thông dịch Python biên dịch mã Python thành mã byte Python, sau đó phiên dịch mã byte. Bản thân trình thông dịch được viết bằng C. Các triển khai mới đã được thêm vào, bao gồm một trình biên dịch python để chạy trên cùng CLI được sử dụng cho C #, được gọi là IronPython và một triển khai chạy trên máy ảo Java, Jython . Để hoàn thành vòng tròn, có một phiên bản Python được viết bằng (một tập hợp con) Python, PyPy .
  • Ruby: Ruby khởi đầu là một ngôn ngữ được dịch thuần túy, nhưng phiên bản gần đây nhất đã chuyển sang sử dụng mã byte. Đối với Ruby cũng vậy, có một dự án biên dịch thành CLI, được đặt tên là IronRuby và một dự án cho Java VM, JRuby .

Tôi xin lỗi, làm thế nào một máy ảo khác với một trình thông dịch? Tôi không thấy cách sử dụng một là một nửa điểm để biên dịch. Bạn đang nói rằng mã byte được biên dịch một nửa?
Philip

1
@Philip: Mã byte không phải là mã máy; Vì vậy, thay vì cung cấp cho CPU các hướng dẫn trực tiếp, bạn vẫn cần một trình thông dịch để lấy mã byte và giải thích điều đó, dịch nó thành các hướng dẫn máy. Ưu điểm là máy ảo đơn giản hơn để chuyển sang các kiến ​​trúc khác và bạn có thể áp dụng các thủ thuật như biên dịch JIT .
Martijn Pieters

Có ai cảm thấy như thuật ngữ "biên dịch" đã bị pha loãng cho các mục đích tiếp thị không?
Philip

2
Whoa! Tôi lấy lại cái đó. Tôi đã đi sai đường ở đó một lúc. Tôi cho rằng "đã biên dịch" có nghĩa là biến thành mã máy và chỉ mã máy, điều đó không thực sự đúng. Nó chỉ là một thuật ngữ để dịch mã sang mã khác. Là mã máy, mã byte hoặc bất kỳ ngôn ngữ nào bạn muốn. Ngoài ra, hóa ra có các trình biên dịch PHP ngoài kia, vì vậy bạn chỉ có thể nói nó "thường" được giải thích.
Philip

Cũng là một nguồn tốt: youtube.com/watch?v=e4ax90XmUBc
Adam

34

Bạn cơ bản là đúng. Nếu người ta nói rằng Ruby được viết bằng C, điều này có nghĩa là trình thông dịch ngôn ngữ và các phần của thư viện lõi được viết bằng C.

Vì vậy, trình thông dịch Ruby là một chương trình C lấy tệp văn bản làm đầu vào, xử lý nó và sau đó gọi các hàm nằm trong tệp văn bản khác (nếu được viết bằng Ruby) hoặc được biên dịch mã C, nhiều chức năng cơ bản cần để truy cập trực tiếp các tài nguyên hệ thống như bộ nhớ, hệ thống tệp và hơn thế nữa. Và một số chức năng đòi hỏi hiệu suất rất cao.

Vì vậy, bạn có các phần khác nhau của một ngôn ngữ có thể hoặc phải được viết bằng các ngôn ngữ khác. Không có gì có thể ngăn bạn viết trình thông dịch bằng C và các thư viện trong C ++ (mặc dù có thể làm cho một vài điều khó khăn hơn). Bạn thậm chí có thể có nhiều bước và sử dụng một ngôn ngữ rất tốt trong xử lý văn bản để tạo một số dữ liệu trung gian sau đó được xử lý bởi một số mã C.

Các yếu tố cho quyết định có thể giống như đối với các ứng dụng phức tạp khác. Hiệu suất là một. Khả năng viết mã có thể truy cập tài nguyên hệ thống trực tiếp khác. Vì vậy, trong hầu hết các trường hợp, nó phải là một ngôn ngữ được biên dịch (mặc dù về lý thuyết bạn có thể viết một trình thông dịch Ruby bằng Python). Tính khả dụng trên các hệ thống khác nhau rất quan trọng nếu bạn muốn ngôn ngữ của mình chạy trên Linux, Win, OS X và các hệ thống khác.


Có ai biết tại sao tôi thấy ba câu trả lời cho câu trả lời của tôi ngay khi tôi đăng nó không?
thorsten müller

1
Bây giờ tôi nhìn thấy bốn người, nhưng tôi không thực sự chắc chắn những gì bạn đang hỏi? Có phải các upvote xuất hiện quá nhanh? Nếu vậy, tốt, rất nhiều mắt về câu hỏi (ba câu trả lời gần như đồng thời), và câu trả lời của bạn là tốt.
yannis

Hmm có. Có lẽ tôi đã lưu nó và sau đó chỉnh sửa, lưu lại và quên mất lần lưu đầu tiên (tôi đang già đi). Đối với tôi nó xuất hiện như thể tôi có ba lần nâng cấp đầu tiên ngay khi tôi đăng.
thorsten müller

@ thorstenmüller +1 cho "Không gì có thể ngăn bạn viết trình thông dịch bằng C và các thư viện trong C ++" Tôi chỉ định hỏi bạn về điều này. Có bất kỳ triển khai nổi tiếng nào cho điều này khi trình thông dịch / trình biên dịch ở một ngôn ngữ trong khi các thư viện cốt lõi ở ngôn ngữ khác không?
Songo

@ thorstenmüller Tôi đã có một vài lần xảy ra. Nếu một vài người đang xem câu hỏi khi bạn đăng, sẽ có một thông báo nhỏ nói rằng "Một câu trả lời mới đã được đăng" trong vòng một hoặc hai bạn nhấn gửi, vì vậy họ có thể lướt qua toàn bộ câu trả lời và được nâng lên trong vòng 10 giây của bạn đăng nó. Ngoài ra, các chỉnh sửa được thực hiện trong vòng 5 phút sau khi đăng câu trả lời không hiển thị trong lịch sử chỉnh sửa, điều này có thể gây ra thêm sự nhầm lẫn nhỏ về phía bạn.
Izkata

10

Nó đơn giản có nghĩa là hầu hết cốt lõi của ngôn ngữ A được viết bằng ngôn ngữ B. "Lõi ngôn ngữ A" nào có thể khác với ngôn ngữ này, nhưng nói chung bạn đoán đúng, nó có nghĩa là trình biên dịch hoặc trình thông dịch. Yếu tố quyết định chọn ngôn ngữ để viết ngôn ngữ khác là, vì với hầu hết mọi dự án, ngôn ngữ nào các nhà phát triển đều quen thuộc hơn.

Điều đó nói rằng, "ngôn ngữ A được viết bằng ngôn ngữ B" là một sự đơn giản hóa cho hầu hết các ngôn ngữ hiện đại. Nếu chúng ta lấy Python làm ví dụ, trong khi triển khai tham chiếu, CPython , thực sự được viết bằng C, có các triển khai được viết bằng các ngôn ngữ khác, như Jython (viết bằng Java), IronPython (viết bằng C #), PyPy (viết bằng Python), CLPython (viết bằng Common Lisp), Stackless Python (viết bằng C và Python) và Unladen Swallow (viết bằng C ++).

Ngôn ngữ lập trình là một định nghĩa và như ví dụ Python cho thấy, thực sự không có bất kỳ hạn chế nào đối với ngôn ngữ mà trình biên dịch, trình thông dịch và thư viện của nó có thể được viết. Và dĩ nhiên, ngôn ngữ cũng có thể được viết bằng ngôn ngữ thông qua một quá trình gọi là bootstrapping .


2
Tôi sẽ không gọi Psyco là một triển khai khác, vì nó chạy như một phần mở rộng cho CPython.
Martijn Pieters

@MartijnPieters Đây cũng là một dự án đã chết, theo trang web của nó. Đã gỡ bỏ.
yannis

@YannisRizos Không phải Unladen Nuốt cũng chết sao?
Andres F.

1
@Songo: Khác với string.lower(s)chức năng python ủy nhiệm điều đó return s.lower(), điều đó là chính xác. Các hoạt động trường hợp chuỗi CPython 3.3 được triển khai trong C.
Martijn Pieters


3

Từ góc độ sử dụng ngôn ngữ lập trình, ngôn ngữ lập trình chỉ là một chương trình. Nó có thể là một trình biên dịch, hoặc nó có thể là một trình thông dịch, hoặc nó có thể là một loại máy ảo. Tất cả những thứ đó chỉ là chương trình máy tính, và do đó có thể được viết bằng bất kỳ ngôn ngữ nào.

Vì vậy, nếu bạn muốn tạo phiên bản PHP của riêng mình, bạn có thể bắt đầu với bất kỳ ngôn ngữ nào bạn thông thạo nhất. Sau đó, bạn sẽ viết một chương trình có thể đọc mã định dạng PHP và làm bất cứ điều gì mà thông số PHP nói rằng chương trình của bạn nên làm . Do đó, bạn đang tạo ngôn ngữ PHP bằng ngôn ngữ X.


Điểm thú vị. Vì vậy, về cơ bản nếu tôi có một hàm dựng sẵn trong PHP explodecó một Stringvà trả về một Array, thì việc thực thi của nó (tức là mã sẽ hoạt động trên chuỗi để tạo ra mảng) được viết bằng C , phải không?
Songo

@Songo: đúng rồi. Một lần nữa, PHP chỉ là một chương trình, không khác gì Word hay Apache hay Notepad hay vi hoặc emacs. Nó đọc dữ liệu và phân tích nó theo một đặc tả ngôn ngữ, sau đó làm bất cứ điều gì đặc tả ngôn ngữ nói rằng nó nên làm.
Bryan Oakley

Câu trả lời này kết hợp xấu ngôn ngữ với việc thực hiện.
Russell Borogove

Tôi nghĩ rằng đây là câu trả lời đơn giản và trực tiếp nhất và tôi không thấy cách nó kết hợp bất cứ điều gì. Nó thậm chí còn gợi ý rằng có thể có nhiều hơn một triển khai PHP. Trên thực tế, có một số, PHP gốc và Facebook, và có thể có những thứ khác.
Warren P

@RussellBorogove: bạn không nghĩ rằng "từ góc độ sử dụng ngôn ngữ lập trình" giúp làm rõ câu trả lời? Hãy nhớ rằng, chúng tôi đang đối phó với một người mới bắt đầu tuyệt đối với câu hỏi của họ, vì vậy hy sinh một chút chính xác để minh họa quan điểm là công bằng, IMO.
Bryan Oakley

3

Một cụm từ rất giống nhau với ý nghĩa hoàn toàn khác nhau là "viết ngôn ngữ A bằng ngôn ngữ B", ví dụ "viết C bằng Java".

Điều này mô tả mã đúng về mặt cú pháp trong một ngôn ngữ, nhưng sử dụng các cấu trúc, thành ngữ và quy ước từ ngôn ngữ khác. Trong ví dụ "viết C trong Java", các dấu hiệu của điều này sẽ là khai báo tất cả các biến cục bộ trên đầu mỗi phương thức, sử dụng hằng số nguyên thay vì enums, sử dụng định danh_with_underscores, v.v.

Thông thường, điều này xảy ra khi ai đó đã làm việc với một ngôn ngữ trong một thời gian dài (đặc biệt là khi họ chỉ làm việc với ngôn ngữ đó) và rất mới đối với ngôn ngữ hiện tại (hoặc không quan tâm đến việc viết mã sạch).


"CPython được viết bằng C" chắc chắn không có nghĩa là "người dùng này viết bằng Python giống như C". Nó có nghĩa là CPython (Python.exe trên windows, / usr / bin / python trên Unix) được viết bằng C.
Warren P

@Warren P: chắc chắn, nhưng các cụm từ rất giống nhau, vì vậy những người không quen thuộc với một trong hai có thể dễ dàng kết thúc ở đây để tìm kiếm một lời giải thích.
Michael Borgwardt

3

Công nghệ là một quá trình lặp đi lặp lại vốn có. Chúng tôi bắt đầu với các công cụ đơn giản và sau đó sử dụng các công cụ đó để tạo ra những công cụ tốt hơn. Các ngôn ngữ lắp ráp đầu tiên có khá nhiều bản dịch 1: 1 của mã byte hướng dẫn được tiêu chuẩn hóa cho chip; kiến trúc 8086 và trình biên dịch chương trình của nó trở nên chiếm ưu thế so với các kiến ​​trúc khác như Z80, RISC, v.v. những ngôn ngữ này phải được viết bằng một cái gì đó nguyên thủy hơn, nếu không, bạn sẽ phải đối mặt với một cuộc tranh cãi giữa gà và trứng; nếu mã nguồn cho trình biên dịch C đầu tiên được viết bằng C, thì cái gì đã biên dịch mã nguồn C đó, và theo định nghĩa, đó có phải là trình biên dịch C đầu tiên không?

Về cơ bản, "C # được viết bằng C ++" có nghĩa là thư viện trình biên dịch và thời gian chạy / lõi phổ biến đầu tiên và / hoặc phổ biến nhất tuân theo đặc tả của ngôn ngữ C # (đó là .NET Framework và trình biên dịch dòng lệnh chương trình CSC.exe) được viết bằng C ++.


0

"Ngôn ngữ A được viết bằng ngôn ngữ B" có nghĩa là việc triển khai duy nhất ngôn ngữ A (hoặc là ngôn ngữ duy nhất được sử dụng rộng rãi) là ngôn ngữ thực sự là một dự án được phát triển bằng ngôn ngữ B và là dự án hoàn chỉnh duy nhất, cập nhật đặc tả của A là mã nguồn B thực thi nó sao cho nếu tài liệu và chương trình B không đồng ý, chương trình B thường được coi là đúng.


Không có một triển khai có thẩm quyền của C ++. Trong trường hợp của C ++, thông số kỹ thuật là chính xác và hành vi không xác định trong thông số kỹ thuật có thể làm bất cứ điều gì trong quá trình thực hiện của bạn. Vì vậy, điều này là không chính xác.
Warren P

Tôi không thấy những bình luận trước đó có liên quan gì đến câu trả lời của tôi. Tôi đã không đưa ra bất kỳ tuyên bố định lượng toàn cầu nào về tất cả các ngôn ngữ và do đó, ví dụ mẫu C ++ không được áp dụng. Một tuyên bố có dạng "A được viết bằng B", trong đó A là "C ++", không có nghĩa gì, ngoại trừ khi B là "tiếng Anh".
Kaz
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.