Nghiên cứu và xây dựng bảng phân tích cú pháp slr
MỤC LỤC MỤC LỤC MỞ ĐẦU CHƯƠNG I: PHÂN TÍCH CÚ PHÁP LR Thuật toán phân tích cú pháp LR Xây dựng bảng phân tích SLR .5 2.1 Mục 2.2 Văn phạm mở rộng 2.3 Hàm closure 2.4 Hàm goto .8 2.5 Xây dựng tập mục 2.6 Hàm FIRST(α) 2.7.Hàm FOLLOW(A) .11 2.8 Bảng phân tích SLR 12 CHƯƠNG II: THỰC HÀNH .13 Xây dựng bảng phân tích SLR cho văn phạm G 13 1.1.Xây dựng tập mục: .13 1.2.Hàm FOLLOW 15 1.3.Xây dựng bảng phân tích SLR .15 2.Áp dụng phân tích cú pháp câu .15 TÀI LIỆU THAM KHẢO 16 MỞ ĐẦU Phân tích cú pháp nội dung quan trọng chương trình dịch, thực hai nhiệm vụ là: Kiểm tra tính đắn cú pháp chương trình nguồn, đồng thời xác định chức thành phần chương trình nguồn Trong phạm vi tập, em tiến hành nghiên cứu dạng phân tích cú pháp từ lên LR, đồng thời nghiên cứu phương pháp xây dựng bảng phân tích cú pháp SLR Bài tập trình bày thành hai phần: - Chương I: Trình bày kiến thức phân tích cú pháp LR phương pháp xây dựng bảng phân tích SLR - Chương II: Áp dụng xây dựng bảng phân tích cho văn phạm cụ thể, ứng dụng phân tích cú pháp cho chuỗi nhập vào Do hiểu biết chương trình dịch hạn chế nên tập không tránh khỏi thiếu sót, em kính mong thầy giáo – TS Hà Chí Trung giúp đỡ, tạo điều kiện để em hoàn thiện tập Hà Nội, ngày 05 tháng 01 năm 2015 Học viên CHƯƠNG I: PHÂN TÍCH CÚ PHÁP LR Thuật toán phân tích cú pháp LR Kỹ thuật phân tích cú pháp LR(k) kỹ thuật phân tích cú pháp từ lên hiệu quả, sử dụng để phân tích lớp rộng văn phạm phi ngữ cảnh Trong đó: - L (left - to - right): Duyệt chuỗi nhập từ trái sang phải - R (rightmost derivation): Xây dựng chuỗi dẫn xuất phải đảo ngược - k : Số lượng ký hiệu nhập xét thời điểm dùng để đưa định phân tích Khi không đề cập đến k, hiểu ngầm k = Các ưu điểm phân tích cú pháp LR là: - Bộ phân tích cú pháp LR xây dựng để nhận biết tất ngôn ngữ lập trình tạo văn phạm phi ngữ cảnh - Phương pháp phân tích cú pháp LR phương pháp tổng quát phương pháp chuyên thu gọn không quay lui Nó cài đặt có hiệu phương pháp chuyên thu gọn khác - Lớp văn phạm dùng phương pháp LR lớp rộng lớn lớp văn phạm sử dụng phương pháp dự đoán - Bộ phân tích cú pháp LR xác định lỗi cú pháp nhanh duyệt dòng nhập từ trái sang phải Tuy nhiên, phương pháp có nhược điểm chủ yếu cần phải thực nhiều công việc để xây dựng phân tích cú pháp LR theo kiểu thủ công cho văn phạm ngôn ngữ lập trình điển hình Mô hình phân tích cú pháp LR mô tả sau: Trong đó: - Stack lưu chuỗi s0X1s1X2s2 Xmsm sm nằm đỉnh Stack Xi ký hiệu văn phạm, si trạng thái tóm tắt thông tin chứa Stack bên - Bảng phân tích bao gồm phần: hàm action hàm goto o action[sm, ai] có giá trị : shift s: đẩy s, s trạng thái reduce A→ β: thu gọn luật sinh A→ β accept: Chấp nhận error: Báo lỗi o goto lấy tham số trạng thái ký hiệu văn phạm, sinh trạng thái Giải thuật phân tích cú pháp LR trình bày sau: Input: Một chuỗi nhập w, bảng phân tích LR với hàm action goto cho văn phạm G Output: Nếu w ∈ L(G), đưa phân tích lên cho w Ngược lại, thông báo lỗi Phương pháp: Khởi tạo s0 trạng thái khởi tạo nằm Stack w$ nằm đệm nhập Ðặt ip vào ký hiệu w$; Repeat forever begin Gọi s trạng thái đỉnh Stack a ký hiệu trỏ ip; If action[s, a] = Shift s' then begin Ðẩy a sau s' vào Stack; Chuyển ip tới ký hiệu kế tiếp; end else if action[s, a] = Reduce (A → β) then begin Lấy * | β| ký hiệu khỏi Stack; Gọi s' trạng thái đỉnh Stack; Ðẩy A, sau đẩy goto[s', A] vào Stack; Xuất luật sinh A → β; end else if action[s, a] = accept then return else error ( ) end Xây dựng bảng phân tích SLR Vấn đề để xây dựng bảng phân tích LR Có ba phương pháp xây dựng sau: - Xây dựng bảng phân tích cú pháp SLR (Simple LR) - Xây dựng bảng phân tích cú pháp LR tắc (Canonical LR) - Xây dựng bảng phân tích cú pháp LALR( Lookahead-LR) Trong phương pháp xây dựng bảng phân tích cú pháp SLR phương pháp "yếu" tính theo số lượng văn phạm xây dựng thành công phương pháp này, lại phương pháp dễ cài đặt Ta gọi bảng phân tích cú pháp tạo phương pháp bảng SLR phân tích cú pháp tương ứng phân tích cú pháp SLR, với văn phạm tương đương văn phạm SLR Trước hết, ta nghiên cứu số vấn đề sau: 2.1 Mục Một mục LR(0) (LR(0) item – gọi tắt mục) văn phạm G sản xuất G có dấu chấm nằm bên vế phải Do sản xuất AXYZ có mục sau: AXY•Z A •XYZ AX•YZ AXYZ• Sản xuất Aε có mục A • Một mục biểu diễn cặp số nguyên, số số thứ tự sản xuất, số thứ hai vị trí dấu chấm Về trực quan, mục cho biết sản xuất trình phân tích suy dẫn Ví dụ, mục nói rằng, ta hi vọng thấy xâu đầu vào xâu suy dẫn từ XYZ Mục thứ hai ta thấy đầu vào suy dẫn từ X ta hi vọng thấy xâu suy dẫn từ YZ Tư tưởng chủ đạo phương pháp SLR ta xây dựng từ văn phạm cho ô tô mát hữu hạn đơn định DFA dùng để nhận dạng tiền tố có Ta nhóm mục với thành tập tập lấy làm trạng thái phân tích SLR Một tập tập mục LR (0) gọi tập LR (0) chuẩn, sở cho việc xây dựng phân tích SLR Để xây dựng tập LR (0) chuẩn cho văn phạm ta định nghĩa văn phạm mở rộng hai hàm: closure (bao đóng) goto (nhảy tới) 2.2 Văn phạm mở rộng Nếu G văn phạm với ký hiệu bắt đầu E G’ văn phạm mở rộng G cách thêm vào G ký hiệu bắt đầu E’ thêm vào sản xuất E’E Lý việc sửa đổi nhằm cho phân tích biết nên dừng phân tích thông báo chấp nhận xâu vào Do đó, việc chấp nhận xảy phân tích thu gọn sản xuất E’ E 2.3 Hàm closure Nếu I tập mục văn phạm G bao đống closure(I) tập mục xây dựng từ I hai luật: Khởi đầu, mục I thêm vào closure(I) Nếu A α•Bβ có closure(I) B γ sản xuất thêm mục B •γ vào I chưa sẵn sàng Áp dụng luật không thêm mục vào closure(I) Trực quan, A α•Bβ closure(I) rằng, điểm trình phân tích, thấy tiếp xâu suy dẫn từ Bβ đầu vào Nếu B γ sản xuất, ta mong muốn thấy xâu suy dẫn từ γ điểm Vì lý ta thêm B •γ vào closure(I) Ví dụ: Xem xét văn phạm mở rộng biểu thức sau: E’ E EE+T|T TT*F|F F (E) | a Nếu I tập mục có mục {[E’ •E]} closure(I) bao gồm mục: E’ •E E •E + T F •(E) F •a E •T T •T * F T •F Ở E’ •E đặt vào closure(I) theo luật Khi có E sau chấm luật ta thêm sản xuất E với chấm nằm đầu trái, tức E•E+T E •T Bây lại có T sau chấm ta lại thêm T•T*F T•F Tiếp theo, tương tự với F ta thêm F•(E) F•a Và không thêm mục vào closure(I) qua luật Hàm closure tính Một cách thuận tiện thực hàm dùng mảng boolean added, đánh số theo ký hiệu không kết thúc G, ví dụ added[B] đặt true ta thêm mục B •γ sản xuất B γ function closure(I); begin J:=I; repeat for với mục A α•Bβ J với sản xuất B γ G mà B •γ không J thêm B •γ vào J until không mục thêm vào J; Trả lại J; end; Chú ý sản xuất thêm vào bao đóng I với dấu chấm đầu bên trái, tất sản xuất B thêm tương tự vào bao đóng Thật ra, số hoàn cảnh thực tế không cần thiết liệt kê mục B •γ thêm vào I hàm closure Ta chia tất tập mục mà ta quan tâm thành hai lớp mục: Mục nhân: bao gồm mục khởi đầu E’ •E tất mục mà chấm không đầu bên trái Mục nhân: mục có chấm nằm đầu bên trái Ta thấy rằng, tập mục hình thành cách lấy bao đóng tập mục nhân, dĩ nhiên mục thêm vào bao đóng không mục nhân Do biểu diễn tập mục ta thật quan tâm với lưu trữ cách loại bỏ tất mục nhân cần sinh lại hàm tính bao đóng 2.4 Hàm goto Hàm thứ hai goto(I,X) với I tập mục X ký hiệu văn phạm goto(I,X) xác định bao đóng closure tập tất mục [A αX•β] mà [A α•Xβ] thuộc I Ta thấy, I tập mục hợp lệ tiền tố có γ đó, goto(I,X) tập mục hợp lệ với tiền tố có γX Ví dụ : Nếu I tập hai mục {[E’ E•], [E E•+T]} goto(I, +) bao gồm: E E + •T F •(E) T •T * F F •a T •F Ta tính goto(I, +) cách kiểm tra I cho mục với dấu + bên phải dấu chấm E’ E• mục vậy, E E + •T Ta chuyển dấu chấm qua bên dấu + để nhận {E E + •T} sau tính closure cho tập function goto(I,X); begin Đặt J tập mục [A→αX•β, a] mà [A→αX•β, a] I Trả lại closure(J); end; 2.5 Xây dựng tập mục Thuật toán dùng để xây dựng C tập tập chuẩn LR (0) cho văn phạm mở rộng G’: procedure items(G’); begin C:= { closure({[E’ • E]})}; repeat for với tập mục I C ký hiệu văn phạm X mà goto(I,X) không rỗng không thuộc C Thêm goto(I,X) vào C; until không thêm tập mục vào C; end; 2.6 Hàm FIRST(α ) Ðịnh nghĩa : FIRST(α) tập hợp ký hiệu kết thúc mà bắt đầu chuỗi dẫn xuất từ α Với α chuỗi ký hiệu văn phạm, Nếu α ⇒* ε ε ∈ FIRST(α) Cách tính: Để tính FIRST(α) trước hết ta tính FIRST(X) sau: Thực quy luật sau ký hiệu kết thúc ε thêm vào tập FIRST(X) : Nếu X kí hiệu kết thúc FIRST(X) {X} Nếu X → ε luật sinh thêm ε vào FIRST(X) Nếu X → Y1Y2Y3 Yk luật sinh thêm tất ký hiệu kết thúc khác ε FIRST(Y1) vào FIRST(X) Nếu ε ∈ FIRST(Y1) tiếp tục thêm vào FIRST(X) tất ký hiệu kết thúc khác ε FIRST(Y 2) Nếu ε ∈ FIRST(Y1) ∩ FIRST(Y2) thêm tất ký hiệu kết thúc khác ε ∈ FIRST(Y3) Cuối thêm ε vào FIRST(X) ε ∈ Bây ta tính FIRST(α) cho xâu α có dạng X1 X2 …Xn sau: Thêm vào FIRST(X1 X2 …Xn) tất ký hiệu ε FIRST(X1) Ta thêm tất ký hiệu ε FIRST(X 2) ε thuộc FIRST(X1), ký hiệu ε FIRST(X 3) ε thuộc FIRST(X2) … Cuối thêm ε vào FIRST(X1 X2 …Xn) với i mà FIRST(Xi) có chứa ε n = Ví dụ: Với văn phạm sau: E → T E' E' → + T E' | ε T → F T' T'→ * F T' | ε F → (E) | id Theo định nghĩa tập FIRST, ta có : Vì F ⇒ (E) | id ⇒ FIRST(F) = { (, id } Từ T → F T' ε ∉ FIRST(F) ⇒ FIRST(T) = FIRST(F) Từ E → T E' ε ∉ FIRST(T) ⇒ FIRST(E) = FIRST(T) Vì E' → ε ⇒ ε ∈ FIRST(E') Mặt khác E' → + TE' mà FIRST(+) = {+} ⇒ FIRST(E') = {+, ε } Tương tự FIRST(T') = {*, ε } Vậy ta có : FIRST(E) = FIRST(T) = FIRST(F) = { (, id } FIRST(E') = {+, ε } 10 FIRST(T') = {*, ε } 2.7 Hàm FOLLOW(A) Định nghĩa: FOLLOW(A) tập hợp ký hiệu kết thúc a mà xuất sau A (bên phía phải A) dạng câu Tức tập hợp ký hiệu kết thúc a, cho tồn dẫn xuất dạng S ⇒* αAaβ Chú ý A ký hiệu phải dạng câu $ ∈ FOLLOW(A) ($ ký hiệu kết thúc chuỗi nhập ) Với A ký hiệu chưa kết thúc Cách tính: Áp dụng quy tắc sau thêm vào tập FOLLOW Ðặt $ vào follow(S), S ký hiệu bắt đầu văn phạm $ ký hiệu kết thúc chuỗi nhập Nếu có luật sinh A→ αBβ thêm phần tử khác ε FIRST(β)và FOLLOW(B) Nếu có luật sinh A→ αB A→ αBβ mà ε ∈ FIRST(β) thêm tất phần tử FOLLOW(A) vào FOLLOW(B) Ví dụ: Với văn phạm ví dụ trên: - Áp dụng luật cho luật sinh F→ (E) ⇒ ) ∈ FOLLOW(E) ⇒ FOLLOW(E)={$,) - Áp dụng luật cho E → TE' ⇒ ), $ ∈ FOLLOW(E') ⇒ FOLLOW(E') ={$, ) } - Áp dụng luật cho E → TE' ⇒ + ∈ FOLLOW(T) Áp dụng luật cho E'→+TE', E' → ε ⇒ FOLLOW(E') ⊂ FOLLOW(T) ⇒ FOLLOW(T) = { +, ), $ } - Áp dụng luật cho T→ FT' FOLLOW(T') = FOLLOW(T) ={+, ), $ } - Áp dụng luật cho T→ FT' ⇒ * ∈ FOLLOW(F) - Áp dụng luật cho T' → * F T' , T'→ ε ⇒ FOLLOW(T') ⊂ FOLLOW(F) ⇒ FOLLOW(F) = {*, +, ), $ } * Vậy ta có: o FOLLOW(E) = FOLLOW(E') = { $, ) } o FOLLOW(T) = FOLLOW(T') = { +, ), $ } o FOLLOW(F) = {*,+, ), $ } 11 2.8 Bảng phân tích SLR Bây ta xem cách xây dựng hàm action goto phân tích SLR từ DFA dùng để nhận dạng tiền tố có Thuật toán đưa bảng action cho văn phạm, thành công nhiều ngôn ngữ lập trình Cho văn phạm G, ta mở rộng thành G’ từ G’ ta xây dựng C tập chuẩn tập mục cho G’ Ta xây dựng hàm phân tích action hàm nhảy goto từ C thuật toán Nó đòi hỏi ta tính FOLLOW(A) cho ký hiệu không kết thúc văn phạm Thuật toán : Xây dựng bảng phân tích SLR Input: văn phạm mở rộng G’ Output: Bảng phân tích SLR có hàm action goto cho G’ Phương pháp: Xây dựng C = {I0, I1,…, In} tập tập mục LR(0) cho G’ Trạng thái i xây dựng từ I i Các hoạt động phân tích cho trạng thái i xác định sau: a Nếu [A→α•aβ] thuộc Ii goto(Ii, a) = Ij đặt action[i, a] thành “gạt j” Ở a phải ký hiệu kết thúc b Nếu [A→α•] thuộc Ii đặt action[i, a] “thu gọn A→αn” cho a thuộc FOLLOW(A); A phải khác E’ c Nếu [E’ →E•] thuộc Ii đặt action [i, $] “chấp nhận” Nếu có đụng độ sinh luật ta nói văn phạm cho SLR(1) Thuật toán thông báo không sinh phân tích trường hợp Các bước chuyển goto cho trạng thái i xây dựng cho ký hiệu không kết thúc A luật: goto(Ii, A) = Ij action[i, A] = j Mọi vị trí không xác định luật đặt “lỗi” Trạng thái khởi đầu phân tích xây dựng từ tập mục có chứa [E’→•E] Bảng phân tích gọi bảng SLR(1) cho văn phạm G’ gọi tắt SLR 12 CHƯƠNG II: THỰC HÀNH Xây dựng bảng phân tích SLR cho văn phạm G Văn phạm G = P tập luật sinh sau: bexpr→bexpr or bterm | bterm bterm→bterm and bfactor | bterm bfactor→not bfactor | (bexpr) | true | false Để rút gọn ký hiệu, thuận lợi cho phân tích xây dựng bảng, ta ký hiệu lại văn phạm sau: STT Ký hiệu trước Not True false Or And Ký hiệu thay a b c + * STT Ký hiệu trước 10 ( ) Bexpr Bterm Bfactor Ký hiệu thay ( ) E T F Vậy, văn phạm G phát biểu lại thành: G = P tập luật sinh sau: E→E + T | T T→T * F | T F→a F | (E) | b | c 1.1 Xây dựng tập mục: Ta có văn phạm tăng cường G’ sau: E’→E E→E + T | T T→T * F | T F→a F | (E) | b | c 13 I0 E’→•E E→•E + T E→•T T→•T*F T→•T F→•aF F→•(E) F→•b F→•c I1 = goto(I0, E) E’→E• E→E•+ T I9 = goto(I3, F) F→aF• I10 = goto(I4, E) F→(E•) E→E•+ T I2 = goto(I0, T) E→T• T→T•* F T→T∙ I3 = goto(I0, a) F→a•F F→•aF F→•(E) F→•b F→•c I4 = goto(I0, ( ) F→(•E) E→•E + T E→•T T→•T*F T→•T I5 = goto(I0, b) F→b• I6 = goto(I0, c) F→c• I11 = goto(I7, T) E→E+T• T→T•* F T→T∙ I12 = goto(I8, F) T→T* F• I13= goto(I10, )) F→(E ) • 14 I7= goto(I1, +) E→E+•T T→•T*F T→•T I8 = goto(I2, *) T→T*•F F→•aF F→•(E) F→•b F→•c 1.2 Hàm FOLLOW Ta tính hàm FOLLOW cho ký hiệu chưa kết thúc sau: FOLLOW(E) = {+, ), $} FOLLOW(T) = FOLLOW(F) = {+, *, ), $} 1.3 Xây dựng bảng phân tích SLR Dựa vào tập mục hàm FOLLOW xây dựng trên, ta xây dựng bảng phân tích cú pháp SLR sau Trạng thái 10 11 12 13 a s3 b s5 c s7 ACTION + * s7 r2 s3 s3 s5 s5 s5 s5 s8 s6 s6 ) $ r2 acc r2 s4 s4 r6 r7 s3 s3 ( s4 r6 r7 11 r6 r7 s6 s6 r4 s8 r3 r5 12 r4 s13 r1 r3 r5 r4 r1 r3 r5 Ý nghĩa: si : chuyển trạng thái i ri : thu gọn luật sinh i acc: accept (chấp nhận) error : khoảng trống Áp dụng phân tích cú pháp câu Câu: not false or (true or false) chuyển thành : ac+(b+c) 15 10 r6 r7 s4 s4 r4 s7 r1 r3 r5 E GOTO T F 3 13 Stack (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) Input Action ac+(b+c)$ c+(b+c)$ +(b+c)$ +(b+c)$ +(b+c)$ +(b+c)$ +(b+c)$ (b+c)$ b+c)$ +c)$ +c)$ +c)$ +c)$ c)$ )$ )$ )$ )$ $ $ $ $ Acc 0a4 0a4c7 a F 10 0F3 0T2 0E1 0E1+8 0E1+8(5 0E1+8(5b6 0E1+8(5F3 0E1+8(5T2 E + ( E 11 E + ( E 11 + E + ( E 11 + c E + ( E 11 + F E + ( E 11 + T 12 E + ( E 11 E + ( E 11 ) 14 0E1+8F3 E + T 12 0E1 TÀI LIỆU THAM KHẢO [1] Phạm Hồng Nguyên, “Nhập môn Chương trình dịch” [2] Phạm Hồng Nguyên, “Giáo trình thực hành Chương trình dịch” [3] Aho, Sethi, Ullman, “Compilers – Principles, Techniques and Tools” [4] Bài giảng môn học Lý thuyết chương trình dịch – TS Hà Chí Trung – HV KTQS 16 [...]... action và hàm nhảy goto từ C bằng thuật toán dưới đây Nó đòi hỏi ta tính FOLLOW(A) cho mọi ký hiệu không kết thúc của văn phạm Thuật toán : Xây dựng một bảng phân tích SLR 1 2 3 4 5 Input: một văn phạm mở rộng G’ Output: Bảng phân tích SLR có các hàm action và goto cho G’ Phương pháp: Xây dựng C = {I0, I1,…, In} là tập các tập mục LR(0) cho G’ Trạng thái i được xây dựng từ I i Các hoạt động phân tích. .. 2.8 Bảng phân tích SLR Bây giờ ta sẽ xem cách xây dựng các hàm action và goto của phân tích SLR từ DFA dùng để nhận dạng các tiền tố có thể có Thuật toán này không phải luôn đưa ra được các bảng action cho mọi văn phạm, nhưng nó thành công đối với nhiều ngôn ngữ lập trình Cho một văn phạm G, ta mở rộng nó thành G’ và từ G’ ta xây dựng C là tập chuẩn của các tập mục cho G’ Ta xây dựng hàm phân tích. .. 1.2 Hàm FOLLOW Ta tính được hàm FOLLOW cho các ký hiệu chưa kết thúc như sau: FOLLOW(E) = {+, ), $} FOLLOW(T) = FOLLOW(F) = {+, *, ), $} 1.3 Xây dựng bảng phân tích SLR Dựa vào tập mục và hàm FOLLOW đã xây dựng ở trên, ta xây dựng được bảng phân tích cú pháp SLR như sau Trạng thái 0 1 2 3 4 5 6 7 8 9 10 11 12 13 a s3 b s5 c s7 ACTION + * s7 r2 s3 s3 s5 s5 s5 s5 s8 s6 s6 ) $ r2 acc r2 s4 s4 r6 r7 s3... được bộ phân tích trong trường hợp này Các bước chuyển goto cho trạng thái i được xây dựng cho mọi ký hiệu không kết thúc A bằng luật: nếu goto(Ii, A) = Ij thì action[i, A] = j Mọi vị trí không được xác định bằng luật 2 và 3 sẽ được đặt là “lỗi” Trạng thái khởi đầu của bộ phân tích được xây dựng từ tập mục có chứa [E’→•E] Bảng phân tích ở trên được gọi là bảng SLR( 1) cho văn phạm G’ và gọi tắt là SLR 12... gọi tắt là SLR 12 CHƯƠNG II: THỰC HÀNH 1 Xây dựng bảng phân tích SLR cho văn phạm G Văn phạm G = P là tập các luật sinh như sau: bexpr→bexpr or bterm | bterm bterm→bterm and bfactor | bterm bfactor→not bfactor | (bexpr) | true | false Để rút gọn các ký hiệu, thuận lợi cho phân tích và xây dựng bảng, ta ký hiệu lại văn phạm như sau:... quy tắc sau cho đến khi không thể thêm gì vào mọi tập FOLLOW được nữa 1 Ðặt $ vào follow(S), trong đó S là ký hiệu bắt đầu của văn phạm và $ là ký hiệu kết thúc chuỗi nhập 2 Nếu có một luật sinh A→ αBβ thì thêm mọi phần tử khác ε của FIRST(β )và trong FOLLOW(B) 3 Nếu có luật sinh A→ αB hoặc A→ αBβ mà ε ∈ FIRST(β) thì thêm tất cả các phần tử trong FOLLOW(A) vào FOLLOW(B) Ví dụ: Với văn phạm trong ví... r7 s3 s3 ( s4 r6 r7 11 r6 r7 s6 s6 r4 s8 r3 r5 12 r4 s13 r1 r3 r5 r4 r1 r3 r5 Ý nghĩa: si : chuyển trạng thái i ri : thu gọn bởi luật sinh i acc: accept (chấp nhận) error : khoảng trống 2 Áp dụng phân tích cú pháp của câu Câu: not false or (true or false) được chuyển thành : ac+(b+c) 15 2 10 3 r6 r7 s4 s4 r4 s7 r1 r3 r5 E 1 GOTO T F 2 3 3 13 Stack (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13)... Nếu [A→α•aβ] thuộc Ii và goto(Ii, a) = Ij thì đặt action[i, a] thành “gạt j” Ở đây a phải là một ký hiệu kết thúc b Nếu [A→α•] thuộc Ii thì đặt action[i, a] là “thu gọn A→αn” cho mọi a thuộc FOLLOW(A); ở đây A phải khác E’ c Nếu [E’ →E•] thuộc Ii thì đặt action [i, $] là “chấp nhận” Nếu có bất kỳ đụng độ nào được sinh ra bằng các luật trên thì ta nói văn phạm đã cho không phải là SLR( 1) Thuật toán thông... Bfactor Ký hiệu thay thế ( ) E T F Vậy, văn phạm G có thể phát biểu lại thành: G = P là tập các luật sinh như sau: E→E + T | T T→T * F | T F→a F | (E) | b | c 1.1 Xây dựng tập mục: Ta có văn phạm tăng cường G’ như sau: E’→E E→E + T | T T→T * F | T F→a F | (E) | b | c 13 I0 E’→•E E→•E + T E→•T T→•T*F T→•T F→•aF F→•(E) F→•b F→•c I1 = goto(I0, E) E’→E• E→E•+ T I9 = goto(I3,