1. Trang chủ
  2. » Luận Văn - Báo Cáo

Xây dựng chương trình tự động sinh mã trung gian và tối ưu mã

105 15 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 105
Dung lượng 743,7 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Hồ Chí Minh Tháng 7 năm 2003 Từ khóa: Trình biên dịch, bộ phân tích từ vựng, từ, sơ đồ dịch, bộ phân tích hướng đến cú pháp, bộ phân tích cú pháp, bộ phân tích cú pháp từ trên xuống, b

Trang 1

ĐẠI HỌC QUỐC GIA TP HỒ CHÍ MINH

TRƯỜNG ĐẠI HỌC BÁCH KHOA KHOA CÔNG NGHỆ THÔNG TIN

-

Luận Văn Cao Học

Đề tài

XÂY DỰNG CHƯƠNG TRÌNH TỰ ĐỘNG SINH MÃ

TRUNG GIAN VÀ TỐI ƯU MÃ

TP HỒ CHÍ MINH, tháng 07 năm 2003

Giáo viên hướng dẫn : PGS.TS Phan Thị Tươi Học viên thực hiện : Tạ Duy Công Chiến Khóa : 11

Trang 2

CÔNG TRÌNH ĐƯỢC HOÀN THÀNH TẠI TRƯỜNG ĐẠI HỌC BÁCH KHOA ĐẠI HỌC QUỐC GIA TP HỒ CHÍ MINH

Cán bộ hướng dẫn khoa học :

PGS.TS PHAN THỊ TƯƠI

Cán bộ chấm nhận xét 1 :

Cán bộ chấm nhận xét 2 :

Luận án cao học được bảo vệ tại HỘI ĐỒNG CHẤM BẢO VỆ LUẬN ÁN CAO HỌC TRƯỜNG ĐẠI HỌC BÁCH KHOA TP HỒ CHÍ MINH ngày … tháng … năm 2003

Trang 3

ĐẠI HỌC QUỐC GIA TP HỒ CHÍ MINH

TRƯỜNG ĐẠI HỌC BÁCH KHOA CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM Độc Lập -Tự Do - Hạnh Phúc

- -

NHIỆM VỤ LUẬN ÁN CAO HỌC

Họ và tên học viên: TẠ DUY CÔNG CHIẾN Phái: Nam

Ngày tháng năm sinh: 06-11-1965 Nơi sinh: LONG AN

Chuyên ngành: CÔNG NGHỆ THÔNG TIN

I- TÊN ĐỀ TÀI: XÂY DỰNG CHƯƠNG TRÌNH TỰ ĐỘNG SINH MÃ

TRUNG GIAN VÀ TỐI ƯU MÃ

II- NHIỆM VỤ VÀ NỘI DUNG:

III- NGÀY GIAO NHIỆM VỤ (Ngày bảo vệ đề cương):

IV- NGÀY HOÀN THÀNH NHIỆM VỤ (Ngày bảo vệ luận án tốt nghiệp):

V- HỌ VÀ TÊN CÁN BỘ HƯỚNG DẪN: PGS.TS PHAN THỊ TƯƠI

Trang 4

PHÒNG QLKH-SĐH CHỦ NHIỆM NGÀNH

Trang 5

LỜI CẢM ƠN

Tôi chân thành cảm ơn Cô – PGS TS Phan Thị Tươi, Giáo viên hướng dẫn, đã tận tình chỉ bảo, nhiệt tình hướng dẫn tôi hoàn thành Luận văn cao học này

Chân thành cảm ơn Quý Thầy Cô - giảng viên trường Đại học Bách Khoa Tp Hồ Chí Minh, trường Đại học Khoa học tự nhiên Tp Hồ Chí Minh đã tận tình giảng dạy, giúp đỡ tôi trong quá trình học tập

Chân thành cảm ơn TS , TS , TS đã giúp chúng tôi rất nhiều bằng những góp ý, chỉ dẫn và các tài liệu quý giá trong quá trình thực hiện Luận văn này

Tp Hồ Chí Minh, ngày …… tháng …… năm 2003 Tạ Duy Công Chiến

Trang 6

Xây Dựng Chương Trình Tự Động Sinh Mã Trung Gian và

Tối Ưu Mã

Tạ Duy Công Chiến Đại Học Bách Khoa TP Hồ Chí Minh

Tháng 7 năm 2003

Từ khóa:

Trình biên dịch, bộ phân tích từ vựng, từ, sơ đồ dịch, bộ phân tích hướng đến cú pháp, bộ phân tích cú pháp, bộ phân tích cú pháp từ trên xuống, bộ phân tích cú pháp từ dưới lên, định nghĩa hướng đến cú pháp, định nghĩa thuộc tính, thuộc tính tổng hợp, thuộc tính kế thừa, ngữ nghĩa, tối ưu hóa, khối cơ bản, dòng điều khiển, dòng dữ liệu, chi phối, đồ thị dòng, biến sống, đồ thị có hướng không vòng, đồ thị giao thoa, thanh ghi ký hiệu, lập thời biểu, ống lệnh, đồ thị độc lập, dừng

Tóm tắt:

Sinh mã và tối ưu mã là các giai đoạn quan trọng của trình biên dịch Trong mô hình phân tích tổng hợp của một trình biên dịch, biên dịch phía trước sẽ dịch chương trình nguồn sang dạng biểu diễn trung gian để sau đó sinh ra mã đích Mặc dù chương trình nguồn có thể được biên dịch trực tiếp sang ngôn ngữ máy mà không cần sinh mã trung gian, nhưng một số ưu điểm của việc sinh mã trung gian là:

o Tiết kiệm thời gian khi tạo ra một trình biên dịch cho các máy khác nhau

o Có thể áp dụng bộ tối ưu mã độc lập với máy dích

Việc sinh mã trung gian thường tạo ra một số lệnh dư thừa làm cho

trình biên dịch không hiệu quả Thông qua giai đoạn tối ưu, mã sinh ra sẽ hiệu quả hơn, kích thước mã được thu giảm, chương trình thực thi nhanh hơn

Trang 7

Trong luận văn này, chúng tôi xây dựng một chương trình tự động sinh mã trung gian, cải tiến và thiết kế các giải thuật tối ưu nhằm cải thiện mã trung gian tốt hơn, đánh giá hiệu suất trước và sau khi tối ưu mã Các kết quả này cho thấy tính hiệu quả của các phương pháp giải thuật mà chúng tôi đã xây dựng được.

Trang 8

Building A Program for Automatic Code Generation and

syntax-Abstract:

Code generation and optimization are the important steps in compiler implementation In the analysis-synthesis model of a compiler, the front end translates a source program into an intermediate representation form which the back end generates target code Although a source program can be translated directly into the target language, some benefits of using a machine independent intermediate form are:

o A compiler for a different machine can be create by attaching a back end for the new machine to an exiting front end

o A machine-independent code optimizer can be applied

to the intermediate representation

Trang 9

