CHNG 4 PH N TCH C PHP 1

  • Slides: 137
Download presentation
CHƯƠNG 4 PH N TÍCH CÚ PHÁP 1

CHƯƠNG 4 PH N TÍCH CÚ PHÁP 1

Vai trò của bộ phân tích cú pháp 2

Vai trò của bộ phân tích cú pháp 2

Vai trò của bộ phân tích cú pháp Bộ phân tích cú pháp nhận

Vai trò của bộ 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. Ø Tồn tại ba loại bộ phân tích cú pháp: v Phương pháp tổng quát: Ø • • v Cocke-Younger-Kasami. Earley. Phương pháp thông dụng: Phân tích từ trên xuống hay phân tích từ dưới lên. 3

Xây dựng văn phạm cho ngôn ngữ lập trình Loại bỏ sự không tường

Xây dựng văn phạm cho ngôn ngữ lập trình Loại bỏ sự không tường minh Ví dụ: Cho văn phạm sau stmt -> if exp then stmt | if exp then stmt else stmt | other Ta thấy văn phạm này không tường minh khi phân tích phát biểu: if E 1 then if E 2 then S 1 else S 2 vì tồn tại hai cây cú pháp cho phát biểu. Ø 4

Xây dựng văn phạm cho ngôn ngữ lập trình 5

Xây dựng văn phạm cho ngôn ngữ lập trình 5

Xây dựng văn phạm cho ngôn ngữ lập trình 6

Xây dựng văn phạm cho ngôn ngữ lập trình 6

Xây dựng văn phạm cho ngôn ngữ lập trình Loại bỏ sự không tường

Xây dựng văn phạm cho ngôn ngữ lập trình Loại bỏ sự không tường minh bằng cách sửa lại văn phạm bằng cách: Khớp mỗi else với một then chưa khớp gần nhất trước đó. stmt -> matched-stmt | unmatched-stmt-> if exp then matched-stmt else matched-stmt | other unmatched-stmt -> if exp then stmt |if exp then matched-stmt else unmatched-stmt Ø 7

Xây dựng văn phạm cho ngôn ngữ lập trình Loại bỏ đệ quy trái:

Xây dựng văn phạm cho ngôn ngữ lập trình Loại bỏ đệ quy trái: v Một văn phạm là đệ qui trái (left recursive) nếu nó có một ký hiệu chưa kết thúc A sao cho có một dẫn xuất , với α là một chuỗi nào đó. v Các phương pháp phân tích từ trên xuống không thể nào xử lý văn phạm đệ qui trái, do đó cần phải dùng một cơ chế biến đổi tương để loại bỏ các đệ qui trái. Ø 8

Xây dựng văn phạm cho ngôn ngữ lập trình 9

Xây dựng văn phạm cho ngôn ngữ lập trình 9

Xây dựng văn phạm cho ngôn ngữ lập trình 10

Xây dựng văn phạm cho ngôn ngữ lập trình 10

Xây dựng văn phạm cho ngôn ngữ lập trình Ø Thí dụ 4. 1:

Xây dựng văn phạm cho ngôn ngữ lập trình Ø Thí dụ 4. 1: Loại bỏ đệ quy trái cho văn phạm: E -> E + T | T T -> T * F | F F -> (E) | id 11

Xây dựng văn phạm cho ngôn ngữ lập trình Ø Giải thuật 4. 1:

Xây dựng văn phạm cho ngôn ngữ lập trình Ø Giải thuật 4. 1: Loại bỏ đệ quy trái Nhập: Văn phạm G không có vòng lặp hoặc luật sinh rỗng. Xuất: Văn phạm tương đương G’ không có đệ quy trái. Phương pháp: G’ không còn đệ quy trái nhưng có thể có luật sinh rỗng. 12

Xây dựng văn phạm cho ngôn ngữ lập trình 13

Xây dựng văn phạm cho ngôn ngữ lập trình 13

Xây dựng văn phạm cho ngôn ngữ lập trình Ø Thí dụ: Chúng ta

Xây dựng văn phạm cho ngôn ngữ lập trình Ø Thí dụ: Chúng ta có áp dụng giải thuật 4. 1 vào văn phạm sau để loại bỏ đệ quy trái. S ->Aa | b A -> Ac | Sd | 14

Thừa số trái Ø Ø Thí dụ: Ta có hai luật sinh: stmt ->

Thừa số trái Ø Ø Thí dụ: Ta có hai luật sinh: stmt -> if exp then stmt else stmt | if exp then stmt Cả hai luật sinh đều có if dẫn đầu nên ta sẽ không biết chọn luật sinh nào để triển khai. Vì thế để làm chậm lại quyết định lựa chọn chúng ta sẽ tạo ra thừa số trái. 15

Tạo văn phạm có thừa số trái Nhập: Cho văn phạm G. Xuất: Văn

Tạo văn phạm có thừa số trái Nhập: Cho văn phạm G. Xuất: Văn phạm G’ có thừa số trái tương đương. Phương pháp: Tìm chuỗi dẫn đầu chung của các vế phải luật sinh, thí dụ: là chuỗi không bắt đầu bởi . Ta thay các luật trên bằng các luật A -> A’ | A’-> 1 | 2 | 3 … | n 16

Thừa số trái Ø Ø Thí dụ: Cho văn phạm như sau S ->

Thừa số trái Ø Ø Thí dụ: Cho văn phạm như sau S -> i. Et. S | i. Et. Se. S | a E -> b Áp dụng giải thuật trên cho văn phạm phát biểu if, ta có văn phạm yếu tố trái như sau. S -> i. Et. SS’ | a S’-> e. S | E -> b 17

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

Phân tích cú pháp từ trên xuống Ø Ø Phân tích cú pháp đệ quy. Phân tích cú pháp không đệ quy. 18

Phân tích cú pháp đệ quy đi xuống Ø Ø Thí dụ: Cho văn

Phân tích cú pháp đệ quy đi xuống Ø Ø Thí dụ: Cho văn phạm G: S -> c. Ad A -> ab | a Các bước phân tích cú pháp từ trên xuống: 19

Phân tích cú pháp đệ quy đi xuống 20

Phân tích cú pháp đệ quy đi xuống 20

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

