FIRST() thì dùng 8.

Một phần của tài liệu Trình biên dịch nguuyên lý kỹ thuật và công cụ (Trang 55 - 57)

. 98 TỔNG QUAN VỀ BIÊN DỊCH

FIRST() thì dùng 8.

Sử dụng c-luật sinh

Các luật sinh cĩ e ở vế phải cần phải được xử lý đặc biệt. Thể phân cú pháp đệ qui- xuống sẽ dùng luật sinh c làm trường hợp mặc định khi khơng sử dụng được một luật. sinh khác. Chẳng bạn như xét:

gimt => begin opt_sữmis end opi_stmts —» simt list | e

Khi phân tích cú pháp cho op£ sứmfs, nếu ký hiệu sải với khơng thuộc FIRST(sm_/is£) thì luật sinh e được dùng. Chọn lựa này hồn tồn chính xác nếu ký hiệu sải với là end. Mọi ký hiệu sải với khơng phải là end sẽ gây ra lỗi và được phát hiện trong khi phân tích s/mt.

Thiết kế thể phân cú pháp dự đốn

Thể phân cú pháp dự đốn là một chương trình gồm cĩ một thủ tục cho mỗi ký hiệu chưa tận. Mỗi thủ tục sẽ thực biện hai việc:

1. Nĩ quyết định xem sẽ dùng luật sinh nào nhờ vào ký hiệu sải với. Luật sinh cĩ vế phải œ sẽ được dùng nếu ký hiệu sải với thuộc FIRST(œ). Nếu cĩ xung đột giữa hai vế phải trên một ký hiệu sải với nào đĩ thì chúng ta khơng thể dùng phương pháp phân tích cú pháp này trên văn phạm đang cĩ. Một luật sinh cĩ e ở vế phải sẽ được dùng nếu sải với khơng thuộc tập FIRST của một vế phải khác.

2. Thủ tục sẽ sử dụng một luật sinh bằng cách mơ phỏng vế phải. Một chưa tận gây ra một lời gọi đến thủ tục cho ký biệu đĩ, và một thẻ từ đối sánh được với ký hiệu sải với gây ra hành động đọc thẻ từ kế tiếp. Nếu tại một thời điểm nào đĩ, thẻ từ trong luật sinh khơng đối sánh được với ký hiệu sải với thì sẽ phải khai báo một lỗi. Hình 2.17 là kết quả áp dụng những qui tắc này cho văn phạm (2.8).

Cũng giống như khi tạo ra một lược đồ dịch bằng cách mở rộng một văn phạm, một chương trình dịch dựa cú pháp cĩ thể được tạo ra bằng cách mở rộng một thể phân cú pháp dự đốn. Một thuật tốn thực hiện điều này sẽ được cho trong Phần 5.5. Hiện tại, chúng ta chỉ cân dùng phương pháp xây dựng khá hạn chế đưới đây bởi vì các lược để dịch được cài đặt trong chương này khơng gắn các thuộc tính vào các ký hiệu chưa tận:

1. Xây dựng một thể phân cú pháp dự đốn, bỏ qua các hành động trong các luật sinh.

PHẲN 3.4 PHÂN TÍCH CÚ PHÁP 53

2. Sao chép các hành động từ lược để địch vào thể phân cú pháp này. Nếu một hành động xuất hiện sau ký hiệu văn phạm X trong luật sinh p thì nĩ được sao chép sau đoạn mã cài đặt X. Ngược lại nếu nĩ xuất hiện ở đầu luật sinh thì nĩ được sao chép ngay trước đoạn mã cài đặt luật sinh.

Chúng ta sẽ xây đựng một chương trình địch như thế ở phần tiếp theo. Đệ qui trái

Rất cĩ thể một thể phân cú pháp đệ qui-xuống bị “lạc” vào một vịng lặp vơ tận. Tình huống này xảy ra với các luật sinh đệ qui trái như

€XDT ¬> €XDT + ÍGTHL

trong đĩ ký hiệu tận trái ở vế phải giống với chưa tận ở vế trái cúa luật sinh. Giả sử rằng thú tục cho expr quyết định áp dụng luật sinh này. Vế phải bắt đầu với expr nên thủ tục cho expr được gọi đệ qui và thể phân cú pháp sẽ lặp vơ tận. Chú ý rằng ký hiệu sải với chỉ thay đổi khi một tận ở vế phải đối sánh được. Do luật sinh bắt đầu bằng chưa tận expr, khơng cĩ thay đổi nào đối với chuỗi nguyên liệu xảy ra giữa các lần gọi đệ qui và như thế gây ra một vịng lặp vơ tận.

⁄ A ⁄ ` A như 8 ~ ` A | | R8 _ Ị LP|sTl+s[- Ts] L2£]+s[]+«[ '_T>s]‹ (a) (b)

Hình 2.18. Sinh ra một chuỗi theo kiểu đệ qui trái và đệ qui phải.

Cĩ thể loại bỏ một luật sinh đệ qui trái bằng cách viết lại luật sinh đĩ. Xét một chưa tận A với hai luật sinh

A - Aa |ƒÿ

trong đĩ o và 8 là các đây ký hiệu tận và chưa tận khơng bắt đầu bằng A. Thí dụ trong luật sinh

54 MỘT TRÌNH BIÊN DỊCH MỘT LƯỢT ĐƠN GIẢN A = expr, d = + term, và B = term

Một phần của tài liệu Trình biên dịch nguuyên lý kỹ thuật và công cụ (Trang 55 - 57)