The task of generating intermediate code usually creates redundant code that makes the compiler less efficient Code optimization will alter the program code to improve the generated code, so more efficient target code can be generated, and speedup program execution or reduce code size

In this thesis, we build a program for automatic code generation, improved and designed optimization algorithms that improve the intermediate code, reduce code size without taking into consideration any properties of the target machine

We also calculate the efficiency of algorithms before and after performing code optimization These results prove that they are be acceptable.

Trang 10

Mục Lục

Chương 1: Đặt vấn đề ……… 1

1.1 Giới thiệu ……… ……… ………… 1

1.2 Tình hình ngiên cứu việc tự động sinh mã trung gian và tối ưu mã trung gian ……… 2

1.3 Mục tiêu đề tài ……… 4

1.4 Phương pháp luận ……… 4

1.5 Các đóng góp của luận văn ……… ……… 6

Chương 2 : Tổng quan về trình biên dịch ……… 8

2.1 Giới thiệu về trình biên dịch ……… 8

2 2 Trình biên dịch trực tiếp cú pháp ……… 8

2.3 Tối ưu mã ………… ……… … 10

Chương 3: Trình biên dịch hướng đến cú pháp …… … 12

3.1 Phân tích từ vựng ……… ……… 12

3.2 Biên dịch hướng đến cú pháp ……… 16

3.3.1 Sinh Mã Trung Gian ……… 23

Chương 4 : Tối ưu mã trung gian … ……… 39

4.1 Tối ưu hóa thanh ghi bằng giải thuật tô màu đồ thị ……41

4.2 Tối ưu hóa bằng lập thời biểu cho các lệnh ……… 62

Chương 5 : Giải thuật và chương trình ……… 77

5.1 Định nghĩa chính qui ……… …… 77

5.2 Văn phạm ngôn ngữ Pascal ………… ……… …… 77

5.3 Các giải thuật xây dựng trình biên dịch hướng đến cú pháp 78 5.4 Sinh mã trung gian … ……….82

Chương 6 : Kết Luận …….……… 91

6.1 Kết luận ……… ………91

6.2 Kết quả đạt được ……… ……….… 91

Trang 11

Tài Liệu Tham Khảo ……….93

Trang 12

Quá trình biên dịch đều phải qua một số giai đoạn nhất định nhằm mục đích là chuyển chương trình của người sử dụng ở ngôn ngữ cấp cao sang chương trình đích ở ngôn ngữ cấp thấp mà máy tính hiểu được thể hiện qua H.1.1

H.1.1 Trình bày khái niệm về trình biên dịch

Khi biên dịch từ chương trình nguồn sang chương trình đích, trình biên dịch đi qua một số giai đoạn sau:

H.1.2 Các giai đoạn của quá trình biên dịch

Qua H.1.2, việc sinh mã trung gian là quá trình không thể thiếu được trong một trình biên dịch Sau khi mã trung gian được sinh ra ở trình biên dịch phía trước, chúng có thể được tối ưu trong bộ tối ưu mã, cũng có thể không cần tối ưu Tuy nhiên một trình biên dịch có thể tối ưu mã thì sẽ làm cho quá trình biên dịch hiệu

Trình biêndịch Chương trình đích (Ngôn ngữ cấp thấp)

Trang 13

Vấn đề sinh mã tối ưu về lý thuyết là rất khó Song trong thực tế chúng ta có thể chọn một số kỹ thuật để tạo mã tốt, nhưng không nhất thiết là tốt nhất Việc cải tiến mã có thể đạt được thông qua một số kỹ thuật biến đổi gọi là tối ưu Trình biên dịch mà áp dụng các biến đổi cải tiến mã gọi là trình biên dịch tối ưu

Đề tài : “Xây dựng chương trình tự động sinh mã trung gian và thực hiện tối ưu mã trung gian” là một trong các quan tâm đó

1.2 Tình hình nghiên cứu việc tự động sinh mã trung gian và tối ưu mã trung gian 1.2.1 Trong nước

Hiện nay các đề tài liên quan đến việc sinh mã và tối ưu hóa mã còn rất ít được nghiên cứu ở các trường đại học cũng như các viện nghiên cứu Một số đề tài tốt nghiệp liên quan đến việc tối ưu mã

- Xây dựng giải thuật tối ưu mã trung gian của trình biên dịch, Lê Hồng Sơn, luận văn tốt nghiệp đại học, 2001 [15]

Tác giã trình bày một số giải thuật tối ưu mã trung gian như: loại bỏ biểu thức con chung, loại bỏ biến quy nạp, thu giảm cường lực

- Tối ưu mã trình biên dịch, Nguyễn Anh Tuấn, luận văn tốt nghiệp cao học,

2002 [14]

Tác giã trình bày một số giải thuật tối ưu mã trung gian như : loại bỏ biểu thức con chung, loại bỏ biến quy nạp, thu giảm cường lực, lan truyền sao chép, tối ưu hóa đại số, tính hiệu suất của các giải thuật

1.2.2 Nước ngoài

Việc tự động sinh mã trung gian và tối ưu mã đã được nghiên cứu rất rộng rãi trên thế giới trong nhiều năm qua đặc biệt là tối ưu mã Riêng đối với quá trình sinh mã trung gian thì hầu như rất ít, chỉ dừng lại ở các giải thuật có sẵn trong các sách giảng dạy đại học Hiện nay đã và đang có rất nhiều đề tài về tối ưu mã mà các giải thuật cố gắng làm cho thời gian biên dịch ngắn hơn và chương trình chạy nhanh hơn, ví dụ như :

Trang 14

- Advanced Compiler - Design and Implemention, Steven S.Muchnick,1997 [20]

Giới thiệu một số giải thuật sinh mã hiệu quả như loại bỏ biểu thức con chung, tô màu đồ thị, lập thời biểu cho các lệnh, loại bỏ mã chết, dịch chuyển mã…

- Code generation for expressions with common subexpressions, Aho, A.V S C Iohnson , and J D UllMan, 1997 [9]

Nhóm nghiên cứu đã đưa ra ngôn ngữ xử lý cây (Twig language) một ngôn ngữ được xây dựng giúp cho quá trinh sinh mã và tối ưu hóa mã Dựa trên ngôn ngữ này, Alfred V.Aho và Steven W.K.Tjiang của AT&T Laboratories đã đưa ra một giải thuật sinh mã dựa trên việc so trùng cây biểu thức và lập trình động

- Efficient Symbolic Analysis for Optimization Compilers [12]

Được nghiên cứu ở trường đại học Florida State University, liên quan đến các vấn đề:

+ Phân tích phụ thuộc dữ liệu

+ Song song hóa các vòng lặp và biến đổi vòng lặp

Tuy nhiên các nghiên cứu ở đây chỉ là bước đầu chưa có kết quả khích lệ

- Register Allocation and splilling via graph coloring [18]

