Thiết kế trình biên dịch là gì? Các loại, Công cụ xây dựng, Ví dụ
⚡ Tóm tắt thông minh
Các giai đoạn của trình biên dịch mô tả sáu giai đoạn chuyển đổi mã nguồn thành mã máy: phân tích từ vựng, phân tích cú pháp, phân tích ngữ nghĩa, tạo mã trung gian, tối ưu hóa mã và tạo mã, được hỗ trợ bởi quản lý bảng ký hiệu và xử lý lỗi.
Các giai đoạn của thiết kế trình biên dịch là gì?
A Trình biên dịch Trình biên dịch hoạt động qua nhiều giai đoạn, và mỗi giai đoạn biến đổi chương trình nguồn từ dạng biểu diễn này sang dạng biểu diễn khác. Mỗi giai đoạn nhận đầu vào từ giai đoạn trước đó và đưa đầu ra của nó cho giai đoạn tiếp theo của trình biên dịch. Có 6 giai đoạn trong một trình biên dịch. Mỗi giai đoạn này giúp chuyển đổi ngôn ngữ cấp cao thành mã máy. Các giai đoạn của trình biên dịch là:
- Phân tích từ vựng
- Phân tích cú pháp
- Phân tích ngữ nghĩa
- Trình tạo mã trung gian
- Code tối ưu hóa
- Code máy phát điện
Các giai đoạn của trình biên dịch
Tất cả các giai đoạn này đều chuyển đổi mã nguồn bằng cách chia nó thành các token, tạo cây phân tích cú pháp và tối ưu hóa mã nguồn thông qua các giai đoạn khác nhau.
Giai đoạn 1: Phân tích từ vựng
Phân tích từ vựng là giai đoạn đầu tiên, khi trình biên dịch quét mã nguồn. Quá trình này có thể được thực hiện từ trái sang phải, từng ký tự một, và nhóm các ký tự này thành các token.
Tại đây, luồng ký tự từ chương trình nguồn được nhóm lại thành các chuỗi có ý nghĩa bằng cách xác định các token. Nó thực hiện việc nhập các token tương ứng vào bảng ký hiệu và chuyển token đó đến giai đoạn tiếp theo.
Các chức năng chính của giai đoạn này là:
- Xác định các đơn vị từ vựng trong mã nguồn.
- Phân loại các đơn vị từ vựng thành các lớp như hằng số, từ khóa dành riêng và nhập chúng vào các bảng khác nhau. Chương trình sẽ bỏ qua các chú thích trong mã nguồn.
- Xác định một từ không thuộc ngôn ngữ đó.
Ví dụ: x = y + 10
| Mã thông báo | Kiểu |
|---|---|
| X | định danh |
| = | Toán tử chuyển nhượng |
| Y | định danh |
| + | Toán tử bổ sung |
| 10 | Con số |
Giai đoạn 2: Phân tích cú pháp
Phân tích cú pháp là quá trình khám phá cấu trúc trong mã nguồn. Nó xác định xem văn bản có tuân theo định dạng mong đợi hay không. Mục tiêu chính của giai đoạn này là để đảm bảo mã nguồn do lập trình viên viết ra là chính xác.
Phân tích cú pháp dựa trên các quy tắc của ngôn ngữ lập trình cụ thể bằng cách xây dựng cây phân tích cú pháp với sự trợ giúp của các token. Nó cũng xác định cấu trúc của ngôn ngữ nguồn và ngữ pháp hoặc cú pháp của ngôn ngữ đó.
Dưới đây là danh sách các nhiệm vụ được thực hiện trong giai đoạn này:
- Lấy các từ khóa từ bộ phân tích từ vựng.
- Kiểm tra xem biểu thức đó có đúng cú pháp hay không.
- Hãy báo cáo tất cả các lỗi cú pháp.
- Xây dựng một cấu trúc phân cấp được gọi là cây phân tích cú pháp.
Ví dụ
Bất kỳ định danh/số nào cũng là một biểu thức. Nếu x là một định danh và y+10 là một biểu thức, thì x = y+10 là một mệnh đề. Hãy xem xét cây phân tích cú pháp cho ví dụ sau:
(a+b)*c
Trong cây phân tích cú pháp:
- Nút bên trong: bản ghi có một trường toán tử và hai trường dành cho các phần tử con.
- Lá: bản ghi có từ 2 trường trở lên; một trường dành cho mã thông báo và các thông tin khác về mã thông báo đó.
- Hãy đảm bảo các thành phần của chương trình được kết hợp với nhau một cách có ý nghĩa.
- Thu thập thông tin kiểu dữ liệu và kiểm tra tính tương thích của kiểu dữ liệu.
- Việc kiểm tra toán hạng được cho phép bởi ngôn ngữ nguồn.
Giai đoạn 3: Phân tích ngữ nghĩa
Phân tích ngữ nghĩa kiểm tra tính nhất quán ngữ nghĩa của mã. Nó sử dụng cây cú pháp của giai đoạn trước cùng với bảng ký hiệu để xác minh rằng mã nguồn đã cho có nhất quán về mặt ngữ nghĩa hay không. Nó cũng kiểm tra xem mã có truyền tải ý nghĩa phù hợp hay không.
Bộ phân tích ngữ nghĩa sẽ kiểm tra các lỗi như không khớp kiểu dữ liệu, toán hạng không tương thích, hàm được gọi với các đối số không hợp lệ, biến chưa được khai báo, v.v.
Các chức năng của giai đoạn phân tích ngữ nghĩa bao gồm:
- Giúp bạn lưu trữ thông tin kiểu dữ liệu đã thu thập và lưu vào bảng ký hiệu hoặc cây cú pháp.
- Cho phép bạn thực hiện kiểm tra kiểu dữ liệu.
- Trong trường hợp không khớp kiểu dữ liệu, khi không có quy tắc sửa lỗi kiểu dữ liệu chính xác nào đáp ứng được thao tác mong muốn, thì sẽ hiển thị lỗi ngữ nghĩa.
- Thu thập thông tin kiểu dữ liệu và kiểm tra tính tương thích của kiểu dữ liệu.
- Kiểm tra xem ngôn ngữ nguồn có cho phép các toán hạng đó hay không.
Ví dụ
float x = 20.2; float y = x*30;
Trong đoạn mã trên, bộ phân tích ngữ nghĩa sẽ chuyển đổi kiểu dữ liệu của số nguyên 30 thành số thực 30.0 trước khi thực hiện phép nhân.
Giai đoạn 4: Trung cấp Code Thế hệ
Sau khi giai đoạn phân tích ngữ nghĩa kết thúc, trình biên dịch sẽ tạo ra mã trung gian cho máy đích. Mã này thể hiện một chương trình cho một số tác vụ cụ thể.tracmáy t.
Mã trung gian nằm giữa ngôn ngữ cấp cao và ngôn ngữ cấp máy. Mã trung gian này cần được tạo ra theo cách dễ dàng dịch sang mã máy đích.
Chức năng của trung gian Code thế hệ:
- Nó nên được tạo ra từ biểu diễn ngữ nghĩa của chương trình nguồn.
- Chứa các giá trị được tính toán trong quá trình dịch thuật.
- Giúp bạn dịch mã trung gian sang ngôn ngữ đích.
- Cho phép bạn duy trì thứ tự ưu tiên của ngôn ngữ nguồn.
- Nó chứa đúng số lượng toán hạng của lệnh.
Ví dụ
Ví dụ:
total = count + rate * 5
Mã trung gian được tạo ra bằng phương pháp mã địa chỉ như sau:
t1 := int_to_float(5)
t2 := rate * t1
t3 := count + t2
total := t3
Giai đoạn 5: Code Tối ưu hóa
Giai đoạn tiếp theo là tối ưu hóa mã trung gian. Giai đoạn này loại bỏ các dòng mã không cần thiết và sắp xếp lại trình tự các câu lệnh để tăng tốc độ thực thi chương trình mà không lãng phí tài nguyên. Mục tiêu chính của giai đoạn này là cải thiện mã trung gian để tạo ra mã chạy nhanh hơn và chiếm ít không gian hơn.
Các chức năng chính của giai đoạn này là:
- Nó giúp bạn thiết lập sự cân bằng giữa tốc độ thực thi và tốc độ biên dịch.
- Cải thiện thời gian chạy của chương trình mục tiêu.
- Tạo ra mã được tối giản hóa nhưng vẫn ở dạng trung gian.
- Loại bỏ mã không thể truy cập và xóa các biến không sử dụng.
- Loại bỏ các câu lệnh không thay đổi khỏi vòng lặp.
Ví dụ: Hãy xem xét đoạn mã sau:
a = intofloat(10)
b = c * a
d = e + b
f = d
Có thể trở thành:
b = c * 10.0
f = e + b
Giai đoạn 6: Code Thế hệ
Code Giai đoạn tạo mã là giai đoạn cuối cùng của trình biên dịch. Nó nhận đầu vào từ giai đoạn tối ưu hóa mã và tạo ra mã trang hoặc mã đối tượng. Mục tiêu của giai đoạn này là phân bổ bộ nhớ và tạo ra mã máy có thể di chuyển được.
Nó cũng phân bổ các vị trí bộ nhớ cho các biến. Các lệnh trong mã trung gian được chuyển đổi thành các lệnh máy. Giai đoạn này chuyển đổi mã được tối ưu hóa hoặc mã trung gian thành ngôn ngữ đích.
Ngôn ngữ đích là mã máy. Do đó, tất cả các vị trí bộ nhớ và thanh ghi cũng được chọn và phân bổ trong giai đoạn này. Mã được tạo ra trong giai đoạn này sẽ được thực thi để nhận đầu vào và tạo ra đầu ra mong muốn.
Ví dụ
Công thức a = b + 60.0 có thể được dịch sang các thanh ghi như sau:
MOVF a, R1 MULF #60.0, R2 ADDF R1, R2
Quản lý bảng biểu tượng
Bảng ký hiệu chứa một bản ghi cho mỗi định danh với các trường dành cho các thuộc tính của định danh đó. Thành phần này giúp trình biên dịch dễ dàng tìm kiếm bản ghi định danh và truy xuất nó một cách nhanh chóng. Bảng ký hiệu cũng hỗ trợ quản lý phạm vi. Bảng ký hiệu và trình xử lý lỗi tương tác với tất cả các giai đoạn, và bảng ký hiệu được cập nhật tương ứng.
Quy trình xử lý lỗi
Trong quá trình thiết kế trình biên dịch, lỗi có thể xảy ra ở tất cả các giai đoạn được nêu dưới đây:
- Bộ phân tích từ vựng: Các mã thông báo viết sai chính tả.
- Công cụ phân tích cú pháp: Thiếu dấu ngoặc đơn.
- Trình tạo mã trung gian: Các toán hạng không khớp nhau cho một toán tử.
- Code Trình tối ưu hóa: Khi câu lệnh không thể truy cập được.
- Code Generator: Khi bộ nhớ đầy hoặc các thanh ghi cần thiết không được cấp phát.
- Bảng ký hiệu: Lỗi do khai báo nhiều định danh trùng lặp.
Các lỗi thường gặp nhất là chuỗi ký tự không hợp lệ trong quá trình quét, chuỗi mã thông báo không hợp lệ trong kiểu dữ liệu, lỗi phạm vi và lỗi phân tích ngữ nghĩa.
Lỗi có thể xảy ra ở bất kỳ giai đoạn nào nêu trên. Sau khi phát hiện lỗi, giai đoạn đó cần xử lý lỗi để tiếp tục quá trình biên dịch. Các lỗi này cần được báo cáo cho trình xử lý lỗi, trình xử lý này sẽ xử lý lỗi để thực hiện quá trình biên dịch. Thông thường, các lỗi được báo cáo dưới dạng một thông báo.