Phân tích cú pháp đoán nhận trước đệ quy Ø Ø Ø v v Hãy loại bỏ đệ quy trái cho văn phạm mà chúng ta thiết kế. Hãy tạo văn phạm có thừa số trái nếu cần thiết. Sơ đồ dịch cho bộ phân tích đoán nhận trước. Sơ đồ này có đặc điểm như sau: Mỗi ký hiệu không kết thúc có một sơ đồ. Tên các cạnh là token và các ký hiệu không kết thúc. 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. 21

Phân tích cú pháp đoán nhận trước đệ quy Để xây dựng sơ đồ

Phân tích cú pháp đoán nhận trước đệ quy Để xây dựng sơ đồ chúng ta sẽ tiến hành các bước sau đây: v Tạo trạng thái bắt đầu và kết thúc. v Với mỗi luật sinh có dạng: A -> X 1 X 2…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 X 1, X 2, X 3…Xn. Ø 22

Phân tích cú pháp đoán nhận trước đệ quy Thí dụ 4. 3: Chúng

Phân tích cú pháp đoán nhận trước đệ quy Thí dụ 4. 3: Chúng ta hãy tạo sơ đồ dịch cho văn phạm G E→E+T|T T→T*F|F F → (E) | id Ø Ø Loại bỏ đệ quy trái trong văn phạm, ta được văn phạm tương đương sau : E -> TE’ E’-> + TE’| T -> FT’ T’-> *FT’| F -> (E) | id Sơ đồ dịch của các ký hiệu không kết thúc của G 23

Sơ đồ dịch của các ký hiệu không kết thúc của G 24

Sơ đồ dịch của các ký hiệu không kết thúc của G 24

Sơ đồ dịch của các ký hiệu không kết thúc của G 25

Sơ đồ dịch của các ký hiệu không kết thúc của G 25

Sơ đồ dịch của các ký hiệu không kết thúc của G, đã được

Sơ đồ dịch của các ký hiệu không kết thúc của G, đã được thu giảm 26

Giải thuật 27

Giải thuật 27

Giải thuật 28

Giải thuật 28

Phân tích cú pháp đoán nhận trước không đệ quy Ø Cấu tạo của

Phân tích cú pháp đoán nhận trước không đệ quy Ø Cấu tạo của bộ phân tích cú pháp: 29

Hoạt động của bộ phân tích n Ø Ø Ø Ở trạng thái bắt

Hoạt động của bộ phân tích n Ø Ø Ø Ở trạng thái bắt đầu, stack chỉ chứa các ký hiệu mục tiêu của văn phạm nằm trên $, trên đỉnh stack. Bảng phân tích M là ma trận. Hai ký hiệu X và a sẽ xác định hành vi của bộ phân tích. Bộ phân tích có ba hành vi như sau: Nếu X = a = $ bộ phân tích dừng và báo thành công. Nếu X = a <> $ bộ phân tích sẽ đẫy X ra khỏi Stack dịch đầu đọc đến ký hiệu nhập kế tiếp. Nếu X là ký hiệu không kết thúc bộ phân tích sẽ xét bảng ma trận để tìm luật sinh hoặt lỗi. 30

Giải thuật n n n Nhập: Chuỗi nhập w và bảng phân tích M

Giải thuật n n n Nhập: Chuỗi nhập w và bảng phân tích M cho văn phạm G. Xuất: Nếu w thuộc L(G), sẽ tạo ra dẫn xuất trái của w, ngược lại sẽ báo lỗi. Phương pháp: Lúc đầu cấu hình của bộ phân tích là ($S, w$) với S là ký hiệu mục tiêu của G. Đặt ip (là con trỏ hoặc còn gọi là đầu đọc của bộ phân tích) vào ký hiệu nhập đầu tiên của w$. 31

Giải thuật 32

Giải thuật 32

Phân tích cú pháp đoán nhận trước không đệ quy Thí dụ 4. 4:

Phân tích cú pháp đoán nhận trước không đệ quy Thí dụ 4. 4: Giả sử chúng ta có văn phạm G. E -> E + T | T T -> T *F | F F -> (E) | id Chúng ta sẽ thực hiện loại bỏ đệ quy trái, nhận được G’: E -> TE’ E’-> +TE’ | T -> FT’ T’ ->*FT’| F -> (E) | id Ø 33

Phân tích cú pháp đoán nhận trước không đệ quy Bây giờ chúng ta

Phân tích cú pháp đoán nhận trước không đệ quy Bây giờ chúng ta sẽ phân tích cú pháp cho câu nhập w = id + id * id bằng bảng phân tích M cho trước. 34

Các bước phân tích cú pháp câu id + id *id 35

Các bước phân tích cú pháp câu id + id *id 35

Xây dựng bảng phân tích M Ø Ø Ø v v v first( )

Xây dựng bảng phân tích M Ø Ø Ø v v v first( ) là tập c ký hiệu kết thúc a, dẫn đầu các chuỗi được dẫn xuất từ , ->a. Nếu -> thì thuộc first ( ). follow(A) là tập các ký hiệu kết thúc a, xuất hiện ngay bên phải A trong dạng câu. Các quy tắc tính first(X) với X là ký hiệu văn phạm: Nếu X là ký hiệu kết thúc thì first(X) = {X} Nếu X-> là luật sinh thì ta thêm vào first(X) Nếu X là ký hiệu không kết thúc và X ->X 1 X 2 X 3. . Xn là luật sinh thì cho a vào first(X) nếu với i thì a thuộc first(Xi) và ký hiệu ở trong tất cả first(X 1) …first(Xi-1) 36

Xây dựng bảng phân tích M Các quy tắc tính follow(A) cho tất cả

Xây dựng bảng phân tích M Các quy tắc tính follow(A) cho tất cả các ký hiệu không kết thúc A. v Cho ký hiệu $ vào follow(S), S là ký hiệu mục tiêu, $ là ký hiệu kết thúc chuổi nhập. v Tồn tại luật A-> B , tất cả các ký hiệu thuộc first( ) sẽ cho vào follow(B) trừ . v Tồn tại luật A-> B hoặc A-> B mà first( ) = { } thì tất cả các ký hiệu follow(A) sẽ cho vào follow(B). Ø 37