Nhóm nghiên cứu việc tối ưu thanh ghi trong trình biên dịch Thông thường một chương trình viết ở ngôn ngữ cấp cao thường ít tham khảo đến các thanh ghi Mục tiêu của trình biên dịch là giữ các toán hạng có nhiều tính toán trong thanh ghi hơn là trong bộ nhớ để giảm đến mức tối thiểu các hoạt động nạp (load) và lưu trữ (store)[18] Chỉ giải quyết cho một số trường hợp giới hạn, chưa có kết quả tối ưu nhất

- Optimizing and Parallelizing Compilers [13]

Đề cập đến các nghiên cứu về việc phát hiện song song hóa nhỏ và/ hoặc song song lớn, các thể hiện trung gian, phân tích dòng và tối ưu, phân phối thanh ghi

Trang 15

Các đề tài nghiên cứu cho việc sinh mã và tối ưu mã về trình biên dịch được thực hiện rất nhiều, nhưng các kết quả chỉ là bước đầu góp phần xây dựng trình biên dịch ngày càng hiệu quả hơn và mở ra nhiều hướng nghiên cứu về trình biên dịch

1.3 Mục tiêu đề tài

Luận văn cao học “Xây dựng chương trình tự động sinh mã trung gian và thực

hiện tối ưu mã trung gian” nghiên cứu thiết kế và hiện thực một trình biên dịch đơn giản, sinh mã trung gian và thực hiện một số giải thuật tối ưu mã

Các mục tiêu chủ yếu của đề tài là:

- Hiện thực toàn bộ một trình biên dịch phía trước đơn giản theo các phương pháp của [6]

- Thực hiện quá trình tự động sinh mã trung gian cho

o Các biểu thức kể cả phép gán

o Các cấu trúc có điều kiện, cấu trúc vòng lặp

o Gọi thủ tục, hàm, chương trình con

- Tối ưu mã trung gian : hiện thực các giải thuật tối ưu mã cho chương trình sau khi sinh mã trung gian

- Đánh giá hiệu suất của giải thuật tối ưu mã trung gian

1.4 Phương pháp luận

Cấu trúc hoàn chỉnh của một trình biên dịch phải trải qua một số giai đoạn, mỗi giai đoạn sẽ đảm nhận một vai trò khác nhau và có tính kế thừa từ giai đoạn trước đó

Kể từ khi máy tính ra đời, các nhà khoa học không ngừng cải tiến và phát triển cả về phần cứng và phần mềm sao cho máy tính ngày càng tốt hơn Thông thường tốc độ xử lý của máy tính đối với một phần mềm ứng dụng không chỉ phụ thuộc vào phần cứng mà còn phụ thuộc rất nhiều đến cấu trúc dữ liệu, ngôn ngữ lập trình và đặc biệt là trình biên dịch xử lý chúng

Trang 16

Việc xây dựng trình biên dịch đòi hỏi phải hiểu biết nhiều lãnh vực: ngôn ngữ lập trình, kiến trúc máy tính, các thuật toán và công nghệ phần mềm Nếu hiểu được những quá trình xảy ra trong trong lúc biên dịch một chương trình có thể cho phép những lập trình viên tránh được các sai sót trong khi viết

Hầu hết các nhà lập trình đều mong muốn là trình biên dịch sinh được mã đích có chất lượng giống như lúc chúng được viết bằng thủ công [5][9][10] Việc sinh mã của trình biên dịch có thể làm cho chương trình chạy nhanh hoặc ít tốn bộ nhớ hơn hoặc cả hai Để đạt được điều này, các trình biên dịch phải sử dụng các kỹ thuật tối ưu trong quá trình sinh mã Do đó, tối ưu hoá mã trở thành một giai đoạn quan trọng không thể thiếu trong tất cả các trình biên dịch

Mã trung gian để thực hiện tối ưu là mã trung gian ba địa chỉ, với mã ba địa chỉ cùng với các thông tin dòng dữ liệu được tính toán, máy tính sẽ thực hiện các phép biến đổi dựa trên các phương pháp kỹ thuật tối ưu để tạo ra mã ba địa chỉ mới tốt hơn và hiệu quả hơn cho việc sinh mã Đó là các kỹ thuật:

- Xây dựng đồ thị có hướng không lặp vòng (Directed acyclic graph–

DAG)[5] dùng để hổ trợ khi thực hiện biến đổi trong các khối cơ bản

(basic block) DAG sẽ xác định được các biểu thức con chung cần

thiết cho việc tối ưu

- Phân tích dòng điều khiển (control flow analysis) dùng để phân hoạch các khối cơ bản của chương trình Trên cơ sở đó máy tính sẽ tiến tới xây dựng đồ thị dòng (flow graph), tính toán các chi phối (dominator – DOM), phát hiện ra các vòng lặp (loops)

- Kỹ thuật phân tích dòng dữ liệu (data flow analysis) [3] nhằm thu thập các thông tin về cách dùng các biến, các định nghĩa trong chương trình Tất cả các thông tin này được thu thập từ nhiều nơi (có thể ở các khối khác nhau) và có thể liên quan với nhau theo một hệ phương trình đó là phương trình dòng dữ liệu cần thiết cho quá trình tối ưu hoá Các thông tin tính toán về biến sống, đạt đến sự định

Trang 17

nghĩa, chuỗi sử dụng-định nghĩa, chuỗi định nghĩa-sử dụng, … dùng trong việc tính toán đường đi của dòng dữ liệu Trên cơ sở đó các thông tin này sẽ quyết định cho các giải pháp tối ưu

Tối ưu trình biên dịch là vấn đề lớn mà các nhà nghiên cứu luôn quan tâm Trên cơ sở đó, có thể phát triển nghiên cứu theo các hướng sau:

- Cấp phát và gán thanh ghi cho các biến trong quá trình biên dịch Với số lượng thanh ghi của máy có giới hạn, trình biên dịch phải có chiến lược cấp phát sử dụng các thanh ghi máy một cách hợp lý và tối ưu nhất

- Tính toán và giải quyết sự phụ thuộc dữ liệu trong chương trình Khả năng song song hóa các vòng lặp sẽ làm giảm thời gian thực thi của chương trình cũng như tiết kiệm được thời gian biên dịch

- Lập thời biểu cho các lệnh, trong mô hình Neumann việc thực thi của một lệnh chỉ bắt đầu sau khi các lệnh trước nó hoàn thành Do đó vấn đề ở đây là việc nghiên cứu giải quyết lịch thực thi các lệnh có thể theo ống lệnh (pipeline), khi CPU có số đơn vị tính toán nhiều hơn một để giảm thời gian thực thi

Tuy nhiên việc tối ưu trình biên dịch cũng có một số khó khăn:

- Việc sinh mã đích có chất lượng giống như viết thủ công thường chỉ ở một số trường hợp giới hạn và rất khó thực hiện

- Không có kỹ thuật tối ưu tổng quát và triệt để, thường là mỗi kỹ thuật tối ưu chỉ áp dụng cho một loại mã nào đó

