T ì h biê dị hBài 1 Tổ Bài 1 – Tổng quan Các chủ đề chính • Thế nào là trình biên dịch • Sự cần thiết của trình biên dịch • Những yêu cầu đối với một trình biên dịch • Tại sao nghiên cứu
Trang 1T ì h biê dị h
Bài 1 Tổ Bài 1 – Tổng quan
Các chủ đề chính
• Thế nào là trình biên dịch
• Sự cần thiết của trình biên dịch
• Những yêu cầu đối với một trình biên dịch
• Tại sao nghiên cứu trình biên dịch
• Cấu trúc chung của trình biên dịch
– Trình biên dịch 2 chuyến
– Trình biên dịch 3 chuyến
– Các kỹ thuật dịch
• Các pha của trình biên dịchp ị
– Phân tích từ vựng
– Phân tích cú pháp
– Phân tích ngữ nghĩa Phân tích ngữ nghĩa
– Phát sinh mã trung gian
– Tối ưu mã
– Phát sinh mã
2
Phát sinh mã
• Các công cụ xây dựng trình biên dịch
• Các chương trình hỗ trợ
Trang 2Thế nào là trình biên dịch
• Trình biên dịch là một phần mềm có nhiệm vụ chuyển một chương trình, được viết bởi ngôn ngữ nguồn, sang chương trình tương đương, biểu diễn bởi ngôn ngữ đích.
– Ngôn ngữ nguồn thường là các ngôn ngữ cấp cao
– Ngôn ngữ đích: thường là ngôn ngữ cấp thấp (mã máy hay
mã hợp ngữ)
• Thông báo các lỗi của chương trình nguồn, được phát hiện trong quá trình dịch.
3
Ví dụ: Thế giới của con người và máy tính
1 Mã nguồn được viết bằng ngôn ngữ cấp cao.
2 Thông thường được dịch sang mã hợp ngữ của hệ thống.
3 Trình biên dịch hợp ngữ (của hệ thống) tiếp tục dịch sang
3 Trình biên dịch hợp ngữ (của hệ thống) tiếp tục dịch sang
mã máy.
7F45 4C46 0102 0100 0000 0000 0000 0000 0002 0002 0000 0001 0001 04A0
0000 0034 0000 1474 0000 0000 0034 0020 0005 0028 001B 0019 0000 0006
0000 0034 0001 0034 0000 0000 0000 00A0 0000 00A0 0000 0005 0000 0000
int main(void) {
int a b s;
Mã nguồn viết
bằng ngôn ngữ C
Mã hợp ngữ (Hệ thống SPARC)
Mã máy
0000 0000 0000 0001 0000 0000 0001 0000 0000 0000 0000 0782 0000 0782
0000 01A4 0000 0007 0001 0000 0000 0002 0000 0838 0002 0838 0000 0000
0000 00B8 0000 0000 0000 0007 0000 0000 2F75 7372 2F6C 6962 2F6C 642E 736F 2E31 0000 0000 0000 0017 0000 0016 0000 0000 0000 0001 0000 0002
0000 0000 0000 0003 0000 0004 0000 0006 0000 0007 0000 0009 0000 0000
0000 000A 0000 000C 0000 000D 0000 000E 0000 0000 0000 0000 0000 000F
0000 0010 0000 0000 0000 0011 0000 0012 0000 0013 0000 0015 0000 0000
int a, b, s;
printf("Enter two integers: ");
scanf("%d %d", &a, &b);
s = a*a + b*b;
printf("%d^2 + %d^2
= %d\n", a, b, s);
0000 0000 0000 0000 0000 000B 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0002 0924 0000 0004
1100 0014 0000 000A 0001 0782 0000 0000 1100 000C 0000 0011 0002 07A4
0002 081C 0000 0000 1200 0000 0000 0038 0000 0000 0000 0000 2000 0000
0000 004E 0002 0928 0000 0000 1100 0014 0000 0053 0002 0838 0000 0000
1100 000F 0000 005C 0002 0924 0000 0004 2100 0014 0000 0064 0002 0810
0002 0828 0000 0000 1200 0000 0000 008 0002 0 E0 0000 0000 1200 0000
%d\ , a, b, s);
}
4
0002 0828 0000 0000 1200 0000 0000 0087 0002 07E0 0000 0000 1200 0000
0000 008C 0002 090C 0000 0000 1100 0013 0000 0093 0002 07EC 0000 0000
1200 0000 0000 0099 0001 0714 0000 001C 1200 000A 0000 009F 0001 0730
0000 0014 1200 000B 0000 00A5 0001 04A0 0000 0074 1200 0009 0000 00AC
0000 0000 0000 0000 2000 0000 0000 00C4 0001 0748 0000 0004 1100 000C
0000 00D1 0001 0634 0000 007C 1200 0009 005F 656E 7669 726F 6E00 5F65
7465 7874 005F 5052 4F43 4544 5552 455F 4C49 4E4B 4147 455F 5441 424C
Trang 3Sự cần thiết của trình biên dịch
• Những khó khăn khi sử dụng ngôn ngữ cấp thấp (hợp ngữ hay ngôn ngữ máy)
– Viết mã nhiều, kém thân thiện
– Hỗ trợ tìm lỗi kém
– Khả năng bảo trì thấp
– Trở ngại trong việc đọc và hiểu chương trình
S ra đời của ngôn ngữ lập trình cấp cao à trình biên dịch
• Sự ra đời của ngôn ngữ lập trình cấp cao và trình biên dịch
đã giải phóng những tiềm năng to lớn trong việc viết
chương trình.
• Hợp ngữ vẫn được sử dụng trong một số ít trường hợp: – Truy xuất đến các tài nguyên cấp thấp
5
uy uất đế các tà guyê cấp t ấp
– Các đoạn mã tương đối nhỏ, thời gian thực thi nhanh
Những yêu cầu đối với một trình biên dịch
• Trình biên dịch bản thân phải là một phần mềm không chứa lỗi.
• Mã đích được phát sinh phải hoàn toàn tương đương với mã nguồn khi thực thi
với mã nguồn khi thực thi.
• Trình biên dịch cần phải khả chuyển (hỗ trợ biên dịch riêng)
riêng).
• Thời gian biên dịch nhanh.
• Thời gian thực thi mã được biên dịch nhanh.
• Kết xuất thông báo lỗi chính xác và có thông điệp rõ
6
ràng.
Trang 4Tại sao nghiên cứu trình biên dịch
• Thế giới riêng trong ngành Khoa học máy tính
• Để xây dựng một trình biên dịch, cần hội tụ nhiều kiến thức: – Trí tuệ nhân tạo: các giải thuật máy học, heuristic, …
– Cấu trúc dữ liệu và giải thuật: kỹ thuật băm, các giải thuật đồ thị qui hoạch động
thị, qui hoạch động, …
– Các mô hình tính toán, lý thuyết ngôn ngữ hình thức, toán rời rạc, lý thuyết giàn trong phân tích, … ý y g g p
– Kiến trúc máy tính: quản lý đa luồng, quản lý tập chỉ thị lệnh, phân cấp bộ nhớ, …
– Công nghệ phần mềm
– Xử lý song song
Lý thuyết về ngôn ngữ lập trình (truyền tham số phạm vi của
7
– Lý thuyết về ngôn ngữ lập trình (truyền tham số, phạm vi của biến, quản lý bộ nhớ, con trỏ, …)
Cấu trúc chung của trình biên dịch
Trình biên dịch
Chương trình
nguồn Chương trình đích quảKết
Lỗi Dữ liệu nhập
8
Trang 5Trình biên dịch 2 chuyến (2-pass)
Ch ế t ướ
Bảng danh biểu
Chuyến trước (front-end)
Mã
nguồn IR Chuyến sau (back-end) đíchMã
• IR (Intermediate Representation): Mã trung gian
Lỗi
IR (Intermediate Representation): Mã trung gian.
• Chuyến trước: còn được gọi là phần Phân tích
– Chuyển mã nguồn (hợp lệ) sang mã trung gianChuyển mã nguồn (hợp lệ) sang mã trung gian
– Tập hợp các thông tin và lưu vào bảng danh biểu
• Chuyến sau: còn được gọi là phần Tổng hợp
9
Chuyến sau: còn được gọi là phần Tổng hợp
– Chuyển mã trung gian sang mã đích
Sự ngụy biện!?!
Fortran Front Fortran Front
Fortran
code
C++
Front
end
Front
Back end
SPARC system
Fortran code C++
Front end Front
Back end
SPARC system
IRs
code
Basic
code
end
Front
end
Back end
Pentium
code
Basic code
end
Front end
Back end Back
Pentium system PowerPC ADA
code
Front
end
Back end
PowerPC system ADA
code
Front end
Back end
PowerPC system
• Xây dựng (m n) trình biên dịch từ (m + n) thành phần?
• Câu trả lời: Phải tìm được mã trung gian (IR) thỏa:
Mã hóa được toàn bộ tri thức của từng chuyến trước
– Mã hóa được toàn bộ tri thức của từng chuyến trước.
– Biểu diễn được mọi đặc tính trong một bộ mã trung gian
– Xử lý được mọi đặc trưng trong từng chuyến sau.
10
• Chỉ đạt thành công hạn chế với mã trung gian mức thấp
– Ứng dụng ở mức (1 + n) với ngôn ngữ như Java
Trang 6Trình biên dịch 3 chuyến (3-pass)
Bảng danh biểu
Chuyến trước (front-end)
Mã
nguồn IR Chuyến giữa Chuyến sau (back-end) đíchMã
(middle-end)
IR
Lỗi
Tối ưu 1 IR Tối ưu 2 IR IR Tối ưu n
IR Tối ưu 1 Tối ưu 2 … Tối ưu n
Lỗi
11 Lỗi
Các kỹ thuật dịch
Biên dịch Thông dịch Kỹ thuật lai Biên dịch
(Compiler)
Thông dịch (Interpreter)
Kỹ thuật lai (Hybrid)
Cổ điển Just-In-Time
Mã nguồn
T ì h biê dị h
Mã nguồn Dữ liệu
Mã nguồn
Trình
Mã nguồn
Trình biên dịch
(Chuyến trước)
Trình thông dịch (máy ảo)
Trình
biên dịch (Chuyến trước)
Mã trung gian
Mã trung gian Dữ liệu Kết quả
Mã
máy Dữ liệu Trình biên dịch
(Chuyến sau i)
Trình thông dịch
(máy ảo i)
Máy tính
Mã máy i
12 Kết quả
Kết quả
Kết quả
Máy tính i
Trang 7Các pha của
Chương trình nguồn Phân tích từ vựng
Phân tích cú pháp
Luồng token
Phân tích ngữ nghĩa
Cây phân tích cú pháp
Cây cú pháp trừu tượng
Bả d h biể
Phát sinh mã trung gian
Cây cú pháp trừu tượng
Mã trung gian
Bảng danh biểu
ú í
Tối ưu mã trung gian
há h ã đí h
Mã trung gian
chú thích
Phát sinh mã đích
Mã đích Tối ưu mã đích
13
Mã đích
Phân tích từ vựng
(Lexical analysis/Scanning)
• Đọc luồng ký tự của chương trình nguồn Đọc luồng ký tự của chương trình nguồn.
• Nhóm các ký tự thành các lexeme (có nghĩa).
• Với mỗi lexeme, bộ phân tích từ vựng:
– Tạo token tương ứng và gửi cho bộ phân tích cú pháp.
– Lưu thông tin vào bảng danh biểu
• Loại trừ các khoảng trắng (tab, blank, comment, …).
• Kiểm tra lỗi từ vựng.
14
Trang 8position = initial + rate * 60
Bộ phân tích từ vựng
id, 1 = id, 2 + id, 3 * 60
Bảng danh biểu
15
g
Phân tích cú pháp
(Syntax analysis/Parsing)
• Sử dụng token để xây dựng cây phân tích cú pháp (parse Sử dụng token để xây dựng cây phân tích cú pháp (parse tree).
Cây phân tích cú pháp mô tả cấu trúc văn phạm của luồng – Cây phân tích cú pháp mô tả cấu trúc văn phạm của luồng
token.
Văn phạm phi ngữ cảnh (contex free grammar CFG) được – Văn phạm phi ngữ cảnh (contex-free grammar – CFG) được
sử dụng để mô tả cấu trúc văn phạm của các ngôn ngữ lập trình
• Kiểm tra lỗi cú pháp.
16
Trang 9Văn phạm phi ngữ cảnh
• Gọi văn phạm phi ngữ cảnh G = (S, N, T, P), với:
– S: Ký hiệu bắt đầu của văn phạm.ý ệ p ạ
– N: Tập các ký hiệu không kết thúc
– T: tập các ký hiệu kết thúc
– P: tập các luật sinh có dạng A B với A N và B N T
• Ví dụ: ụ
1 <assign> id = <expr>
2 <expr> <expr> + <term> | <term>
3 <term> <term> * <fact> | <fact>
4 <fact> id | num
17
id, 1 = id, 2 + id, 3 * 60
Bộ phân tích cú pháp
<id, 1> = <expr>
<expr> + <term>
<id, 1> +
<id, 2> *
<expr> + <term>
<term> <term> * <fact> <id, 3> 60
<fact>
<id 2>
<fact>
<id 3>
60
18
<id, 2> <id, 3>
Cây phân tích cú pháp Cây cú pháp trừu tượng
Trang 10Phân tích ngữ nghĩa
(Semantic analysis)
• Sử dụng cây cú pháp trừu tượng và bảng danh biểu để
kiểm tra “ngữ nghĩa”.
– Biến sử dụng đã được khai báo?
• Tập hợp thông tin, lưu trữ lên cây cú pháp và/hoặc bảng danh biểu.
• Tiến hành kiểm tra kiểu (type checking):
• Tiến hành kiểm tra kiểu (type checking):
– Toán tử có phù hợp với toán hạng
– Chỉ số mảng có phải là kiểu số nguyên?Chỉ số mảng có phải là kiểu số nguyên?
– Kiểu của toán hạng bên trái và phải phép gán có phù hợp? – …
19
• Thực hiện chuyển kiểu (coercion)
=
<id 1> +
<id, 1> +
<id, 2> *
<id, 3> 60
=
Bộ phân tích ngữ nghĩa
<id, 1> +
<id, 2> *
<id 3> int2float
Chuyển kiểu
20
<id, 3> int2float
60
Trang 11Phát sinh mã trung gian
(Intermediate Code Generation)
• Trình biên dịch có thể phát sinh một hoặc nhiều biểu diễn Trình biên dịch có thể phát sinh một hoặc nhiều biểu diễn trung gian.
– Cây cú pháp trừu tượng (high-level IR).y p p g ( g )
– Mã 3 địa chỉ, mã máy ngăn xếp (low-level IR).
• IR cấp thấp giống như chương trình được viết bằng ngôn p p g g g g g ngữ của một máy ảo, có ưu điểm:
– Dễ dàng sản sinh
– Dễ dàng dịch sang mã đích
– Hoặc có thể chạy trực tiếp trên máy ảo
21
Mã 3 địa chỉ
(Three Address Code)
• Tương tự như các câu lệnh hợp ngữ Tương tự như các câu lệnh hợp ngữ.
• Chứa tối đa 3 toán hạng trên một chỉ thị.
• Mỗi toán hạng đóng vai trò như một thanh ghi.
• Chứa tối đa một toán tử bên vế phải của chỉ thị.
Thứ tự các chỉ thị sẽ cố định thứ tự các toán tử được thực thi
• Khi cần thiết, các tên tạm (temporary name) có thể được
sinh ra để chứa giá trị trung gian khi tính toán.
22
Trang 12Ví dụ: Biểu diễn trung gian cho biểu thức x – 2 y
23
=
<id, 1> +
id 2 *
<id, 2> *
<id, 3> int2float
60
Bộ phát sinh mã trung gian
t1 = int2float(60) t2 = id3 * t1
t3 = id2 + t2 id1 = t3
24
Trang 13Tối ưu mã
(Code Optimization)
• Cải tiến mã trung gian để cho ra mã đích “tốt hơn”.
• “Tốt hơn”: tùy trường hợp cụ thể
– Nhanh hơn
– Mã ngắn hơn
– Mã đích tiêu hao ít năng lượng hơn
• Các trình biên dịch có pha “tối ưu mã” gọi là “optimizing compiler” mất nhiều thời gian hơn.
• Có 2 loại tối ưu, liên quan đến phần cứng
– Phụ thuộc phần cứng: tối ưu trên mã đích
25
– Độc lập phần cứng: tối ưu trên mã trung gian
Tối ưu mã …
• Bộ tối ưu mã phải thỏa các tiêu chí sau:
Mã được tối ưu phải đúng nghĩa là duy trì ngữ nghĩa của – Mã được tối ưu phải đúng, nghĩa là duy trì ngữ nghĩa của chương trình được biên dịch
Sự tối ưu phải cải tiến được sự thực thi của mã ban đầu – Sự tối ưu phải cải tiến được sự thực thi của mã ban đầu
Với hệ thống nhúng: Tối thiểu hóa kích thước mã phát sinh.
Với thiết bị di động: Tối thiểu hóa năng lượng sử dụng
Với thiết bị di động: Tối thiểu hóa năng lượng sử dụng.
Tăng tốc độ thực thi.
Thời gian cho quá trình tối ưu mã là hợp lý
– Thời gian cho quá trình tối ưu mã là hợp lý
– Duy trì chi phí phát triển cũng như bảo trì toàn hệ thống biên dịch ở mức hợp lý
26
dịch ở mức hợp lý
Trang 14Bộ phát sinh mã
(Code Generation)
• Bộ phát sinh mã:
– Nhập: IR của chương trình nguồn
– Xuất: mã của ngôn ngữ đích
• Ngôn ngữ đích:
– Mã máy:
Mỗi chỉ thị của mã trung gian được dịch thành dãy các mã máy.
Thanh ghi/bộ nhớ thay thế các biến trong chương trình.
Tận dụng khả năng sử dụng thanh ghi.
– Mã dạng hợp ngữ:
Tiếp tục sử dụng trình biên dịch hợp ngữ để dịch sang mã máy
27
Tiếp tục sử dụng trình biên dịch hợp ngữ để dịch sang mã máy.
t1 = int2float(60) t2 = id3 * t1
t3 = id2 + t2 id1 = t3
Bộ tối ưu mã
t1 = id3 * 60.0 id1 = id2 + t1
Bộ phát sinh mã
28
Trang 15Bảng danh biểu
(Symbol Tables)
• Bản chất của trình biên dịch là
– Ghi nhận các danh biểu được sử dụng trong chương trình – Tập hợp các thông tin về những thuộc tính của danh biểu:
Vùng nhớ được cấp phát
Vùng nhớ được cấp phát.
Kiểu dữ liệu.
Phạm vi ạ
Số lượng tham số truyền, kiểu tham số, kiểu truyền, kiểu trả về,
… (nếu danh biểu là tên chương trình con).
• Bảng danh biểu là cấu trúc dữ liệu gồm nhiều bản ghi
chứa:
ể
29
– Tên danh biểu.
– Các trường (fields) tương ứng với các thuộc tính.
Xử lý lỗi
(Error Handling)
• Các lỗi chủ yếu được tìm và xử lý trong chuyến trước Các lỗi chủ yếu được tìm và xử lý trong chuyến trước.
• Phân tích từ vựng:
Cá ký t ó hì h thà h ê t k ?
– Các ký tự có hình thành nên token?
• Phân tích cú pháp:
– Luồng token có vi phạm luật cú pháp của ngôn ngữ?
• Phân tích ngữ nghĩa:
– Xảy ra: <tên mảng> + <tên thủ tục>?
– Chỉ mục mảng có phải là số nguyên?
30
Trang 16Các công cụ xây dựng trình biên dịch
• Lợi ích của việc sử dụng các công cụ:
– Tránh những chi tiết phức tạp của giải thuật.g p ạp g ậ
– Dễ dàng tích hợp kết quả thành phần vào trình biên dịch
• Một số công cụ thông dụng:
– Scanner generator: phát sinh bộ phân tích từ vựng từ những
mô tả token bằng biểu thức chính qui
mô tả token bằng biểu thức chính qui.
– Parser generator: phát sinh bộ phân tích cú pháp từ những
mô tả văn phạm của ngôn ngữ nguồn
mô tả văn phạm của ngôn ngữ nguồn
– Code-generator generator: tạo bộ phát sinh mã, dựa trên tập
luật dịch chỉ thị của mã trung gian sang ngôn ngữ đích
31
luật dịch chỉ thị của mã trung gian sang ngôn ngữ đích
– …
Các chương trình hỗ trợ
Chương trình nguồn
Bộ tiền xử lý
Chương trình nguồn (đã hiệu chỉnh) Trình biên dịch
Mã hợp ngữ Trình biên dịch hợp ngữ
Mã hợp ngữ
ố
Bộ liên kết/Bộ nạp
Mã máy khả tái định vị • Tập tin mã đối tượng khả tái định vị
• Hàm thư viện
32
Bộ liên kết/Bộ nạp
Mã máy đích
Trang 17Các chương trình hỗ trợ
• Bộ tiền xử lý (Preprocessor)
– “Bung” các macro
– Kết nối các file nguồn được lưu trữ riêng
• Trình biên dịch hợp ngữ (Assembler) p g ( )
– Phát sinh mã máy đích từ mã hợp ngữ
• Bộ liên kết (Linker) ộ ( )
– Liên kết các file mã khả tái định vị được biên dịch riêng – Kết nối địa chỉ cụ thể của các hàm thư viện hoặc hàm hệ ị ụ ệ ặ ệ thống với những lời gọi hàm trong chương trình
• Bộ nạp (Loader): tải các file mã đối tượng vào bộ nhớ,
33
chuẩn bị thực thi chương trình.