Xây dựng bảng phân tích M Ø Ø Thí dụ 4. 5: Cho văn

Xây dựng bảng phân tích M Ø Ø Thí dụ 4. 5: Cho văn phạm G. E -> TE’ E’-> +TE’ | T -> FT’ T’ ->*FT’| F -> (E) | id Toàn bộ các hàm first và follow của các ký hiệu văn phạm của G: first(E) = first(T) = first(F) = {(, id} first(E’) = {+, }; first(T’) = {*, } follow(E) = follow(E’) = {$, )} follow(T) = follow(T’) = {+, $, )} follow(F) = {*, +, $, )} 38

Xây dựng bảng phân tích M Ø Ø Ø v v Nhập: Văn phạm

Xây dựng bảng phân tích M Ø Ø Ø v v Nhập: Văn phạm G. Xuất: Bảng phân tích M. Phương pháp: Với mỗi luật sinh A -> hãy thực thi bước 2 và 3. Với mỗi ký hiệu kết thúc a thuộc first( ), thêm A -> vào M[A, a]. Nếu ký hiệu thuộc first( ), thêm A -> vào M[A, b] sao cho b thuộc follow(A). Nếu $ thuộc follow(A) thì thêm A -> vào M [A, $]. Những phần tử của bảng M trống, hãy đánh dấu lỗi. 39

Văn phạm LL(1) n Thí dụ 4. 7: Cho văn phạm G. S ->

Văn phạm LL(1) n Thí dụ 4. 7: Cho văn phạm G. S -> i. Et. SS’ | a S’-> e. S’ | E -> b first(S) = {i, a}, first(S’) = {e, }, first(E) = {b} follow(S) = {e, $}, follow(S’) = {e, $}, follow(E) = {t} 40

Bảng phân tích M cho thí dụ 41

Bảng phân tích M cho thí dụ 41

Bảng phân tích M cho thí dụ Ø Ø Nguyên nhân vì e vừa

Bảng phân tích M cho thí dụ Ø Ø Nguyên nhân vì e vừa thuộc first(S’) = {e, } vừa thuộc follow(S’) = {e, $}. Văn phạm không có phần tử nào của bảng phân tích M có nhiều hơn một trị thì được gọi là văn phạm LL(1). 42

Khắc phục lỗi trong phân tích cú pháp đoán nhận trước Ø Ø Lỗi

Khắc phục lỗi trong phân tích cú pháp đoán nhận trước Ø Ø Lỗi xuất hiện trong các trường hợp sau: Một là ký hiệu kết thúc trên stack không trùng với ký hiệu nhập đang được đọc. Hai là A là ký hiệu không kết thúc trên đỉnh stack, a trên chuỗi nhập, được đọc, mà M[A, a] là trống. Một số heuristics được áp dụng cho việc khắc phục lỗi. 43

Khắc phục lỗi trong phân tích cú pháp đoán nhận trước Ø Ø Ta

Khắc phục lỗi trong phân tích cú pháp đoán nhận trước Ø Ø Ta cho tất cả các ký hiệu trong follow(A) vào tập token đồng bộ của A. Chúng ta làm như vậy cho mỗi ký hiệu không kết thúc A. Khi phân tích cú pháp có xuất hiện lỗi, chúng ta sẽ bỏ qua các ký hiệu kết thúc trên chuổi nhập cho đến khi xuất hiện token trên chuổi nhập, thuộc follow(A) thì ta loại A ra khỏi stack. Khi phân tích cú pháp có xuất hiện lỗi, và A ở trên stack thì bộ phân tích sẽ loại bỏ các ký hiệu nhập cho đến khi xuất hiện token trên chuổi nhập, thuộc first(A) 44

Khắc phục lỗi trong phân tích cú pháp đoán nhận trước Ø Thí dụ

Khắc phục lỗi trong phân tích cú pháp đoán nhận trước Ø Thí dụ 4. 8: Cho văn phạm 45

Phân tích M có ký hiệu khắc phục lỗi 46

Phân tích M có ký hiệu khắc phục lỗi 46

Phân tích M có ký hiệu khắc phục lỗi 47

Phân tích M có ký hiệu khắc phục lỗi 47

Thí dụ 48

Thí dụ 48

Thí dụ Ø Phân tích và khắc phục lỗi cho chuỗi nhập: W =

Thí dụ Ø Phân tích và khắc phục lỗi cho chuỗi nhập: W = )id*+id 49

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

Phân tích cú pháp từ dưới lên Ø Ø Phân tích cú pháp từ dưới lên được hiểu là phân tích đẩy và thu giảm (Shift-Reduce parsing) là phương pháp phân tích LR (L có nghĩa là bộ phân tích sẽ đọc ký hiệu nhập từ trái sang, R có nghĩa là bộ phân tích sẽ tạo ra dẫn xuất phải ngược). Thí dụ 4. 9. Cho văn phạm G. S ->a. ABe A ->Abc|b B ->d Phân tích câu w = abbcde. 50

Phân tích cú pháp từ dưới lên Ø Ø Tóm tắt các bước thu

Phân tích cú pháp từ dưới lên Ø Ø Tóm tắt các bước thu giảm như sau: Quá trình thu giảm nếu theo chiều ngược lại thì đó chính là quá trình dẫn xuất phải. Quá trình này đã sinh cây cú pháp của câu phân tích từ dưới lên. 51

Thí dụ 52

Thí dụ 52

Thí dụ 53

Thí dụ 53

Handle Ø Handle của chuỗi ký tự là một chuổi con, mà nó so

Handle Ø Handle của chuỗi ký tự là một chuổi con, mà nó so trùng với vế phải luật sinh sao cho việc thu giảm chuổi con này về ký hiệu không kết thúc là một trong các bước của quá trình dẫn xuất. Tìm kiếm handle: Bắt đầu từ chuỗi cần phân tích w, ta đặt w = n. n là dạng câu được dẫn xuất ở lần thứ n. 54

Handle Xây dựng dẫn xuất phải ngược từ w = n. Ta tìm ßn

Handle Xây dựng dẫn xuất phải ngược từ w = n. Ta tìm ßn trong n sao cho ßn là vế phải luật sinh An -> ßn. Thay ßn trong n bằng An, ta nhận được dạng câu thứ (n – 1) là (n – 1). Quá trình thu giảm cứ tiếp tục như vậy cho đến khi đạt được 0 chỉ còn là một ký hiệu không kết thúc và là ký hiệu mục tiêu. 55