- Biến đổi chương trình không được gây ra lỗi, sai ý nghĩa

- Công việc gỡ lỗi trong môt trình biên dịch đã tối ưu trở nên phức tạp hơn so với khi chưa tối ưu [5]

1.5 Các đóng góp của luận văn

- Thiết kế và xây dựng bộ phân tích từ vựng

- Thiết kế và xây dựng bộ biên dịch hướng đến cú pháp

Trang 18

- Thiết kế và xây dựng bộ sinh mã trung gian ba địa chỉ cho các phát biểu gán, các biểu thức, các cấu trúc rẽ nhánh, các cấu trúc điều khiển, các thủ tục và các hàm

- Tối ưu mã trung gian theo một số giải thuật:

ƒ Giải thuật tối ưu thanh ghi bằng phương pháp tô màu đồ thị trong trường hợp thanh ghi không giới hạn

ƒ Giải thuật tối ưu thanh ghi bằng phương pháp tô màu đồ thị trong trường hợp thanh ghi có giới hạn

ƒ Tối ưu mã bằng phương pháp lập thời biểu cho các lệnh

- Tính toán hiệu suất đạt được của các giải thuật sau khi tối ưu

Trang 19

Chương 2

TỔNG QUAN VỀ TRÌNH BIÊN DỊCH

2.1 Giới thiệu về trình biên dịch

Trình biên dịch có thể chia thành các khối như H.2.1 Trong đề tàichúng tôi tập trung ở hai khối đầu: trình biên dịch hướng đến cú pháp và bộ tối ưu mã trung gian H.2.1 trình bày các giai đoạn của quá trình biên dịch

như sau

2.2 Trình biên dịch hướng đến cú pháp

Trình biên dịch hướng đến cú pháp còn được gọi là trình biên dịch phía trước ( front end compiler) Trình biên dịch phía trước sẽ dịch chương trình nguồn của người sử dụng và sinh ra mã trung gian

H.2.2 trình bày cấu trúc của một trình biên dịch hướng đến cú pháp

H.2.2 Trình biên dịch hướng đến cú pháp

Dòng token

Dòng

ký tự

Bộ phân tích từ vựng Bộ biên dịch hướng đến cú

pháp

Kết quả đánh giá

Mã trung gian

Chương

trình

nguồn

Mã trung gian chưa tối ưu

Mã đối tượng

Mã trung gian đã Tối ưu

Bộ sinh mã đối tượng

Bộ đánh giá mã đối tượng

H.2.1 Các khối của trình biên dịch

Trang 20

2.2.2 Bộ biên dịch hướng đến cú pháp

H.2.3 trình bày bộ biên dịch hướng đến cú pháp

H.2.3 Bộ biên dịch hướng đến cú pháp

Bộ biên dịch hướng đến cú pháp sử dụng các định nghĩa hướng đến cú pháp và sơ đồ dịch để xây dựng cây phân tích cú pháp khi nhận các token từ bộ phân tích từ vựng, sau đó duyệt cây khi cần đánh giá các quy tắc ngữ nghĩa tại các nút của cây Trong quá trình đánh giá các quy tắc ngữ nghĩa có thể làm phát sinh mã, lưu thông tin vào bảng danh biểu, đưa ra các thông báo lỗi hoặc thực hiện một số hành động khác

Tuy nhiên trong quá trình hiện thực không nhất thiết phải tuân thủ theo các giai đoạn như H.2.3 Các trường hợp đặc biệt của định nghĩa hướng đến cú pháp có thể cài đặt một lần bằng cách đánh giá các quy tắc trong khi phân tích cú pháp mà không cần phải xây dựng cây cú pháp hay đồ thị phụ thuộc

Quá trình biên dịch sẽ nhận các token từ bộ phân tích từ vựng, thực hiện phân tích cú pháp, phát hiện và khắc phục các lỗi cú pháp để có thể xử lý phần còn lại trong giai đọan phân tích cú pháp Có một số phương pháp để tiếp cận :

- Phân tích cú pháp từ dưới lên

- Phân tích cú pháp từ trên xuống

- Phân tích cú pháp LR

2.2.3 Sinh mã trung gian

1 Tác dụng của quá trình sinh mã trung gian

Theo H.2.2, trước tiên trình biên dịch sẽ dịch chương trình nguồn thành một dạng biểu diễn trung gian để bước sau sinh ra mã đích

Để việc sinh mã trung gian độc lập với mã đích, người ta thường chọn mã

Cây phân tích cú pháp

Đồ thị Phụ thuộc

Mã trung gian

Token từ bộ phân

tích từ vựng

Thứ tự đánh giá các quy tắc ngữ nghĩa

Trang 21

- Thuận lợi khi cần thay đổi giai đoạn sau (back-end phrase), có thể tạo ra một trình biên dịch cho nhiều máy tính khác bằng cách thay đổi giai đoạn sau

- Có thể tạo một bộ tối ưu mã độc lập với mã đích

2 Chọn lựa ngôn ngữ trung gian

Yêu cầu của đề tài là chọn mã ba địa chỉ làm ngôn ngữ trung gian Mã ba địa chỉ là một lệnh có dạng tổng quát x : = y op z Trong đó x,

y, z là các tên, hằng hoặc các tên tạm do trình biên dịch sinh ra, op là một toán tử bất kỳ

Ví dụ Biểu thức x+y*z có thể được dịch thành mã ba địa chỉ

t1 := y * z t2 := x + t1 trong đó t1 và t2 là các tên tạm do trình biên dịch sinh ra

Việc phân tích các biểu thức số học phức tạp thành các biểu thức con đơn giản đã làm cho mã ba địa chỉ trở thành một ngôn ngữ thiết yếu trong việc sinh mã đích và tối ưu mã

Lý do dùng thuật ngữ “mã ba địa chỉ” đó là mỗi câu lệnh thường chứa

ba địa chỉ, hai địa chỉ dành cho hai toán hạng và một địa chỉ dành cho kết quả Mã ba địa chỉ có nhiều loại lệnh, các lệnh trong mã ba địa chỉ có nhiều điểm tương đồng với mã hợp ngữ

2.3 Tối ưu mã

Quá trình tối ưu mã trung gian được thực hiện như sau

Phân tích dòng dữ liệu

Trang 22

2.3.1 Tiêu chuẩn cho việc tối ưu mã

- Trong quá trình tối ưu mã, mọi biến đổi phải giữ nguyên nghĩa của chương trình Mọi tối ưu không được thay đổi dữ liệu đầu vào (input), đầu ra (output) của chương trình, không gây ra lỗi, không gây ra phép chia bởi zero

- Mọi biến đổi phải làm cho chương trình nhanh hơn, và thu giảm thanh ghi trong việc sinh mã đối tượng

2.3.2 Phân tích dòng điều khiển (control flow analysis)

Phân tích dòng điều khiển bao gồm:

