Tại sao C ++ để viết một trình biên dịch?


15

Tôi đã tự hỏi tại sao C ++ là một lựa chọn tốt để viết một trình biên dịch. Tất nhiên C cũng tốt cho mục đích này, bởi vì nhiều trình biên dịch được viết bằng C hoặc C ++ nhưng tôi quan tâm nhiều hơn đến C ++ lần này. Bất kỳ lý do tốt? Tôi đã tìm kiếm điều đó trên Internet, nhưng tôi không thể tìm thấy bất kỳ lý do chính đáng nào.


3
"Nhiều trình biên dịch được viết [...] bằng C ++" - có tham chiếu nào không? Những cái nào? Điều gì khiến bạn nghĩ rằng C ++ thường được sử dụng để xây dựng trình biên dịch hơn các ngôn ngữ phổ biến khác?
Doc Brown

4
@DocBrown Vâng, Clang và MSVC được viết chủ yếu bằng C ++, gcc có một chút C ++ trong đó, Java JVM được viết bằng C ++ stackoverflow.com/questions/410320/what-is-java-written-in và cũng là siêu người dùng. com / câu hỏi / 136136 / Hoài
Klaim

@DocBrown DMD trình biên dịch tham chiếu cho D được viết bằng C ++
ratchet freak

3
Ai nói đó là một lựa chọn tốt ??
Phil

1
@Phil Bạn có nghĩ rằng họ đã lựa chọn mà không có sự xem xét thay thế? Đó không phải là một lựa chọn "tốt", đó là một lựa chọn "hiệu quả".
Klaim

Câu trả lời:


21

C ++ có hai mặt của nó. Nó có một khía cạnh phát triển cấp thấp khiến nó có vẻ như là một ngôn ngữ tự nhiên để thực hiện những thứ cấp thấp như tạo mã. Nó cũng có một mặt cấp cao (mà C không) cho phép bạn cấu trúc một ứng dụng phức tạp (như trình biên dịch) theo cách hợp lý, hướng đối tượng, trong khi vẫn duy trì hiệu suất. Bởi vì nó có cả các khía cạnh cấp thấp và cấp cao, nên đây là một lựa chọn tốt cho ứng dụng lớn đòi hỏi các tính năng hoặc hiệu suất cấp thấp.


9
Theo như tôi biết thì rất nhiều logic bên trong trình biên dịch có bản chất chức năng (chuyển đổi các cấu trúc dữ liệu phức tạp thành các cấu trúc dữ liệu khác) vì vậy tôi không chắc liệu các phương tiện hướng đối tượng (được nhắm mục tiêu nhiều hơn đến lập trình lớn , các khía cạnh kiến ​​trúc) mang lại một lợi thế thực sự cho trình biên dịch xây dựng wrt cho một phong cách lập trình thủ tục. Chỉ 2 xu của tôi.
Giorgio

5
@Giorgio Có các đối tượng giúp trong rất nhiều khía cạnh khác của việc viết trình biên dịch. Ví dụ, có rất nhiều trạng thái mà trình biên dịch phải xử lý khi tối ưu hóa và loại công cụ đó tự cho vay tốt với OOP. Ngoài ra, lập trình OOP và chức năng có thể khá miễn phí, vì vậy chỉ vì các thuật toán có thể chủ yếu là chức năng, không có nghĩa là các đối tượng sẽ không giúp đỡ.
Oleksi

3
@Giorgio và Oleksi: Tôi có thể xác nhận cả hai bạn. Tôi đã viết một trình biên dịch với Haskell cho một ngôn ngữ trong thế giới thực. Đó là một sự phù hợp thực sự tốt. Nhưng đôi khi tôi đã bỏ lỡ một số OO xung quanh. Nếu tôi phải viết một trình biên dịch khác, tôi chắc chắn sẽ chọn Haskell, nhưng đây thực sự là một trường hợp đặc biệt. Tôi sẽ không chọn Haskell mà không do dự cho các loại dự án khác.
Scarfridge

23
Tại sao bạn cần phải có một ngôn ngữ với "bên cấp thấp" để tạo mã? Tôi không thể thấy hai cái này được kết nối theo cách nào.
phant0m

5
Bạn không cần "bên cấp thấp" để tạo mã nhiều hơn bạn cần số nhận dạng Unicode để có thể viết văn bản tiếng Nhật vào tệp.
dan04

11

