Bài toán phân tích cú pháp Phương pháp phân tích cú pháp quay lui Phương pháp phân tích cú pháp tất định Xây dựng bộ phân tích cú pháp cho KPL Kiểm tra xâu phân tích từ trái qua phải Kiểm tra ký hiệu trái nhất của xâu cần phân tích Tới ký hiệu tiếp,.. Cho tới ký hiệu cuối cùng Phương pháp xây dựng cây phân tích
Xây dựng CHƯƠNG TRÌNH DỊCH Phạm Đăng Hải haipd@soict.hut.edu.vn Chương 3: Phân tích cú pháp Bài tốn phân tích cú pháp Phương pháp phân tích cú pháp quay lui Phương pháp phân tích cú pháp tất định Xây dựng phân tích cú pháp cho KPL 05/12/21 Bài tốn phân tích cú pháp Bài toán đặt Cho – Văn phạm phi ngữ cảnh G G = (VT, VN, P, S) – Xâu ω V*T Hỏi – ω∈ L(G)? Nếu ω ∈ L(G) Trong chương trình dịch, xâu ω chuỗi token thu từ giai đoạn trước – phân tích từ vựng – Chỉ sản xuất sử dụng để sinh ω – Cấu trúc nên suy dẫn 05/12/21 Bài tốn phân tích cú pháp Phương pháp phân tích • Kiểm tra xâu phân tích từ trái qua phải – Kiểm tra ký hiệu trái xâu cần phân tích – Tới ký hiệu tiếp, Cho tới ký hiệu cuối • Phương pháp xây dựng phân tích – Trên xuống (Top-down): S ⇒* ω? – Dưới lên (Bottom-up): ω *⇐ S? • Phương pháp lựa chọn sản xuất (A→α1|…|αn) – Quay lui (backtracking) • Thử sản xuất – Tất định (deterministic) • Xác định sản xuất thích hợp 05/12/21 Bài tốn phân tích cú pháp Phân tích trái • • Phân tích trái xâu α dãy sản xuất sử dụng suy dẫn trái từ S α Các sản xuất đánh số thứ tự 1, p – Phân tích danh sách số từ đến p • Ví dụ cho văn phạm E → T+E E → T T → F* T T → F F → (E) F → a Xét xâu a*(a+a) E ⇒2 T ⇒3 F*T ⇒6 a*T ⇒4 a*F ⇒5a*(E) ⇒1 a*(T+E) ⇒4 a*(F+E) Phân tích trái xâu a*(a+a) 23645146246 ⇒6 a*(a+E) ⇒2 a*(a+T) ⇒4 a*(a+F) ⇒6 a*(a+a) 05/12/21 Chương 3: Phân tích cú pháp Giới thiệu Phương pháp phân tích cú pháp quay lui Phương pháp phân tích cú pháp tất định Xây dựng phân tích cú pháp cho KPL 05/12/21 Phương pháp phân tích quay lui Giới thiệu • Tư tưởng chủ yếu giải thuật – Xây dựng phân tích cú pháp (cây suy dẫn) cho xâu ω • Thuật tốn Top-down – Đi từ nút gốc tới nút • Thuật tốn Bottom –up – Q trình phân tích gạt thu gọn 05/12/21 Phương pháp phân tích quay lui Thuật toán Top-down Cho VPPNC G = (VT, VN, P, S) ∀ sản xuất A→α1|…|αn đánh số 1, 2, Xây dựng phân tích cho xâu ω: Khởi tạo - Xây dựng có nút gốc S - S (Start symbol): Ký hiệu khởi đầu - Gọi ký hiệu cần phân tích ký hiệu xâu ω Gọi S nút hoạt động, 05/12/21 Phương pháp phân tích quay lui Thuật toán Top-down Tạo nút (một cách đệ quy) Nút hoạt động ký hiệu không kết thúc A – Chọn sản xuất A chưa áp dụng: A →X1X2 .Xk (k ≥ 0) – Tạo k trực tiếp A với nhãn X1, X2, Xk – Nếu k > 0, Lấy X1 làm nút hoạt động – Nếu k = 0, (sản xuất A → ε), lấy nút bên phải (ngay sau) A nút hoạt động Tiếp tục thực bước 05/12/21 Phương pháp phân tích quay lui Thuật tốn Top-down Tạo nút (một cách đệ quy) Nút hoạt động ký hiệu kết thúc a - So sánh a với ký hiệu cần phân tích – Nếu trùng • Nút hoạt động nút bên phải a • Ký hiệu cần phân tích ký hiệu xâu vào – Nếu khơng trùng • Quay lại bước sử dụng sản xuất thử sản xuất tiếp – Nếu hết khả năng, quay lại bước trước 05/12/21 10 Phương pháp phân tích tất định Tìm danh sách sản xuất sử dụng →Ví dụ A + B A S B void S(){ sx[n++]=‘1’; B(); A(); } 05/12/21 A void A(){ if( Ch==‘+’) { sx[n++]=‘2’; nextCh(); B(); A(); }else sx[n++]=‘3’; } 85 Chương 3: Phân tích cú pháp Giới thiệu Phương pháp phân tích cú pháp quay lui Phương pháp phân tích cú pháp tất định Xây dựng phân tích cú pháp cho KPL 05/12/21 86 Phương pháp phân tích tất định Nguyên tắc • Văn phạm KPL LL(1) – Sử dụng phương pháp phân tích xem trước • Bảng phân tích lớn – Dùng phương pháp đệ quy xuống • Bộ phân tích cú pháp – Gồm tập thủ tục, thủ tục ứng với sơ đồ – Luôn đọc trước ký hiệu/từ tố • Xem trước từ tố cho phép chọn đường gặp điểm rẽ nhánh sơ đồ cú pháp – Khi thoát khỏi thủ tục triển khai đích, ln có từ tố đọc dơi 05/12/21 87 Phương pháp phân tích tất định Các thủ tục • • • • • • • • • • Token * getToken() //phân tích từ vựng void error (const char msg[]);//Báo lỗi void factor(void);//phân tích nhân tử void term(void);//phân tích số hạng void expression(void); // phân tích biểu thức void condition(void); // phân tích điều kiện void statement(void); // phân tích câu lệnh void block(void); // phân tích khối câu lệnh void basictype(void); // kiểu biến void program(); //Phân tích chương trình 05/12/21 88 Phương pháp phân tích tất định Term void term() { factor(); while(Token == times || Token == slash) { getToken(); factor(); } } 05/12/21 89 Phương pháp phân tích tất định Term (Thực hành KPL) ::= := Times := Slash void Term(){ Factor(); Term2(); } 05/12/21 FOLLOW( := ε void Term2(){ switch(Token){ case Times: Eat(Times); Factor(); Term2(); break; case Slash:… case KW_TO : case KW_DO : …………… case KW_END : break; Default: Error(Invalid Term) } 90 Phương pháp phân tích tất định Expression void expression() { if(Token== plus || Token == minus) getToken(); term(); while(Token == plus || Token == minus){ getToken(); term(); } } 05/12/21 91 Phương pháp phân tích tất định Expression (Thực hành KPL) ::= Plus ::= Minus ::= ::= ::=Plus ::=Minus ::= ε void compileExpression2() { compileTerm(); compileExpression3(); } 05/12/21 void compileExpression() { switch (Token) { case SB_PLUS: eat(SB_PLUS); Expression2(); break; case SB_MINUS: eat(Minus); Expression2(); break; default: Expression2(); } } 92 Phương pháp phân tích tất định Expression (Thực hành KPL) void compileExpression3() { switch (Token) { case Plus: eat(Plus); compileTerm(); compileExpression3(); break; case Minus: eat(Minus); compileTerm(); compileExpression3(); break; 05/12/21 // check the FOLLOW set case KW_TO: case KW_DO: case SB_RPAR: case SB_COMMA: case SB_EQ: case SB_NEQ: case SB_LE: case SB_LT: case SB_GE: case SB_GT: case SB_RSEL: case SB_SEMICOLON: case KW_END: case KW_ELSE: case KW_THEN: break; default: Error(Lỗi biểu thức); } }//compileExpression() 93 Phương pháp phân tích tất định Condition void condition() { expression(); if(Token == eql || Token == neq || Token == lss || Token == leq || Token == grt || Token == geq){ getsym(); expression(); }else { error("condition: syntax error"); } } 05/12/21 94 Phương pháp phân tích tất định Statement 05/12/21 95 Phương pháp phân tích tất định Statement void statement() { if(Token==Ident){ //variable := getToken(); //array variable ? if(Token==assign){ getToken(); Expresion(); }else Error(“Thieu toan tu gan”) } else… } 05/12/21 96 Phương pháp phân tích tất định Statement if (Token == KW_CALL){ getToken(); if(Token == Ident){ if(Token == Lparen){ getToken(); Expression(); while(Token==comma){ getToken(); Expression(); } if(Token = Rparen) getToken() else Error(“Thiếu dấu đóng ngoặc); } }else Error(“Thiếu tên thủ tục/hàm”); }else 05/12/21 97 Phương pháp phân tích tất định Statement if (Token == KW_BEGIN){ getToken() Statement(); while (Token == Semicolon) { getToken(); Statement(); } if(Token==KW_END) getToken() else Error(“Thiếu từ khóa End”); }else 05/12/21 98 Phương pháp phân tích tất định Program void Program(){ if(Token=KW_PROGRAM){ getToken(); if (Token==Ident){ getToken(); if(Token==Semicolon){ getToken(); Block(); if(Token==Period) printf(“Thành công”); else Error(“Thiếu dấu ”); }else Error(“Thiếu dấu chấm phẩy”); }else Error(“Thiếu tên chương trình”); }else Error(Thiếu từ khóa Program) } 05/12/21 99 .. .Chương 3: Phân tích cú pháp Bài tốn phân tích cú pháp Phương pháp phân tích cú pháp quay lui Phương pháp phân tích cú pháp tất định Xây dựng phân tích cú pháp cho KPL 05/12/21 Bài tốn phân tích. .. Phương pháp phân tích cú pháp tất định Xây dựng phân tích cú pháp cho KPL 05/12/21 Phương pháp phân tích quay lui Giới thiệu • Tư tưởng chủ yếu giải thuật – Xây dựng phân tích cú pháp (cây suy dẫn)... lớn chương trình phải phân tích gồm nhiều ký hiệu (từ tố) Không thể thông báo lỗi chi tiết 05/12/21 24 Chương 3: Phân tích cú pháp Giới thiệu Phương pháp phân tích cú pháp quay lui Phương pháp phân