- Nhận diện các khối cơ bản (basic blocks)

- Phân tích đồ thị dòng điều khiển (control flow graph)

- Xác định chi phối (dominator) của một nút trong đồ thị

- Xác định các cấu trúc điều khiển của một chương trình

- Xác định các thủ tục

- Nhận diện các vòng lặp

2.3.3 Phân tích dòng dữ liệu (data flow analysis)

Để tối ưu và làm tốt việc sinh mã, một trình biên dịch cần thu thập toàn bộ thông tin của chương trình và phân bố các thông tin này đến mỗi khối trong đồ thị dòng

Phân tích dòng dữ liệu là xác định dữ liệu dùng trong chương trình và dùng kết quả phân tích này để xác định các tối ưu là hợp lệ Phân tích này có thể thực hiện

- Cục bộ (bên trong một khối) : phân tích ảnh hưởng của mỗi lệnh, giải quyết các ảnh hưởng ở đầu/cuối mỗi khối

- Toàn cục (bên trong các procedure) : xem ảnh hưởng của các dòng điều khiển trong chương trình

Trang 23

Chương 3

TRÌNH BIÊN DỊCH HƯỚNG ĐẾN CÚ PHÁP

3.1 Phân Tích Từ Vựng

Để cài đặt bộ phân tích từ vựng ta có hai phương pháp

- Phương pháp thủ công

- Phương pháp tự động

Phương pháp thủ công xây dựng bộ phân tích từ vựng bằng cách tạo ra một sơ đồ miêu tả các trạng thái mà bộ phân tích từ vựng sẽ trải qua khi nhận dạng token của ngôn ngữ nguồn rồi chuyển sơ đồ thành chương trình tìm kiếm các token

Phương pháp tự động đặc tả mẫu của các token bằng các biểu thức chính quy và dùng một bộ sinh, chẳng hạn như Lex và Jlex để tạo ra bộ phân tích từ vựng bằng cách biến đổi các biểu thức chính quy thành các automat hữu hạn rồi từ đó sinh ra chương trình mô phỏng các automat

Vấn đề trọng tâm của đề tài là sinh mã trung gian và tối ưu mã trung gian nên chúng tôi chọn phương pháp thủ công để xây dựng bộ phân tích từ vựng

3.1.1 Quá trình nhận dạng TOKEN

Token là các đơn vị từ vựng nhỏ nhất có nghĩa, nó biểu thị cho: danh biểu, hằng, các toán tử, các từ khóa của ngôn ngữ lập trình, các ký tự phân cách v.v…

Ví dụ 3.1 Cho văn phạm G, có tập luật sinh P như sau:

stmt → if exp then stmt│if exp then stmt else stmt │є

exp → term relop term │term

term → id │num

Các ký hiệu kết thúc là if, then, else, relop, num, chính là các token được định nghĩa chính quy như sau:

if → if

Trang 24

then → then

relop → <│ < = │ >│ > =│ < >│ =

id → letter (letter│ digit)*

num → digit + (.digit +│є) ((E (+│ - │є) digit+)│є )

Dựa vào ngôn ngữ được đặc tả bởi biểu thức chính quy trên, bộ phân tích từ

vựng sẽ nhận dạng các token if, then, else, relop, id, num

Bộ phân tích từ vựng còn phải nhận dạng các khoảng trắng để loại bỏ Chúng

ta thêm định nghĩa chính quy cho dấu trắng và chuỗi dấu trắng bằng hai định nghĩa sau:

delim → blank │tab│newline

else else

id id Con trỏ chỉ đến bảng danh biểu

Trang 25

3.1.2 Sơ Đồ Dịch

Sơ đồ dịch là bước trung gian trong việc xây dựng bộ phân tích từ vựng

Sơ đồ dịch miêu tả các hành vi của bộ phân tích từ vựng khi nhận dạng các token

Ví dụ 3.2

3.1.3 Hiện thực sơ đồ dịch bằng chương trình

Chuỗi các sơ đồ dịch sẽ được chuyển thành chương trình tìm kiếm token, là bộ phân tích từ vựng Ứng với mỗi trạng thái của sơ đồ dịch là một đoạn chương trình Nếu có một số cạnh xuất phát từ một trạng thái thì đoạn chương trình của trạng thái đó phải có lệnh đọc và lựa chọn cạnh nào là cạnh tiếp theo Thủ tục nextchar được dùng để đọc ký tự kế tiếp trong bộ đệm nhập Nếu một cạnh có tên trùng với ký tự vừa được đọc, hoặc có tên là lớp ký tự, có chứa ký tự vừa được đọc thì sự điều khiển của chương trình sẽ chuyển đến đoạn chương trình của trạng thái sắp tới do cạnh đó chỉ đến

Nếu không có cạnh nào trùng tên với ký tự vừa được đọc và trạng thái hiện tại cũng không là trạng thái kết thúc của việc nhận dạng một token, thì trở lại vị trí để bắt đầu sự tìm kiếm token khác bằng sơ đồ dịch kế tiếp Nếu tất cả các sơ đồ dịch không thể nhận dạng được một token nào đó thì bộ phân tích từ vựng sẽ thông báo lỗi

- Sơ đồ dịch cho danh biểu

10

Trang 26

Token đã nhận dạng sẽ được gửi sang bộ phân tích cú pháp (parser) bằng hai thông tin thông qua cặp biến < id, vị trí > cho token loại danh biểu và < num, trị > cho số

Ví dụ 3.3 Với sơ đồ dịch H.3.2 , ta có đoạn chương trình sau

case ‘<’: state = 5; break;

case ‘>’: state = 6; break;

Trang 27

3.2 Biên Dịch Hướng Đến Cú Pháp

Mỗi ngôn ngữ lập trình đều có các quy tắc để miêu tả cấu trúc cú pháp của chương trình hợp lệ Cú pháp của ngôn ngữ lập trình được miêu tả bằng văn phạm phi ngữ cảnh hoặc ký pháp BNF (Backus-Naur Form) Từ các lớp văn phạm, ta có thể thiết kế tự động bộ phân tích cú pháp, nó xác định xem một chương trình nguồn có đúng cú pháp không

Quá trình biên dịch hướng đến cú pháp bao gồm nhận các chuỗi nhập vào, xây dựng cây phân tích cú pháp, sau đó duyệt cây khi cần đánh giá các quy tắc ngữ nghĩa tại các nút của cây Quá trình đánh giá này có thể làm phát sinh mã, lưu thông tin vào bảng danh hiệu, đưa ra các thông báo lỗi …

Để biên dịch hướng đến cú pháp chúng ta cần định nghĩa hướng đến cú pháp

hay lược đồ dịch

3.2.1 Định nghĩa hướng đến cú pháp

Là văn phạm phi ngữ cảnh, trong đó mỗi ký hiệu văn phạm có một tập thuộc tính đi kèm Thuộc tính có thể là thuộc tính tổng hợp hay thuộc tính kế thừa