Kinh nghiệm của tôi không đồng ý với tiền đề của bạn ở đây. Trong thực tế, đối với các ngôn ngữ có mục đích chung cấp cao, việc viết trình biên dịch theo cùng ngôn ngữ với ngôn ngữ nguồn (ngôn ngữ đang được biên dịch) là một cách làm rất phổ biến . Ví dụ:

  • Trình biên dịch Java của Sun được viết bằng Java
  • Trình biên dịch Scala được viết bằng Scala
  • Trình biên dịch C # của Mono được viết bằng C #
  • Trình biên dịch Smalltalk của Squick được viết bằng Smalltalk
  • ... và nhiều thứ khác nữa

Một ngoại lệ là phần đầu của trình biên dịch được viết cho các khung trình biên dịch hiện có, chẳng hạn như GCC, LLVM hoặc Polyglot, sau đó được viết bằng ngôn ngữ của khung hoặc trình biên dịch dựa trên các trình tạo trình phân tích cú pháp hiện có như Yacc. Do GCC, LLVM và Yacc là các công cụ phổ biến, được thiết lập bằng C và C ++, nên nó khuyến khích các nhà văn trình biên dịch sử dụng chúng, điều này có thể dẫn đến C và C ++ nhận được một phần lớn trong phân phối ngôn ngữ thực hiện trình biên dịch.


2
Tôi nghĩ điều đó có liên quan nhiều đến những người viết trình biên dịch biết rõ và thích rất nhiều ngôn ngữ họ đang viết một trình biên dịch hơn là vì lý do kỹ thuật khách quan.
Thomas Bonini

1
@ Kelp trình biên dịch ".
Sồi

1
Trình biên dịch Java của Sun được viết bằng C ++: stackoverflow.com/questions/410320/what-is-java-written-in
Klaim

10
@Klaim bạn đang nhầm lẫn hai sản phẩm ở đây. Một là trình biên dịch Java của Sun ( javacdòng lệnh), nó biên dịch Java thành Mã byte Java. Nó được viết bằng Java - Tôi đã tự sửa đổi nó nhiều lần và bạn có thể duyệt các nguồn Java trực tuyến . Cái còn lại là trình biên dịch đúng lúc được nhúng trong JVM Hotspot, trình biên dịch Mã byte Java thành mã máy gốc. Giống như hầu hết các JVM, nó được viết bằng C ++, nhưng nó không phải là trình biên dịch Java - thực tế, nó không biết gì về ngôn ngữ Java.
Sồi

@Oak, hoàn toàn chính xác! Nói cách khác, JVM! = Javac
Paul Draper

5

Để biên dịch cái gì để làm gì? Trình biên dịch chuyển đổi mã nguồn từ một ngôn ngữ ( ngôn ngữ nguồn) sang ngôn ngữ khác (ngôn ngữ đích), không cho biết bất cứ điều gì về mức độ thấp của ngôn ngữ đích.

  • CoffeeScript biên dịch thành JavaScript, trình biên dịch được viết bằng CoffeeScript.
  • Script # biên dịch C # thành JavaScript, trình biên dịch được viết, nếu tôi nhớ rõ, C #.
  • Vân vân.

Ngôn ngữ bạn chọn để viết trình biên dịch phụ thuộc vào ngữ cảnh. Ví dụ, khi làm việc trong một dự án biên dịch một ngôn ngữ có nguồn gốc từ PHP sang mã PHP gốc, tôi đã sử dụng kết hợp PHP và C # để viết trình biên dịch, bởi vì nó có ý nghĩa nhất đối với các kỹ năng của tôi. Một người khác sẽ chọn Python, hoặc Java và PHP hoặc C ++ với một chút JavaScript hoặc bất cứ điều gì.

C hoặc C ++ là một lựa chọn phổ biến vì có sự hỗ trợ của các công cụ liên quan đến trình biên dịch (xem câu trả lời của Telastyn) và vì hai ngôn ngữ này cho phép bạn đi thực sự bản địa. Nhưng không có gì sai trong việc lựa chọn ngôn ngữ khác.

Lưu ý rằng để trở nên táo bạo hơn , bạn có thể chọn ngôn ngữ nguồn để tự viết trình biên dịch. Đó là những gì đã xảy ra với trình biên dịch CoffeeScript và nhiều trình biên dịch khác. Nó cũng phổ biến với các IDE: một trong những Visual Studio đầu tiên được xây dựng bằng cùng Visual Studio.


4
Tự lưu trữ không phải là geeky, nó là một tài sản quan trọng để chuyển một trình biên dịch.

4
Lý do là, nó ngay lập tức cho phép trình biên dịch trở thành một chương trình thử nghiệm. Nó rất có thể cũng sẽ là chương trình lớn nhất cho trình biên dịch đó trong một thời gian dài.

5