Phân tích cú pháp thứ tự yếu Ø Văn phạm có tính chất: không

Phân tích cú pháp thứ tự yếu Ø Văn phạm có tính chất: không có luật sinh nào có vế phải là chuỗi rỗng (A -> ) hoặc ở vế phải không có hai ký hiệu không kết thúc đứng kề nhau gọi là văn phạm thứ tự yếu. 56

Phân tích cú pháp thứ tự yếu 57

Phân tích cú pháp thứ tự yếu 57

Phân tích cú pháp thứ tự yếu 2. Hoạt động Thí dụ 4. 10.

Phân tích cú pháp thứ tự yếu 2. Hoạt động Thí dụ 4. 10. Cho văn phạm của phát biểu gán < assign stmt > -> id = < exp > -> < exp > + < term > | <term> < term > -> < term > * < factor > | < factor > -> id | (< exp >) Ký hiệu <assign stmt> là ký hiệu mục tiêu. 58

Bảng phân tích S-R cho văn phạm ở thí dụ 59

Bảng phân tích S-R cho văn phạm ở thí dụ 59

Giải thuật phân tích cú pháp thứ tự yếu Lúc đầu stack trạng thái

Giải thuật phân tích cú pháp thứ tự yếu Lúc đầu stack trạng thái chỉ có ký hiệu $. Stack nhập chứa chuỗi nhập, được kết thúc bởi dấu $ ; c: = false ; repeat if Ký hiệu mục tiêu ở trên đỉnh stack và ký hiệu $ ở đáy stack trạng thái, đồng thời stack nhập chỉ chứa $ then c: =true /*phântíchthànhcông, câycúphápxâydựngxong*/ else begin -X ở trên đỉnh stack trạng thái, Y ở trên đỉnh stack nhập. -Giả sửT là trị của phần tử S-R [X, Y]; if T là rỗng then error () 60

Giải thuật phân tích cú pháp thứ tự yếu else if T = R

Giải thuật phân tích cú pháp thứ tự yếu else if T = R then If trên đỉnh stack có chứa vế phải của luật sinh nào đó then begin Gọi A ->X 1 X 2…Xn là luật sinh nào có vế phải dài nhất so trùng với chuỗi trên stack trạng thái: (a) Giải tỏa X 1 X 2…Xn ra khỏi stack; (b) Thay. A lên stack. (c) Tạo nút mới A trên cây cú pháp, có các con là X 1 X 2…Xn end 61

Giải thuật phân tích cú pháp thứ tự yếu else error () //Không tìm

Giải thuật phân tích cú pháp thứ tự yếu else error () //Không tìm ra luật sinh else begin (a) Giải tỏa Y ra khỏi stack nhập; (b) Đẩy Y lên đỉnh stack trạng thái; (c) Tao nút mới tên Y trên cây cú pháp; end; until c; 62

Xây dựng bảng phân tích S-R Ø Ø Định nghĩa các quan hệ <

Xây dựng bảng phân tích S-R Ø Ø Định nghĩa các quan hệ < • , =, • >: Chúng ta nói X < • Y nếu và chỉ nếu tồn tại một luật sinh mà vế phải có dạng …XA với A là ký hiệu không kết thúc và sinh ra một chuỗi bắt đầu bằng Y (A ->Y…) như vậy X là biên trái của handle. X • >Y nếu và chỉ nếu tồn tại một luật sinh mà vế phải có dạng …AB. A sinh ra một chuỗi ký hiệu được kết thúc bằng X (A-> …X). B sinh ra một chuỗi được bắt đầu bằng. Y (B ->Y…), hoặc B = Y. Ở đây có hai trường hợp xảy ra trong quá trình tìm các mối quan hệ cho cặp (X, Y). 63

Xây dựng bảng phân tích S-R Ø Ø Ø X = Y nếu và

Xây dựng bảng phân tích S-R Ø Ø Ø X = Y nếu và chỉ nếu tồn tại một luật sinh mà vế phải có dạng …XY. . . Nhận xét: (Nếu khi phân tích cú pháp X trên đỉnh stack trạng thái, Y trên stack nhập) X • >Y thì bộ phân tích sẽ thực hiện một hành vi thu giảm. X <= • Y thì bộ phân tích sẽ thực hiện một hành vi đẩy. 64

Nguyên tắc tính quan hệ <= • Ø Ø Ø Tồn tại $ <=

Nguyên tắc tính quan hệ <= • Ø Ø Ø Tồn tại $ <= • A với A là ký hiệu mục tiêu của văn phạm cho trước. Nếu vế phải luật sinh có X nằm kề ngay Y về phía trái (…XY…) thì X <= • Y Nếu X <= • Y mà tồn tại một luật sinh Y -> Z 1 …Zn thì X <= • Z 1 65

Nguyên tắc tính quan hệ • > Ø Ø Tồn tại A • >

Nguyên tắc tính quan hệ • > Ø Ø Tồn tại A • > $ với A là ký hiệu mục tiêu. Nếu X <= • Y và tồn tại một luật sinh X -> Z 1…Zn thì Zn • > Y Nếu X • >Y và tồn tại một luật sinh Y -> Z 1…Zn thì X • > Z 1 66

Ví dụ Ø Với chuỗi nhập id = id + id * id, hãy

Ví dụ Ø Với chuỗi nhập id = id + id * id, hãy cho biết quá trình phân tích. 67

Bộ phân tích cú pháp LR Ø Ø Các tính chất của phương pháp

Bộ phân tích cú pháp LR Ø Ø Các tính chất của phương pháp phân tích LR: Bộ phân tích LR có thể nhận dạng được cấu trúc cú pháp của các ngôn ngữ lập trình do văn phạm phi ngữ cảnh tạo ra. Phương pháp LR là phương pháp tổng quát nhất của phương pháp phân tích đẩy và thu giảm, không bị quay lui từ trước đến giờ. 68

Bộ phân tích cú pháp LR Ø Ø Lớp văn phạm được phân tích