Một thuộc tính có thể biểu diễn bất kỳ điều gì chúng ta chọn: chuỗi, số, kiểu, vị trí bộ nhớ Giá trị của thuộc tính tại một nút của cây phân tích cú pháp được định nghĩa bởi luật ngữ nghĩa đi kèm với luật sinh được dùng tại nút đó Giá trị của một thuộc tính tổng hợp tại một nút được tính từ giá trị của các nút con của nó trong cây Giá trị của thuộc tính kế thừa được tính từ giá trị thuộc tính của những nút anh em và cha của nó

Luật ngữ nghĩa thiết lập phụ thuộc giữa các thuộc tính có thể được biểu diễn bằng một đồ thị Từ đồ thị phụ thuộc chúng ta tìm ra một thứ tự đánh giá các luật ngữ nghĩa

Một cây phân tích cú pháp trình bày giá trị các thuộc tính tại mỗi nút được gọi là cây phân tích cú pháp có chú thích (annotated parse tree) Quá trình tính giá trị các thuộc tính tại các nút gọi là chú thích (annotate) cho cây phân tích cú pháp

Trang 28

3.2.2 Hình thái của một định nghĩa hướng đến cú pháp

Trong một định nghĩa hướng đến cú pháp, mỗi luật sinh AỈ α có thể được liên kết với một tập các luật ngữ nghĩa có dạng b:=f(c1, c2,c3,…, ck) trong đó f là một hàm, c1, c2… ck là các thuộc tính của các ký hiệu văn phạm trong luật sinh và

• b là một thuộc tính tổng hợp của A hoặc

• b là một thuộc tính kế thừa của một trong các ký hiệu ở vế phải của luật sinh

Ví dụ 3.4 Các định nghĩa hướng đến cú pháp đơn giản của một máy tính bỏ túi

T.val := T1.val * F.val T.val := F.val

F.val := E.val

F.val := digit.lexval

Token digit có thuộc tính tổng hợp lexval với gía trị được giả định do phần phân tích từ vựng cung cấp Luật ngữ nghĩa đi kèm với luật sinh LỈEn

chỉ là một thủ tục in ra giá trị của biểu thức số học sinh bởi E

3.2.2.1 Thuộc tính tổng hợp

Một định nghĩa hướng đến cú pháp chỉ sử dụng các thuộc tính tổng hợp được gọi là định nghĩa thuộc tính S (S-attributed definition) Một cây phân tích cú pháp cho một định nghĩa thuộc tính S có thể được chú thích bằng cách đánh giá các luật ngữ nghĩa cho các thuộc tính tại mỗi nút theo hướng đi từ lá đến gốc

Trang 29

Ví dụ 3.5 Định nghĩa thuộc tính S trong ví dụ 3.4 cho một biểu thức số học

3 * 5 + 4n có cây cú pháp như H.3.4

Giã sử xét nút tương ứng với luật sinh T Ỉ T * F Giá trị thuộc tính T.val tại nút này được định nghĩa như sau:

TỈT1 * F T.val = T1.val * F.val

3.3.2.2 Thuộc tính kế thừa

Thuộc tính kế thừa là thuộc tính của một nút xác định theo thuộc tính nút cha và/hoặc các nút anh em của nó Thuộc tính kế thừa rất có ích cho việc diễn tả sự phụ thuộc của cấu trúc ngôn ngữ vào bối cảnh mà nó xuất hiện Ta có thể dùng thuộc tính kế thừa để xác định kiểu dữ liệu cho khai báo biến như

ở ví dụ 3.6

Ví dụ 3.6 Định nghĩa hướng đến cú pháp với thuộc tính kế thừa L.in

Luật sinh Quy tắc ngữ nghĩa

DỈ T L

T Ỉ int

L.in := T.type T.type := integer

L

nE.val =19

Trang 30

T Ỉ real

L ỈL1, id

L Ỉ digit

T.type := real L1.in := L.in addtype (id.entry, L.in) addType(id.entry, L.in)

3.2.2.3 Định nghĩa thuộc tính L

Định nghĩa thuộc tính L (L-attributed definition) là một lớp của định nghĩa hướng đến cú pháp, gần như chứa đựng hầu hết tất cả các hành động dịch có thể được thực hiện mà không cần phải xây dựng cây phân tích cú pháp Một định nghĩa hướng đến cú pháp là định nghĩa thuộc tính L nếu mỗi thuộc tính kế thừa của Xj ở vế phải của luật sinh A Ỉ X1X2….Xn, với 1 <= j

<= n, chỉ phụ thuộc vào

• Các thuộc tính của các ký hiệu X1, X2,….,Xj-1 ở bên trái của Xj

trong luật sinh và

• Các thuộc tính kế thừa của A

Mọi định nghĩa thuộc tính S đều thuộc tính L

3.2.3 Phân tích cú pháp

Bộ phân tích cú pháp nhận chuỗi các token từ bộ phân tích từ vựng để tạo ra cấu trúc cú pháp của chương trình nguồn

Vai trò của bộ phân tích cú pháp được miêu tả trong H.3.5

Có hai phương pháp phân tích cú pháp cơ bản cho ngôn ngữ lập trình

Yêu cầu token

Token Bộ phân tích Cây cú pháp

cú pháp

Bộ phân tích

từ vựng

Bảng danh biểu

Các bộ phận khác của TBD

H.3.5 Bộ phân tích cú pháp trong trình biên dịch

Trang 31

o Phân tích cú pháp từ dưới lên (bottom-up parser)

Hai phương pháp này áp dụng trên các lớp văn phạm LL(1) hoặc LR(1), là văn phạm của các ngôn ngữ lập trình Cả hai phương pháp này đều có thể dùng để sinh tự động bộ phân tích cú pháp

Một dạng đặc biệt của phương pháp phân tích cú pháp từ trên xuống là phương pháp đoán nhận trước bao gồm

- Phân tích cú pháp đoán nhận trước đệ quy

• Với phương pháp này, văn phạm của ngôn ngữ lập trình phải thỏa mãn điều kiện không có đệ quy trái

• Từ văn phạm ta có thể xây dựng lược đồ dịch cho từng ký hiệu không kết thúc của văn phạm Sau đó lược đồ dịch sẽ được chuyển thành chương trình phân tích cú pháp đoán nhận trước Phương pháp này thích hợp cho quá trình phân tích thủ công

- Phân tích cú pháp đoán nhận trước không đệ quy

• Hoạt động theo cơ chế Automat Push-down Stack

Phương pháp phân tích từ dưới làm việc trên lớp văn phạm LR(1) Từ lớp văn phạm này người ta đã xây dựng bộ sinh tự động bộ phân phân tích cú pháp từ dưới lên không bị quay lui

Với mục đích của đề tài nhằm hiện thực một trình biên dịch hướng đến cú pháp đơn giản và thủ công, nên chúng tôi đã chọn phương pháp đón nhận trước có đệ qui