Tôi có xu hướng đặt câu hỏi tiền đề cơ bản ở đây. Trong khi C và C ++ hoạt động hoàn hảo để viết trình biên dịch, khá nhiều ngôn ngữ khác dường như cũng hoạt động hoàn hảo cho nhiệm vụ này.

Một chút phụ thuộc vào ngôn ngữ bạn đang biên dịch mặc dù. Đối với các ngôn ngữ nhỏ, đơn giản, C và Pascal hoạt động khá độc đáo. Nếu bạn định biên dịch thứ gì đó lớn và phức tạp, trình biên dịch của bạn cũng lớn và phức tạp - trong trường hợp đó, các tính năng bổ sung của C ++ để tổ chức và làm việc với các chương trình lớn hơn rõ ràng có ích. Tuy nhiên, điều đó không thực sự cụ thể đối với việc biên dịch, chỉ là các tính năng hữu ích cho các chương trình lớn hơn nói chung.

Tôi nghĩ rằng nó cũng đáng đề cập đến một điểm khác. Những người mới bắt đầu (dường như) nghĩ về trình biên dịch hầu như thực hiện thao tác văn bản, vì vậy họ nghĩ rằng một cái gì đó như Perl sẽ giúp ích rất nhiều trong việc viết trình biên dịch. Trong thực tế, hầu hết các phần thú vị của quá trình biên dịch không thực sự bắt đầu cho đến khi bạn xây dựng AST. Mặc dù tôi chắc chắn Perl có thể thực hiện công việc một cách hoàn hảo, nhưng khả năng xử lý văn bản của nó cũng không thực sự mang lại lợi thế lớn cho nó (thao tác văn bản chủ yếu nằm ở lexer và các trình tạo lexer cho những thứ như C đều hỗ trợ REs).


2
AST = Cây cú pháp trừu tượng, RE = Biểu thức chính quy
hỗn loạn3quilibrium

5

Trình biên dịch có thể được thực hiện trong bất kỳ ngôn ngữ hiện đại. Tuy nhiên, một trong những yêu cầu quan trọng nhất từ ​​trình biên dịch là phải nhanh.

C ++ có một lợi thế rõ ràng ở đây. Tối ưu hóa trong C ++ không hề rẻ. Tuy nhiên, do tính chất cấp thấp của ngôn ngữ này, có thể tự tối ưu hóa mã C ++ hơn bất kỳ ngôn ngữ nào khác (ngoại trừ hội không có khả năng di động).


9
Một yêu cầu quan trọng khác là mã được tạo ra phải chính xác - tôi muốn có một trình biên dịch chậm mà tôi có thể tin tưởng hơn là một mã nhanh tạo mã không chính xác.

1
Mặc dù chắc chắn có thể tối ưu hóa C ++ rất nhiều, nhưng có rất nhiều mã khá tốt hơn so với mã C ++ tối ưu ngoài kia.
Donal Fellows

2
@DonalFellows Xoay ngược lại: có thể viết ít hơn mã tối ưu trong bất kỳ ngôn ngữ nào, nhưng có những tối ưu hóa không thể kích hoạt bằng các ngôn ngữ khác ngoài C ++ (trừ Trình biên dịch. Tôi không bao gồm C vì thiếu của các cấu trúc cấp cao cho phép nội tuyến mạnh hơn).
Klaim

2

Tôi nghi ngờ rằng động lực chính cho việc sử dụng của họ là đầu ra của Lex / Yacc / Bison là (chủ yếu) ở C. Vì đó là tiêu chuẩn từ rất lâu, nên nó có động lượng.

Không phải đó là những lý do đặc biệt tốt ...


Thật ra nó không làm tôi hài lòng, nhưng cảm ơn vì đã thử.
Kobra

Điều đó không trả lời câu hỏi "tại sao chọn C ++ trên C để xây dựng trình biên dịch".
Doc Brown

2
Đó không phải là một lý do tốt cả. Các công cụ tương tự với Lex và Yacc tồn tại cho nhiều nền tảng. PLY và ANTLR, ví dụ.
dùng16764

Hơn nữa, hầu hết các trình biên dịch trong thế giới thực phổ biến (ví dụ tôi khá chắc chắn là Clang và GCC) sử dụng các trình phân tích cú pháp viết tay.

@delnan: Có nhưng có lẽ họ đã bắt đầu sử dụng một cái được tạo ra để đưa mọi thứ lên khỏi mặt đất. Việc tạo trình phân tích cú pháp là một bước tối ưu hóa mà bạn không thực sự muốn làm cho đến khi bạn có thể chứng minh những thứ khác đang hoạt động.
Martin York
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.