Viết chương trình phân tích cú pháp theo phương pháp earley

18 0 0
Viết chương trình phân tích cú pháp theo phương pháp earley

Đ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

TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP HÀ NỘI KHOA CÔNG NGHỆ THƠNG TIN ––––––  –––––– BÀI TẬP LỚN Mơn: Automata ngơn ngữ hình thức Đề tài: Viết chương trình phân tích cú pháp theo phương pháp Earley Có trình bày bước tính tốn dẫn xuất có Giáo viên hướng dẫn: Trần Hùng Cường Nhóm SV thực hiện: Phan Huy Anh Nguyễn Việt Hoài Nguyễn Đình Phú Khánh Lương Thế Lộc Lớp: ĐH KHMT1 - K2 Hà Nội, tháng năm 2010 MỤC LỤC Tóm tắt Giải thuật Earley a Khởi tạo .4 b Thuật toán +) Dự đoán +) Duyệt .5 +) Hoàn thiện Chương trình phân tích cú pháp câu theo phương pháp Early Parser Tóm tắt Giải thuật Earley là mợt giải thuật bản, sử dụng tương đối rộng rãi các hệ thống phân tích cú pháp Tuy nhiên, giải thuật này hạn chế sinh quá nhiều luật dư thừa quá trình phân tích Trong bài này, chúng tơi đề xuất phương pháp phân tích cú pháp theo giải thuật Earley Giải thuật Earley là một giải thuật sử dụng phổ biến việc xây dựng các hệ thống phân tích cú pháp Giải thuật này sử dụng chiến lược phân tích kiểu xuống (top-down), bắt đầu với một ký hiệu không kết thúc đại diện cho câu và sử dụng các luật khai triển cho đến thu câu vào Hạn chế cách tiếp cận này là không chú trọng nhiều đến các từ đầu vào Vì quá trình phân tích, giải thuật Earley sản sinh nhiều luật dư thừa.Ngoài ra, giải thuật Earley xây dựng cho tiếng Anh nên áp dụng cho tiếng Việt có hạn chế Mỗi câu vào tiếng Anh có mợt cách tách từ, với tiếng Việt, câu vào có nhiều cách tách từ khác Với đặc điểm đầu vào giải thuật Earley là một câu với mợt cách tách, bợ phân tích cú pháp phải thực hiện lặp lặp lại giải thuật này cho trường hợp tách từ tiếng Việt Để giải quyết vấn đề này, chúng nhận thấy các cách tách từ Việt tồn các cặp cách tách giống danh sách các từ loại và khác phần đuôi chúng Giải thuật Earley bản, giúp người đọc hình dung mợt cách khái quát giải thuật này Giải thuật Earley Giải thuật Earley phát biểu sau: Đầu vào: Văn phạm G = (N, T, S, P), đó: • N: tập kí hiệu khơng kết thúc • T: tập kí hiệu kết thúc • S: kí hiệu khơng kết thúc bắt đầu • P: tập luật cú pháp Xâu vào w = a1a2 an Đầu ra: Phân tích w "sai" Kí hiệu: • α, β, γ biểu diễn xâu chứa các kí hiệu kết thúc, khơng kết thúc rỗng • X, Y, Z biểu diễn các kí hiệu khơng kết thúc đơn • a biểu diễn kí hiệu kết thúc Earley sử dụng cách biểu diễn luật thơng qua dấu chấm “• ” X→ α • β có nghĩa : • Trong P có mợt luật sản xuất X→ α β • α phân tích • β chờ phân tích • Khi dấu chấm “ • ” chuyển sau β có nghĩa là mợt luật hoàn thiện Thành phần X phân tích đầy đủ, ngược lại là mợt luật chưa hoàn thiện Đối với từ thứ j xâu đầu vào, bộ phân tích khởi tạo mợt bợ có thứ tự các trạng thái S(j) Mỗi bộ tương ứng với một cột bảng phân tích Mỗi trạng thái có dạng (X → α • β, i), thành phần sau dấu phẩy xác định luật này phát sinh từ cột thứ i a.Khởi tạo • S(0) khởi tạo chứa ROOT → • S • Nếu bợ cuối ta có luật (ROOT → S•, 0) thì có nghĩa xâu vào phân tích thành cơng b Thuật tốn Thuật toán phân tích thực hiện bước: Dự đoán (Predictor), Duyệt (Scanner), và Hoàn thiện (Completer) bợ S(j) +) Dự đốn Với trạng thái S(j): (X → α • Y β, i), ta thêm trạng thái (Y → • γ, j) vào S(j) nếu có luật sản xuất Y → γ P +) Duyệt Nếu a là kí hiệu kết thúc tiếp theo Với trạng thái S(j): (X → α • a β, i), ta thêm trạng thái (X → α a • β, i) vào S(j+1) +) Hồn thiện Với trạng thái S(j): (X → γ• , i), ta tìm S(i) trạng thái (Y → α • X β, k), sau thêm (Y → α X • β, k) vào S(j) Ở bộ S(j) phải kiểm tra xem trạng thái có chưa trước thêm vào để tránh trùng lặp Để minh họa cho thuật toán trên, chúng ta phân tích câu “học sinh học sinh học” với tập luật cú pháp sau: S → N VP S → P VP S → N AP S → VP AP VP → V N VP → V NP NP → N N NP → N A AP → R A N → học sinh N → sinh học V → học V → sinh AP – cụm tính từ P – đại từ N – danh từ V – đợng từ A – tính từ R – phụ từ Trong đó: S – câu VP – cụm động từ NP – cụm danh từ Do câu có nhiều cách tách từ, đầu vào giải thuật Earley là một câu với một cách tách từ nên chúng minh họa giải thuật Earley với cách tách từ trường hợp câu phân tích là: học sinh, học, sinh học Bảng phân tích cho cách tách này sau: Cợt ROOT • S, S •N VP, S •P VP, S •N AP, S •VP AP, VP •V N, VP •V NP, N •học sinh, N •sinh học, V •học, N học sinh•, S N •VP, S N •AP, VP •V N, VP •V NP, AP •R A, V •học, V học•, VP V •N, VP V •NP, NP •N N, NP •N A, N •học sinh, N •sinh học, N sinh học•, VP V N•, NP N •N, NP N •A, S N VP•, ROOT S•, Bảng Bảng minh họa giải thuật Earley Chương trình phân tích cú pháp câu theo phương pháp Early Parser #include #include #include #include #include using namespace std; #define #define #define #define #define noun verb_i verb_t adj aux 16 #define pro #define det #define prep 32 64 128 #define #define #define #define #define #define SENT NP VP PP NP2 NP3 256 257 258 259 260 261 #define #define #define #define LHS NUMRHS DOT TABLE void nhapDanhTu(map &TL) { fstream fin; fin.open("noun.txt"); int n; fin >> n; string str; for (int i = 0; i < n; i++) { fin >> str; TL[str] = TL[str] | noun; } } fin.close(); void nhapNoiDongTu(map &TL) { fstream fin; fin.open("verb_i.txt"); int n; fin >> n; string str; for (int i = 0; i < n; i++) { fin >> str; TL[str] = TL[str] | verb_i; } fin.close(); } void nhapNgoaiDongTu(map &TL) { fstream fin; fin.open("verb_t.txt"); int n; fin >> n; string str; for (int i = 0; i < n; i++) { fin >> str; TL[str] = TL[str] | verb_t; } fin.close(); } void nhapTinhTu(map &TL) { fstream fin; fin.open("adj.txt"); int n; fin >> n; string str; for (int i = 0; i < n; i++) { fin >> str; TL[str] = TL[str] | adj; } fin.close(); } void nhapGioiTu(map &TL) { fstream fin; fin.open("prep.txt"); int n; fin >> n; string str; for (int i = 0; i < n; i++) { fin >> str; TL[str] = TL[str] | prep; } fin.close(); } void nhapMaoTu(map &TL) { fstream fin; fin.open("det.txt"); int n; fin >> n; string str; for (int i = 0; i < n; i++) { fin >> str; TL[str] = TL[str] | det; } } fin.close(); void nhapDaiTu(map &TL) { fstream fin; fin.open("pro.txt"); int n; fin >> n; string str; for (int i = 0; i < n; i++) { fin >> str; TL[str] = TL[str] | pro; } } fin.close(); void nhapTroDongTu(map &TL) { fstream fin; fin.open("auxi.txt"); int n; fin >> n; string str; for (int i = 0; i < n; i++) { fin >> str; TL[str] = TL[str] | aux; } } fin.close(); void nhapDanhSachLuat(vector Luat[], int &iNumRule) { map BangTra; BangTra["noun"] = noun; BangTra["verb_i"] = verb_i; BangTra["verb_t"] = verb_t; BangTra["adj"] = adj; BangTra["prep"] = prep; BangTra["pro"] = pro; BangTra["aux"] = aux; BangTra["det"] = det; BangTra["S"] = SENT; BangTra["NP"] = NP; BangTra["VP"] = VP; BangTra["PP"] = PP; BangTra["NP2"] = NP2; BangTra["NP3"] = NP3; fstream fin; char str[100]; fin.open("Rules.txt"); fin >> iNumRule; fin.getline(str, 100, '\n'); for (int i = 0; i < iNumRule; i++) { fin.getline(str, 100, '\n'); int j = 0; int k; char* p = strtok(str, "-> ,+"); while (p != NULL) { if (j == 0) { j++; k = BangTra[p]; Luat[i].push_back(k); Luat[i].push_back(0); Luat[i].push_back(0); Luat[i].push_back(0); } else { Luat[i].push_back(BangTra[p]); 10 Luat[i][1]++; } p = strtok(NULL, "-> ,+"); } } fin.close(); } void nhapCauInput(vector &Cau) { Cau.clear(); char str[100]; gets(str); } char* p = strtok(str, " "); while ( p != NULL) { Cau.push_back(p); p = strtok(NULL, " "); } bool isTerminal(int term) { return (term < 128); } bool DauChamCuoiCau(vector &Luat) { return (Luat[DOT] == Luat[NUMRHS]); } // Tu loa va tu loai phai la cac terminal bool CungTuLoai(int TuLoai1, int TuLoai2) { if ( (TuLoai1 & TuLoai2) != 0) return true; else return false; } void thuatToan(vector Cau, vector Luat[], map &TuLoai, int iNumRule, vector Table[]) { /* Trong chua ket thuc cau Lay tu kiem tra tu loai cua tu Tim bang truoc nhung cau co chi so la n-1 Neu tu loai sau dau cham = tu loai cua tu dang xet Dich chuyen cac dau cham, nho cap nhat lai chi so cua cau Voi moi cau vua cap nhat lai chi so Neu dau cham truoc non-terminal thi trien khai else Neu dau cham truoc terminal 11 thi khong trien khai else Neu dau cham nam o cuoi cung Backtracking */ int i; int n = Cau.size(); // Init i = 0; while (i < iNumRule) { if (Luat[i][LHS] == SENT) { //Luat[i][TABLE] = -1; Table[0].push_back(Luat[i]); } i++; } int j = 0; int num = Table[0].size(); vector DSKhaiTrien; while(j < num) { int pos = Table[0][j][DOT]; int iTuLoai = Table[0][j][pos+4]; int flag = 0; for (int l = 0; l < DSKhaiTrien.size(); l++) if (DSKhaiTrien[l] == iTuLoai) flag = 1; if ( flag == && !isTerminal(iTuLoai)) { DSKhaiTrien.push_back(iTuLoai); for(int k = 0; k < iNumRule; k++) { if (Luat[k][LHS] == iTuLoai) { vector temp (Luat[k]); temp[TABLE] = 0; Table[0].push_back(temp); } } } } j++; DSKhaiTrien.clear(); //////////////////////////////////////////////////////////////////////// ////////////////// int flag; 12 // Vong lap thuat toan i = 1; while (i

Ngày đăng: 29/09/2023, 12:51

Tài liệu cùng người dùng

Tài liệu liên quan