3.2.4 Phân tích cú pháp đoán nhận trước đệ qui

Để biên dịch từ trên xuống, các định nghĩa thuộc tính L được cài đặt trong phần phân tích cú pháp đoán nhận trước Ta dùng lược đồ dịch thay cho định nghĩa hướng đến cú pháp để thấy rõ được các hành vi ngữ nghĩa Vì phần lớn các toán tử số học đều kết hợp trái nên sẽ tự nhiên hơn khi dùng các văn phạm đệ qui trái cho các biểu thức và do đó thao tác khử bỏ đệ qui trái ra khỏi lược đồ dịch là điều tất yếu Ví dụ sau đây minh họa quá trình xây dựng bộ phân tích cú pháp theo phương pháp đoán nhận trước

Trang 32

Lược đồ dịch trong quá trình phân tích cú pháp này phải có đặc điểm sau:

- Mỗi ký hiệu không kết thúc ở vế trái của luật sinh có một sơ đồ

- Tên các cạnh là token và là các ký hiệu không kết thúc ở vế phải của luật sinh

Sự truyền trên token sẽ được thực hiện nếu ký hiệu nhập trùng với token đó Nếu có sự truyền trên ký hiệu không kết thúc A thì ta thực hiện một lệnh gọi thủ tục A Sau đó

1 Tạo trạng thái bắt đầu và kết thúc

2 Với mỗi luật sinh có dạng AỈX1, X2,…Xn, ta xây dựng đường đi từ trạng thái bắt đầu đến trạng thái kết thúc sao cho các cạnh có tên X1,

H.3.6 trình bày sơ đồ dịch cho từng ký hiệu không kết thúc của G, tương ứng với vế trái của luật sinh

Trang 34

Sau khi có sơ đồ dịch, ta bắt đầu xây dựng bộ phân tích cú pháp đoán nhận trước đệ quy cho văn phạm G Sử dụng thủ tục đọc ký hiệu nhập kế tiếp nextchar, với c là biến chứa ký hiệu nhập kế tiếp Match là thủ tục so trùng Error là thủ tục báo lỗi

Giải thuật xây dựng bộ phân tích cú pháp đoán nhận trước từ sơ đồ dịch H.3.7

else error;

end; {F}

begin F;

while c =’*’ do F ; end {T}

begin T;

while c = ‘+’ do T;

end; {E}

3.3 Sinh mã trung gian

Trong quá trình biên dịch, ở giai đoạn đầu trình biên dịch sẽ dịch chương trình nguồn thành dạng biểu diễn trung gian để từ đó giai đoạn sau sinh ra mã đích Người thiết kế trình biên dịch có xu hướng chọn mã trung gian độc lập với mã đích nhằm mục đích:

1 Thuận lợi khi cần thay đổi mã đích

2 Có thể áp dụng bộ tối ưu hóa mã trung gian độc lập với máy đích Để đơn giản, chúng ta giả thiết rằng chương trình nguồn đã được phân tích cú pháp và kiểm tra kiểu tĩnh Phần lớn các định nghĩa hướng đến cú pháp trong chương này được cài đặt trong quá trình phân tích cú pháp từ trên xuống, vì thế quá trình sinh mã trung gian có thể được ghép chung với phân tích cú pháp nếu cần

Trang 35

3.3.1 Ngôn ngữ trung gian

Cây cú pháp và ký pháp hậu vị là hai loại dạng biểu diễn trung gian Một loại

thứ ba được gọi là mã ba địa chỉ ( three-address code)

3.3.1.1 Dạng biểu diễn đồ thị

Cây cú pháp mô tả cấu trúc phân cấp tự nhiên của một chương trình nguồn Tương tự DAG cũng biểu diễn thông tin cho chương trình nguồn nhưng các biểu thức chung được làm cho đồng nhất với nhau H.3.10 trình bày cây cú pháp và DAG cho biểu thức a := b* (- c) + b* (- c)

Ký pháp hậu vị là dạng biểu diễn tuyến tính của cây cú pháp; đó là một danh sách các nút của cây, trong đó một nút là toán tử xuất hiện ngay sau các con của nó Ký pháp hậu vị cho cây cú pháp ở H.3.10(a) là

a b c uminus * b c nminus * + assign Các cạnh trong một cây cú pháp không xuất hiện trong ký pháp hậu vị

Cây cú pháp được tạo bởi các định nghĩa hướng đến cú pháp Ví dụ như các định nghĩa trong H.3.11 dùng để xây dựng cây cú pháp cho các lệnh gán

H.3.10 Cách biểu diễn đồ thị của a := b* (- c) + b* (- c)

(a) Cây cú pháp (b)DAG

Trang 36

H.3.10(a) là cây cú pháp cho biểu thức a := b* (- c) + b* (- c)

Định nghĩa hướng đến cú pháp sẽ sinh dạng DAG H.3.10(b) nếu hàm mkunode(op, child) và mknode(op, left, right) trả về một con trỏ chỉ đến một nút đã có thay vì tạo ra các nút mới Token id có thuộc tính place chỉ đến vị trí của nó trong bảng danh biểu

3.3.1.2 Mã ba địa chỉ

Mã ba địa chỉ (three-address code) là một dãy câu lệnh có dạng tổng quát

x := y op z, trong đó x, y, z là các tên, hằng hoặc các tên tạm do trình biên dịch sinh ra; op là một toán tử bất kỳ, chẳng hạn toán tử số học trên các số nguyên hay số thực hoặc một toán tử logic nhận trị boole

Ví dụ biểu thức x+y*z có thể được dịch thành một dãy các lệnh mã ba địa chỉ t1 := y * z

t2 := x + t1

trong đó t1 và t2 là các tên tạm do trình biên dịch sinh ra

Mã ba địa chỉ là một biểu diễn tuyến tính hóa của cây cú pháp hoặc của DAG, trong đó các toán hạng tương ứng với các nút lá của đồ thị Cây cú pháp và DAG trong H.3.10 được biểu diễn lại bằng mã ba địa chỉ trong H.3.12 Tên biến có thể xuất hiện hướng đến trong mã ba địa chỉ

a : = t5

(b) Mã cho dag

H.3.12 Các loại mã ba địa chỉ

Trang 37

3.3.1.3 Các loại mã ba địa chỉ

Mã ba địa chỉ có nhiều điểm tương đồng với mã hợp ngữ Các câu lệnh có tên gợi nhớ và có các câu lệnh điều khiển Dưới đây là các câu lệnh ba địa chỉ thông dụng và được dùng trong chương trình

1 Các câu lệnh gán có dạng x :=y op z, trong đó op là một phép toán số học hoặc phép toán logic hai ngôi

2 Các chỉ thị gán có dạng x := op y, trong đó op là một phép toán một ngôi.Các phép toán một ngôi chủ yếu gồm có phép đổi dấu, phép phủ định logic, toán tử đẩy (shift) và toán tử chuyển đổi kiểu, chẳng hạn đổi một số thập phân có dấu chấm cố định thành một số thập phân có dấu chấm di động