Bộ phân tích cú pháp LR Ø Ø Lớp văn phạm được phân tích bằng phương pháp LR là lớp văn phạm cha, bao trùm lớp văn phạm được phân tích bởi phương pháp đoán nhận trước. Bộ phân tích có khả năng phát hiện lỗi sớm nhất khi nó rà đến ký hiệu nhập từ trái sang phải. 69

Cấu tạo bộ phân tích cú pháp LR 70

Cấu tạo bộ phân tích cú pháp LR 70

Hoạt động Ø Ø Ø Stack được dùng để chứa chuỗi ký hiệu có

Hoạt động Ø Ø Ø Stack được dùng để chứa chuỗi ký hiệu có dạng s 0 X 1 s 1 X 2…Xmsm, với sm nằm trên đỉnh stack, Xi được gọi là ký hiệu văn phạm, si là trạng thái. Cặp(si, Xi) sẽ xác định một trị được lưu chứa trong bảng phân tích. Bảng phân tích gồm hai phần biểu thị bởi hàm action và goto. Cấu hình (configuration) của bộ phân tích LR là một cặp (nội dung stack nội dung còn lại của chuỗi nhập) Ví dụ: (s 0 X 1 s 1…Xisi…Xmsm, aiai+1…an$). 71

Phân tích cú pháp LR Ø Ø Ø Nhập: chuỗi nhập w, bảng phân

Phân tích cú pháp LR Ø Ø Ø Nhập: chuỗi nhập w, bảng phân tích action goto của văn phạm G. Xuất: nếu w thuộc L (G), nó tạo ra sự phân tích từ dưới lên. Ngược lại, bộ phân tích sẽ báo lỗi. Phương pháp: Thời điểm ban đầu stack có trạng thái s 0. Chuỗi w$ nằm trên bộ đệm nhập. Bộ phân tích đặt đầu đọc (con trỏ ip) vào ký hiệu nhập đầu tiên của w. 72

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

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

Ví dụ Cho văn phạm. G (1) E -> E + T (2) E

Ví dụ Cho văn phạm. G (1) E -> E + T (2) E -> T (3) T -> T * F (4) T -> F (5) F -> (E) (6) F -> id Phân tích câu w = id *id + id 74

Bảng phân tích cho văn phạm G 75

Bảng phân tích cho văn phạm G 75

Ví dụ 76

Ví dụ 76

Xây dựng bảng phân tích SLR Định nghĩa: thực thể LR (0) gọi tắt

Xây dựng bảng phân tích SLR Định nghĩa: thực thể LR (0) gọi tắt là thực thể của văn phạm G là luật sinh của G với các điểm chấm ở các vị trí nào đó của vế phải. Thí dụ: G có luật sinh A -> XYZ, sẽ cho bốn thực thể: A-> • XYZ A->X • YZ A->XY • Z A->XYZ • Nếu A -> sẽ cho ta thực thể A -> • 77

Giải thuật tính bao đóng–Closure. Function closure (I : item) : item; begin J

Giải thuật tính bao đóng–Closure. Function closure (I : item) : item; begin J : = I; repeat for với mỗi thực thể A -> a. Bß trong J và với mỗi luật sinh B -> trong G sao cho thực thể B -> • chưa có trong J do thêm B -> • vào J; until không thể thêm thực thể mới vào J; closure : = J; end; 78

Ví dụ Ø Xét văn phạm gia tố của biểu thức: E' → E

Ví dụ Ø Xét văn phạm gia tố của biểu thức: E' → E E→E+T|T T→T*F|F F → (E) | id 79

Giải thuật tính goto Goto(I, X), trong đó I là một tập các mục

Giải thuật tính goto Goto(I, X), trong đó I là một tập các mục và X là một ký hiệu văn phạm là bao đóng của tập hợp các mục A → αX • β sao cho A → α • Xβ I. Ø Cách tính goto(I, X): 1. Tạo một tập I' = ∅. 2. Nếu A → α • Xβ I thì đưa A→ αX • β vào I', tiếp tục quá trình này cho đến khi xét hết tập I. 3. Goto(I, X) = closure(I') Ø 81

Giải thuật tính tập tuyển các tập thực thể Procedure items (G’); begin C

Giải thuật tính tập tuyển các tập thực thể Procedure items (G’); begin C : = {closure ({S’-> • S}}} repeat for với mỗi tập thực thể I trong C và với mỗi ký hiệu văn phạm X sao cho phép goto(I, X) không rỗng và không có trong C do thêm goto(I, X) vào C; until không thể thêm tập thực thể mới vào C; end; 83

Xây dựng bảng phân tích Nhập: văn phạm gia tố G’ Ø Xuất: bảng

Xây dựng bảng phân tích Nhập: văn phạm gia tố G’ Ø Xuất: bảng phân tích SLR với hàm action và goto cho văn phạm G’ Ø Phương pháp: 1. Xây dựng C = {Io, I 1, …In}. 2. i là trạng thái đại diện cho tập thực thể Ii. a. Nếu A -> • aß là thực thể ở trong Ii và goto(Ii, a) = Ij thì phần tử action[i, a] = shift(j), với a phải là ký hiệu kết thúc. b. Nếu A -> • ở trong Ii thì action[i, a] = reduce(A -> ) với a là tất cả các ký hiệu nằm trong follow(A). A không phải là S’(ký hiệu mục tiêu mới). Ø 84

Xây dựng bảng phân tích c. Nếu S’->S • ở trong Ii thì action

Xây dựng bảng phân tích c. Nếu S’->S • ở trong Ii thì action [i, $] = accept. 3. Cho tất cả các ký hiệu không kết thúc A. Nếu goto[Ii, A] = Ij thì hàm goto[i, A] = j. 4. Tất cả các phần tử của bảng phân tích không được xác định bằng quy tắc 2 và 3, chúng ta coi là lỗi. 5 Trạng thái bắt đầu của bộ phân tích là tập thực thể có chứa thực thể S’-> • S. 85

Ví dụ Cho văn phạm gia tố G’ E’-> E E -> E +

Ví dụ Cho văn phạm gia tố G’ E’-> E E -> E + T E -> T T -> T* F T -> F F -> (E) F -> id Hãy tìm tập C và sơ đồ DFA. Xây dựng bảng phân tích SLR 86

Xây dựng tập C 89

Xây dựng tập C 89

Xây dựng tập C 90

Xây dựng tập C 90

Xây dựng tập C 91

Xây dựng tập C 91

Tính Follow FOLLOW(E) = {+, ), $} Ø FOLLOW(T) = {*, +, ), $}

