Trình biên dịch làm việc như thế nào? [đóng cửa]


16

Lưu ý: Tôi ngạc nhiên rằng điều này chưa được hỏi trước đây và nếu có thì tôi không thể tìm thấy nó trong một tìm kiếm.

Tôi đã có hàng tấn trang web, tôi đã đọc hàng tấn bài báo và tôi đã nghe hàng tấn lời giải thích. Hầu hết trong số họ là tốt, nhưng tất cả đều rộng hoặc quá phức tạp hoặc chỉ đơn giản là xấu. Vì vậy, câu hỏi của tôi là, một trình biên dịch làm việc như thế nào?

Nếu đây là một câu hỏi khó, rộng, xin vui lòng cho tôi biết. Nhưng nếu không, xin vui lòng trả lời câu hỏi.


4
Quá rộng, ít nhất là phần "Làm thế nào nó hoạt động". Có toàn bộ sách viết về chủ đề đó.
Oded

1
vi.wikipedia.org/wiki/Compiler sẽ là liên kết Wikipedia không quan trọng để tìm, cụ thể bạn đang tự hỏi điều gì? Câu hỏi đủ rộng để tôi có thể đưa ra câu trả lời thông minh, "Trình biên dịch dịch mã từ ngôn ngữ này sang ngôn ngữ khác", vì đó là ý tưởng chung có nhiều sắc thái trong đó một khi bắt đầu nhìn vào điều đó thực sự liên quan đến cái gì
JB King

1
Vâng và tôi nghĩ rằng nó đã được trả lời khá tốt.
Jeremy

1
Bất kỳ lời giải thích nào về cách trình biên dịch hoạt động sẽ quá rộng hoặc quá phức tạp. Đây là một chủ đề phức tạp và các lớp trình biên dịch là các khóa học liên quan đến máy tính khó nhất tôi từng tham gia.
David Thornley

1
@David Tất nhiên trình biên dịch rất phức tạp và bạn không thể giải thích tất cả các chi tiết về cách chúng hoạt động ở đây. Tuy nhiên, tôi chắc chắn rằng bạn đã có một sự hiểu biết cơ bản ở cấp độ cao về trình biên dịch là gì hoặc cách thức hoạt động trước khi bạn tham gia khóa học trình biên dịch.
Dima

Câu trả lời:


23

Trình biên dịch là một chương trình dịch mã nguồn cho một chương trình khác từ ngôn ngữ lập trình thành mã thực thi.

Mã nguồn thường là ngôn ngữ lập trình cấp cao (ví dụ: Pascal, C, C ++, Java, Perl, C #, v.v.). Mã thực thi có thể là một chuỗi các lệnh máy có thể được CPU thực thi trực tiếp hoặc nó có thể là một biểu diễn trung gian được diễn giải bởi một máy ảo (ví dụ mã byte Java).

Nói tóm lại, trình biên dịch chuyển đổi một chương trình từ định dạng có thể đọc được thành định dạng có thể đọc được bằng máy.

Về cách trình biên dịch hoạt động, điều đó thực sự phức tạp. Có sách và các khóa học đại học về chủ đề này. Tôi sẽ cố gắng phác thảo ngắn gọn các giai đoạn chính của quy trình, nhưng đây sẽ là một tổng quan rất khó hiểu.

  1. Lexing - chia văn bản của chương trình thành "mã thông báo". Các mã thông báo là "từ" của ngôn ngữ lập trình, chẳng hạn như mã định danh (từ khóa, tên biến, tên hàm, v.v.) hoặc toán tử (=, *, &, v.v.).
  2. Phân tích cú pháp - chuyển đổi chuỗi mã thông báo thành cây phân tích, là cấu trúc dữ liệu đại diện cho các cấu trúc ngôn ngữ khác nhau: khai báo kiểu, khai báo biến, định nghĩa hàm, vòng lặp, điều kiện, biểu thức, v.v.
  3. Tối ưu hóa - đánh giá các biểu thức không đổi, tối ưu hóa các biến không sử dụng hoặc mã không thể truy cập, các vòng lặp không kiểm soát nếu có thể, v.v.
  4. Dịch cây phân tích thành các lệnh máy (hoặc mã byte JVM).

Một lần nữa, tôi nhấn mạnh rằng đây là một mô tả rất ngắn gọn. Trình biên dịch hiện đại rất thông minh, và do đó, rất phức tạp.


2
Trên thực tế, nó biến đổi một ngôn ngữ thành ngôn ngữ khác. Trình biên dịch C ++ ban đầu đã biên dịch thành C. Trình biên dịch Vala cũng vậy. Trình biên dịch Java biên dịch thành mã byte không thể thực thi được nếu không có trình biên dịch JIT của JVM.
deadalnix

1
@deadalnix IMHO, vấn đề là bạn đi từ mã không thể thực thi sang mã thực thi. Tôi sẽ lập luận rằng C-front không phải là trình biên dịch mà là giao diện người dùng của trình biên dịch C. Hoặc một giai đoạn trong quá trình biên dịch, nếu bạn muốn. Tất nhiên, các máy ảo làm mờ ranh giới giữa "thực thi" và "không thể thực thi". Ở đây tôi chỉ đơn giản coi mã thực thi là bất cứ thứ gì đi vào máy ảo, như mã byte và trừu tượng hóa mọi thứ diễn ra bên trong VM, như JIT.
Dima

1
@Dima, nó không phải từ mã không thể thực thi sang mã thực thi. Chẳng hạn, bạn không thể thực thi mã byte JVM trực tiếp trên các máy Windows.

1
@ Thorbjørn Ravn Andersen: nhưng mã byte được JVM thực thi. Không phải toàn bộ quan điểm của một "máy ảo" trông giống như một máy thật đối với lập trình viên sao?
Dima

2
Tôi sẽ lập luận rằng theo truyền thống, một trình biên dịch đã chuyển đổi một chương trình từ định dạng có thể đọc được thành người có thể đọc được bằng máy, như Dima đã nói. Các biến thể như Cfront chuyển đổi C ++ sang C hoặc javac chuyển đổi Java sang mã byte là các chủ đề nâng cao hơn có lẽ nên để lại cho đến khi giải thích khái niệm truyền thống, cơ bản cho ai đó không quen thuộc với nó.
Carson63000

5

Trình biên dịch là một chương trình máy tính (hoặc bộ hướng dẫn) chuyển đổi mã nguồn được viết bằng ngôn ngữ lập trình (ngôn ngữ nguồn) sang ngôn ngữ máy tính khác (ngôn ngữ đích, thường có dạng nhị phân được gọi là mã đối tượng). Lý do phổ biến nhất cho việc muốn chuyển đổi mã nguồn là để tạo một chương trình thực thi.

Trình biên dịch kết nối các chương trình nguồn bằng các ngôn ngữ cấp cao với phần cứng cơ bản. Một trình biên dịch yêu cầu:

  1. Xác định tính chính xác của cú pháp của chương trình
  2. Tạo mã đối tượng chính xác và hiệu quả
  3. Thời gian tổ chức
  4. Định dạng đầu ra theo quy ước của trình biên dịch chương trình hợp ngữ và / hoặc trình liên kết.
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.