3 Các câu lệnh sao chép (copy statement) có dạng x:= y trong đó giá trị

của y được gán cho x

4 Lệnh nhảy vô điều kiện goto L Câu lệnh ba địa chỉ có nhãn L là câu

lệnh được thực thi tiếp theo

5 Các lệnh nhảy điều kiện như if x relop y goto L, với relop là các toán

tử quan hệ ( < ,=, >=, <=, <>) Sự điều khiển trương trình sẽ nhảy đến câu lệnh có nhãn L nếu biểu thức x relop y cho trị đúng

6 Lệnh param x 1 , param x 2 …, param x n được sinh ra tương ứng với các

thông số thực x1,x2,…,xn và lệnh call p, n dùng cho lời gọi thủ tục hay hàm với n thông số thực p(x 1 , x 2 ,…x n )

7 Các phép gán liên quan đến mảng có dạng x := y[i] và x [i] :=y Phép gán thứ nhất cho x bằng với giá trị nằm ở vị trí i đơn vị bộ nhớ sau y Câu lệnh x[i]:=y đặt giá trị của y vào trong vị trí i đơn vị bộ nhớ sau x

8 Phép gán địa chỉ và con trỏ có dạng x := &y, x :=* y và * x:=y Phép gán thứ nhất đặt giá trị của x bằng vị trí của y trong bộ nhớ Trong câu lệnh x:=* y, gán giá trị x bằng với giá trị của đối tượng mà y đang chỉ tới Cuối cùng *x:=y đặt giá trị của đối tượng được chỉ bởi x bằng giá trị của y

Trang 38

3.3.2 Biên dịch hướng đến cú pháp sang mã ba địa chỉ

Khi phát sinh mã ba địa chỉ, các tên tạm được tạo ra cho các nút trung gian của cây cú pháp Giá trị của ký hiệu không kết thúc E ở vế trái của luật sinh EỈE1+ E2 sẽ được thay bằng một tên tạm t mới Nói chung mã ba địa chỉ id := E gồm có mã để tính trị E và lưu vào một tên tạm t nào đó, theo sau là phép gán id.place := t

Nếu một biểu thức chỉ là một danh biểu, như y chẳng hạn, thì chính y sẽ giữ giá trị của biểu thức

Ví dụ 3.8 Xét lại biểu thức a := b * (- c) + b * (- c)

H.3.12(a) trình bày kết quả sinh mã ba địa chỉ dựa trên định nghĩa thuộc tính

S trong hình H.3.13

S Ỉ id :=E S.code := E.code || gen (id.place ‘:=’ E.place)

E Ỉ E 1 + E 2 E.place := newtemp;

E.code := E1code || E2code ||

gen (E.place ‘=’ E1.place ‘+’ E2.place)

E Ỉ E1 * E2 E.place := newtemp;

E.code := E1.code || E2.code ||

gen (E.place’:=’E1.place ‘*’ E2.place)

H.3.13 Định nghĩa hướng đến cú pháp sinh mã ba địa chỉ cho phát biểu gán

- E.code : đoạn mã ba địa chỉ dùng để tính giá trị của E

- E.place: là tên sẽ giữ giá trị của E

- newtemp: hàm trả về các tên khác nhau t1, t2,…, tn cho cáclần gọi khác nhau, và gen(x ‘:=’ y ‘+’ z) biểu diễn cho câu lệnh ba địa chỉ x :=y +z

Trang 39

Các phát biểu điều khiển có thể được đưa vào định nghĩa hướng đến cú pháp

như phát biểu while trong H.3.14 Mã cho phát biểu S while E do S 1 được sinh ra bằng cách dùng hai thuộc tính mới S.begin và S.after, là nhãn cho câu lệnh đầu tiên trong đoạn mã cho E và câu lệnh theo sau đoạn mã while Những thuộc tính này biểu diễn cho các nhãn được tạo ra bởi hàm newlabel, trả về một nhãn mới mỗi khi được gọi Khi giá trị của E bằng zero, quyền điều khiển rời khỏi đoạn mã của while

S Ỉ while E do S1 S.begin := newlabel;

S.after : = newlabel;

S.code : =gen (S.begin ‘:’ || E.code||

gen (‘if’ E.place ‘=’ ‘0’ ‘goto’ S.after) ||

S1.code || gen (‘goto’ S.begin) ||

gen ( S.after ‘:’)

H.3.14 Định nghĩa hướng đến cú pháp sinh mã cho phát biểu while-do

3.3.3 Hiện thực các lệnh mã ba địa chỉ

Một lệnh ba địa chỉ là một dạng trừu tượng của mã trung gian Trong trình biên dịch, những lệnh này có thể được cài đặt như các mẫu tin với các trường dành cho toán tử và các toán hạng Sau đây sẽ trình bày các phương pháp hiện thực mã

ba địa chỉ cho các biểu thức cơ bản

3.3.3.1 Lệnh gán

Các biểu thức hay danh biểu có thể thuộc kiểu số nguyên, số thực, mảng Để dịch lệnh gán thành mã ba địa chỉ, ta tìm kiếm các danh biểu trong bảng danh biểu và truy xuất các phần tử trong mảng

E.code

if E.place = 0 goto S.after

S1.codeGoto S.beginS.begin:

S.after:

Trang 40

H.3.15 trình bày cách tìm các danh biểu trong bảng danh biểu, token id được

biểu diễn bằng thuộc tính id.name Thao tác lookup (id name) kiểm tra xem có id

trong bảng danh biểu hay không Nếu có thì trả về một con trỏ chỉ đến danh biểu

được tìm thấy; nếu không lookup sẽ trả về nil Các hành động ngữ nghĩa trong H.3.15 sử dụng thủ tục emit để xuất mã ba địa chỉ vào một tập tin

S Ỉ id : = E {p : = lookup (id name);

H 3.15 Sơ đồ biên dịch sinh mã ba địa chỉ cho câu lệnh gán

3.3.3.2 Mảng và địa chỉ các phần tử của mảng

Các phần tử của một mảng có thể được truy xuất nhanh chóng nếu chúng được lưu ở các vị trí liên tiếp nhau trong bộ nhớ Giả sữ ta có mảng một chiều A,nếu kích thước của mỗi phần tử mảng là w thì phần tử thứ i của mảng A sẽ bắt đầu

ở vị trí base + (i - low) * w, trong đó low là cận dưới của mảng và base là địa chỉ

tương đối của mảng A

Biểu thức trên có thể được tính trị vào lúc biên dịch nếu như nó được viết lại

là i * w + (base - low * w)

Biểu thức con c = base - low * w có thể được tính trị khi gặp khai báo của mảng Giả thiết rằng c được lưu trong bảng danh biểu cho A, vì thế địa chỉ tương đối của A[i] sẽ bằng i * w + c

Ngày đăng: 18/02/2021, 08:04

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w