Tính Follow FOLLOW(E) = {+, ), $} Ø FOLLOW(T) = {*, +, ), $} Ø FOLLOW(F) = {*, +, ), $} Ø 92

Xây dựng bảng phân tích Ø Ø Trước tiên xét tập mục I 0

Xây dựng bảng phân tích Ø Ø Trước tiên xét tập mục I 0 : Mục F → • (E) cho ra action[0, (] = "shift 4", và mục F → • id cho action[0, id] = "shift 5". Các mục khác trong I 0 không sinh được hành động nào. Bây giờ xét I 1 : Mục E'→ E • cho action[1, $] = "accept", mục E → E • + T cho action[1, +] = "shift 6". 93

Xây dựng bảng phân tích Ø Ø Ø Kế đến xét I 2 :

Xây dựng bảng phân tích Ø Ø Ø Kế đến xét I 2 : E → T • T→T • *F Vì FOLLOW(E) = {+, ), $}, làm cho action[2, $] = action[2, +] = action[2, )] = "reduce 2". Mục thứ hai làm cho action[2, *] = "shift 7". Tiếp tục theo cách này, ta thu được bảng phân tích cú pháp SLR đã trình bày. 94

Ví dụ Cho văn phạm G (1) S L = R (2) S R

Ví dụ Cho văn phạm G (1) S L = R (2) S R (3) L * R (4) L id (5) R L Xây dựng bảng phân tích SLR cho văn phạm trên 95

Ví dụ Ø Ta nhận thấy đụng độ khi action [2, =] = s

Ví dụ Ø Ta nhận thấy đụng độ khi action [2, =] = s 6 đồng thời action [2, =] = r 5 và action [2, $] = r 5. Do đó tại phần tử action [2, =] có hai trị s 6 và r 5. Như vậy G không phải là văn phạm SLR. 96

Xây dựng bảng phân tích Canonical LR Ø Dạng tổng quát của thực thể

Xây dựng bảng phân tích Canonical LR Ø Dạng tổng quát của thực thể là [A α β, a] với A αβ là luật sinh và a là ký hiệu kết thúc hoặc dấu $. Ø Thực thể có dạng như thế được gọi là thực thể LR (1). Nếu β = ∈ thì thực thể sẽ có dạng [A α , a]. Lúc này chúng ta thực hiện thu giảm bằng luật sinh A α chỉ với điều kiện ký hiệu nhập kế tiếp là a. 97

Phép tính closure Function Closure(I) begin Repeat For Mỗi mục [A → α Bβ,

Phép tính closure Function Closure(I) begin Repeat For Mỗi mục [A → α Bβ, a] trong I, mỗi luật sinh B → γ trong G' và mỗi ký hiệu kết thúc b ∈ FIRST (βa) sao cho [B → γ, b] ∉ I do Thêm [B → • γ, b] vô I; Until Không còn mục nào có thể thêm cho I được nữa; return I; end; 98

Phép tính goto Function goto (I, X) begin Gọi J là tập hợp các

Phép tính goto Function goto (I, X) begin Gọi J là tập hợp các mục [A → αX β, a] sao cho [A → α • Xβ, a]∈ I; return Closure(J); end; 99

Xây dựng tập tuyển các tập thực thể Procedure Items (G') begin C :

Xây dựng tập tuyển các tập thực thể Procedure Items (G') begin C : = Closure ({[S' → S, $]}) Repeat For Mỗi tập các mục I trong C và mỗi ký hiệu văn phạm X sao cho goto(I, X) ≠ và goto(I, X) C do Thêm goto(I, X) vô C; Until Không còn tập các mục nào có thể thêm cho C; end; 100

Xây dựng bảng phân tích Canonical LR 1. Xây dựng C = {I 0,

Xây dựng bảng phân tích Canonical LR 1. Xây dựng C = {I 0, I 1, . . In} là tập tuyển các tập thực thể LR(1) 2. Trạng thái thứ i được xây dựng từ Ii. Các action tương ứng trạng thái i được xác định như sau: 1. Nếu [A → α aβ, b] Ii và goto(Ii, a) = Ij thì action[i, a] = “shift j”. Ở đây a phải là ký hiệu kết thúc. 2. Nếu [A → α , a] Ii, A S' thì action[i, a] = “reduce (A → α)”. 3. Nếu [S' → S , $] Ii thì action[i, $] = “accept”. 101

Xây dựng bảng phân tích Canonical LR Nếu có một sự đụng độ giữa

Xây dựng bảng phân tích Canonical LR Nếu có một sự đụng độ giữa các luật nói trên thì ta nói văn phạm không phải là LR(1) và giải thuật sẽ thất bại. 3. Nếu goto(Ii, A) = Ij thì goto[i, A] = j 4. Tất cả các ô không xác định được bởi 2 và 3 đều là “error” 5. Trạng thi khởi đầu của bộ phân tích cú pháp được xây dựng từ tập các mục chứa [S' → • S, $] 102

Xây dựng bảng phân tích LR(1) chính tắc Bảng phân tích xác định bởi

Xây dựng bảng phân tích LR(1) chính tắc Bảng phân tích xác định bởi giải thuật trên gọi là bảng phân tích LR(1) chính tắc của văn phạm G, bộ phân tích LR sử dụng bảng LR(1) gọi là bộ phân tích LR(1) chính tắc và văn phạm có một bảng LR(1) không có các action đa trị thì được gọi là văn phạm LR(1). 103

Ví dụ Cho văn phạm G (1) S L = R (2) S R

Ví dụ Cho văn phạm G (1) S L = R (2) S R (3) L * R (4) L id (5) R L Xây dựng bảng phân tích Canonical LR cho văn phạm trên 104

Ví dụ Văn phạm gia tố của văn phạm G (0) S’ S (1)

Ví dụ Văn phạm gia tố của văn phạm G (0) S’ S (1) S L = R (2) S R (3) L * R (4) L id (5) R L 105

Xây dựng tập tuyển các tập thực thể Goto(I 2 , =) = I

Xây dựng tập tuyển các tập thực thể Goto(I 2 , =) = I 6 : {S → L= R, $ R → L, $ L → *R, $ L → id, $} Goto(I 4, R) = I 7 : {L → *R , = | $} Goto(I 4, L) = I 8 : {R→ L , = | $} Goto(I 4, *) = I 4 Goto(I 4, id) = I 5 108

Xây dựng tập tuyển các tập thực thể Goto(I 6, R) = I 9

Xây dựng tập tuyển các tập thực thể Goto(I 6, R) = I 9 : {S → L = R , $} Goto(I 6, L) = I 10 : {R → L , $} Goto (I 6, *) = I 11 : {L → * R, $ R → L, $ L → *R, $ L → id, $} Goto (I 6, id) = I 12 : {L → id , $} Goto (I 11, R) = I 13 : {R → *R , $} 109

Xây dựng tập tuyển các tập thực thể Goto(I 11, L) = I 10

Xây dựng tập tuyển các tập thực thể Goto(I 11, L) = I 10 Goto (I 11, *) = I 11 Goto (I 11, id) = I 12 110

Xây dựng bảng phân tích LR chính tắc cho văn phạm trên 111

Xây dựng bảng phân tích LR chính tắc cho văn phạm trên 111

Nhận xét Ø Mỗi văn phạm SLR(1) là một văn phạm LR(1), tuy nhiên

Nhận xét Ø Mỗi văn phạm SLR(1) là một văn phạm LR(1), tuy nhiên bộ phân tích cú pháp LR chính tắc có thể có nhiều trạng thái hơn so với bộ phân tích cú pháp SLR cho văn phạm đó. 112

Xây dựng bảng phân tích cú pháp LALR Ø Phần này giới thiệu phương

Xây dựng bảng phân tích cú pháp LALR Ø Phần này giới thiệu phương pháp cuối cùng để xây dựng bộ phân tích cú pháp LR. Ø LALR (Lookahead-LR), phương pháp này thường được sử dụng trong thực tế bởi vì những bảng LALR thu được nói chung là nhỏ hơn nhiều so với các bảng LR chính tắc và phần lớn các kết cấu cú pháp của ngôn ngữ lập trình đều có thể được diễn tả thuận lợi bằng văn phạm LALR. 113

Hạt nhân (core) Ø Một tập hợp mục LR(1) có dạng {[ A →

Hạt nhân (core) Ø Một tập hợp mục LR(1) có dạng {[ A → α • β, a]}, trong đó A → αβ là một luật sinh và a là ký hiệu kết thúc có hạt nhân (core) là tập hợp {A → α • β}. Ø Trong họ tập hợp các mục LR(1) C = {I 0, I 1, . . In} có thể có các tập hợp các mục có chung một hạt nhân. 114

Thuật toán xây dựng bảng phân tích cú pháp LALR Ø Xây dựng họ

Thuật toán xây dựng bảng phân tích cú pháp LALR Ø Xây dựng họ tập hợp các mục LR(1) C = {I 0, I 1, . . In} Ø Với mỗi hạt nhân tồn tại trong tập các mục LR(1) tìm trên tất cả các tập hợp có cùng hạt nhân này và thay thế các tập hợp này bởi hợp của chúng. Ø Ðặt C' = {J 0, J 1, . . Jm} là kết quả thu được từ C bằng cách hợp các tập hợp có cùng hạt nhân. Action tương ứng với trạng thái i được xây dựng từ Ji theo cách thức như giải thuật xây dựng bảng phân tích LR chính tắc. Ø Nếu có một sự đụng độ giữa các action thì giải thuật xem như thất bại và ta nói văn phạm không phải là văn phạm LALR(1). 115

Thuật toán xây dựng bảng phân tích cú pháp LALR Ø Bảng goto được

Thuật toán xây dựng bảng phân tích cú pháp LALR Ø Bảng goto được xây dựng như sau: Giả sử J = I 1 ∪ I 2 ∪. . . ∪ Ik. Vì I 1, I 2, . . . Ik có chung một hạt nhân nên goto (I 1, X), goto (I 2, X), . . . , goto (Ik, X) cũng có chung hạt nhân. Ðặt K bằng hợp tất cả các tập hợp có chung hạt nhân với goto (I 1, X) ⇒ goto(J, X) = K. 116

Ví dụ Cho văn phạm G (1) S L = R (2) S R

Ví dụ Cho văn phạm G (1) S L = R (2) S R (3) L * R (4) L id (5) R L Xây dựng bảng phân tích LALR cho văn phạm trên 117

Ví dụ Văn phạm gia tố của văn phạm G (0) S’ S (1)

Ví dụ Văn phạm gia tố của văn phạm G (0) S’ S (1) S L = R (2) S R (3) L * R (4) L id (5) R L 118

Ví dụ Ø Với ví dụ trên, ta có họ tập hợp mục C'

Ví dụ Ø Với ví dụ trên, ta có họ tập hợp mục C' như sau C' = {I 0, I 1, I 2, I 3, I 411, I 512, I 6, I 713, I 810, I 9 } 119

Xây dựng tập tuyển các tập thực thể Goto(I 0, S) = I 1

Xây dựng tập tuyển các tập thực thể Goto(I 0, S) = I 1 : {S' → S , $} Goto(I 0, L) = I 2 : {S → L = R, $ R → L , $} Goto(I 0, R) = I 3 : {S → R , $ } Goto(I 0, *), Goto(I 6, *) = I 411 : {L → * R, = | $ R → L, = | $ L → *R, = | $ L → id, = | $} Goto(I 0, id), Goto(I 6, id) = I 512 : {L → id , = | $} 121

Xây dựng tập tuyển các tập thực thể Goto(I 2 , =) = I

Xây dựng tập tuyển các tập thực thể Goto(I 2 , =) = I 6 : {S → L= R, $ R → L, $ L → *R, $ L → id, $} Goto(I 411, R) = I 713 : {L → *R , = | $} Goto(I 411, L), Goto(I 6, L) = I 810 : {R→ L , = | $} Goto(I 6, R) = I 9 : {S → L = R , $} 122

Bảng phân tích cú pháp LALR 123

Bảng phân tích cú pháp LALR 123

Sử dụng các văn phạm mơ hồ Ø Như chúng ta đã nói trước

Sử dụng các văn phạm mơ hồ Ø Như chúng ta đã nói trước đây rằng mọi văn phạm mơ hồ đều không phải là LR. Tuy nhiên có một số văn phạm mơ hồ lại rất có ích cho việc đặc tả và cài đặt ngôn ngữ. Ø Chẳng hạn văn phạm mơ hồ cho kết cấu biểu thức đặc tả được một cách ngắn gọn và tự nhiên hơn bất kỳ một văn phạm không mơ hồ nào khác. Ø Vì các văn phạm là đa nghĩa nên chúng ta sẽ đưa thêm các quy tắc khử mơ hồ để chỉ cho phép chọn một cây phân tích cú pháp cho mỗi một câu nhập. Theo cách này, đặc tả ngôn ngữ về tổng thể vẫn là 124 đơn nghĩa.

Sử dụng độ ưu tiên và tính kết hợp của các toán tử để

Sử dụng độ ưu tiên và tính kết hợp của các toán tử để giải quyết đụng độ Ø Xét văn phạm của biểu thức số học với hai toán tử + và * : E E + E | E * E | (E) | id (1) Ø Ðây là một văn phạm mơ hồ vì nó không xác định độ ưu tiên và tính kết hợp của các tóan tử + và *. Trong khi đó ta có văn phạm tương đương không mơ hồ cho biểu thức có dạng như sau: E E+T|T T T*F|F (2) F (E) | id 125

Sử dụng độ ưu tiên và tính kết hợp của các toán tử để

Sử dụng độ ưu tiên và tính kết hợp của các toán tử để giải quyết đụng độ Ø Văn phạm này xác định rằng + có độ ưu tiên thấp hơn * và cả hai toán tử đều kết hợp trái. Tuy nhiên có 2 lý do để chúng ta sử dụng văn phạm (1) chứ không phải là (2): v Dễ dàng thay đổi tính kết hợp và độ ưu tiên của + và * mà không phá hủy các luật sinh và số các trạng thái của bộ phân tích. v Bộ phân tích cho văn phạm (2) sẽ mất thời gian thu gọn bởi các luật sinh E T và T F. Hai luật sinh này không nói lên được tính kết hợp và độ ưu tiên. 126

Sử dụng độ ưu tiên và tính kết hợp của các toán tử để

Sử dụng độ ưu tiên và tính kết hợp của các toán tử để giải quyết đụng độ Ø Nhưng với văn phạm (1) thì làm thế nào để tránh sự đụng độ? Trước hết chúng ta hãy thành lập bộ sưu tập C các tập mục LR(0) của văn phạm tăng cường của nó. Sau đó xây dựng bảng SLR như sau: 127

Bảng phân tích cú pháp SLR 128

Bảng phân tích cú pháp SLR 128

Phân tích Ø Nhìn vào bảng SLR trong hình trên, ta thấy có sự

Phân tích Ø Nhìn vào bảng SLR trong hình trên, ta thấy có sự đụng độ tại action [7, +] và action [7, *]; action [8, +] và action [8, *]. Ø Chúng ta sẽ giải quyết sự đụng độ này bằng quy tắc kết hợp và độ ưu tiên của các toán tử. Xét chuỗi nhập id + id * id 129

Phân tích 130

Phân tích 130

Phân tích Ø Bây giờ đến ô đụng độ action[7, *] nên lấy r

Phân tích Ø Bây giờ đến ô đụng độ action[7, *] nên lấy r 1 hay s 5? Ø Lúc này chúng ta đã phân tích qua phần chuỗi id * id. Nếu ta chọn r 1 tức là thu gọn bởi luật sinh E E + E, có nghĩa là chúng ta đã thực hiện phép cộng trước. Ø Do vậy nếu ta muốn toán tử * có độ ưu tiên cao hơn + thì phải chọn s 5. 131

Phân tích Ø Nếu chuỗi nhập là id + id thì quá trình phân

Phân tích Ø Nếu chuỗi nhập là id + id thì quá trình phân tích văn phạm dẫn đến hình trạng hiện tại là : Stack Output 0 E 1+4 E 7 + id $ Ø Sẽ phải xét action [7, +] nên chọn r 1 hay s 4? Ø Nếu ta chọn r 1 tức là thu gọn bởi luật sinh E E + E tức là + thực hiện trước hay toán tử + có kết hợp trái => action [7, +] = r 1 132

Phân tích Ø Sau khi đã giải quyết được sự đụng độ đó ta

Phân tích Ø Sau khi đã giải quyết được sự đụng độ đó ta có được bảng phân tích SLR đơn giản hơn bảng phân tích của văn phạm tương đương (2) (chỉ sử dụng 10 trạng thái thay vì 12 trạng thái). Ø Tương tự, ta có thể xây dựng bảng phân tích LR chính tắc và LALR cho văn phạm (1). 133

Ví dụ Ø Giải quyết trường hợp văn phạm mơ hồ IF THEN ELSE

Ví dụ Ø Giải quyết trường hợp văn phạm mơ hồ IF THEN ELSE Ø Xét văn phạm cho lệnh điều kiện: Stmt if exp then stmt else stmt | if exp then stmt | other 134

Ví dụ Ø Ðể đơn giản ta viết i thay cho if exp then,

Ví dụ Ø Ðể đơn giản ta viết i thay cho if exp then, S thay cho stmt, e thay cho else và a thay cho other, ta có văn phạm gia tố viết lại như sau: S’ S S i S e S (1) S i. S (2) S a (3) 135

Bảng phân tích SLR 136

Bảng phân tích SLR 136

Phân tích Ø Ðể giải quyết đụng độ tại action[4, e]. Trường hợp này

Phân tích Ø Ðể giải quyết đụng độ tại action[4, e]. Trường hợp này xảy ra trong tình trạng chuỗi ký hiệu if exp then stmt nằm trong Stack và else là ký hiệu nhập hiện hành. Ø Sử dụng nguyên tắc kết hợp mỗi else với một then chưa kết hợp gần nhất trước đó nên ta phải Shift else vào Stack để kết hợp với then nên action[4, e] = s 5. 137