GIẢI PHÁP KIỂM TRA TÍNH ĐÚNG CỦA VĂN PHẠM PHI NGỮ CẢNH
90 Nguyễn Thị Minh Hỷ, Trần Hồ Thủy Tiên GIẢI PHÁP KIỂM TRA TÍNH ĐÚNG CỦA VĂN PHẠM PHI NGỮ CẢNH A METHOD TO CHECK THE ACCURACY OF CONTEXT-FREE GRAMMAR Nguyễn Thị Minh Hỷ, Trần Hồ Thủy Tiên Trường Đại học Bách khoa, Đại học Đà Nẵng Minhy81199@yahoo.com; thttien@dut.udn.vn Tóm tắt - Ngơn ngữ biểu diễn nhiều cách khác nhau, nhiên ngôn ngữ có cầu trúc cần phải có văn phạm để biểu diễn Một văn phạm phi ngữ cảnh sản sinh ngơn ngữ Bài báo giới thiệu phương pháp nhằm kiểm tra tính văn phạm phi ngữ cảnh cách bước kiểm tra tính xác thành phần tạo nên văn phạm Phương pháp đề xuất bao gồm cơng việc sau: kiểm tra cấu tạo ký hiệu kết thúc ký hiệu chưa kết thúc, kiểm tra việc sử dụng ký hiệu để tạo sản xuất, kiểm tra sản xuất có vi phạm điều kiện để tạo ngôn ngữ hay không? Giải pháp đề xuất ứng dụng để kiểm tra văn phạm phi ngữ cảnh trước hoạt động để sản sinh ngôn ngữ, phục vụ cho việc giảng dạy Abstract - Languages can be represented in many different ways, but structured languages usually use correct grammar for representation Only an exact context - free grammar can generate a language This paper introduces a method to check the accuracy of context-free grammar; particularly, checking the accuracy of components forming this grammar step by step The proposed method consists of some major tasks such as checking the structure of terminals as well as non-terminals, verifying the use of these symbols to create the productions and checking up whether a production has met the conditions for constructing a language The proposed method can be applied to check a context-free grammar before it produces a language for the purpose of teaching Từ khóa - văn phạm phi ngữ cảnh; vế trái; vế phải; sản xuất; ký hiệu chưa kết thúc; ký hiệu kết thúc Key words - context - free grammar; the left side; the right side; production; non-terminal; terminal Đặt vấn đề Ngày nay, nhu cầu sử dụng công nghệ thông tin ngày nhiều, lúc, nơi, lĩnh vực nên vấn đề tạo loại ngơn ngữ lập trình cần thiết Một chương trình dãy câu lệnh, câu lệnh dãy từ, từ tạo từ ký tự Chương trình, câu lệnh, từ (hay gọi xâu) tạo theo qui tắc định, qui tắc văn phạm Hay nói cách khác, văn phạm chế để sản sinh ngơn ngữ Chương trình trước thực thi phải thơng qua giai đoạn biên dịch để kiểm tra xem có bị lỗi từ vựng hay lỗi cú pháp không Để việc kiểm tra xác, địi hỏi việc xây dựng văn phạm để tạo ngơn ngữ lập trình phải xác Do việc đưa giải pháp để kiểm tra tính văn phạm phi ngữ cảnh cần thiết - Không ký hiệu kết thúc chưa kết thúc chưa sử dụng sản xuất - Khơng có sản xuất vế phải vế trái - Khơng có ký hiệu vơ sinh: Tính văn phạm phi ngữ cảnh Văn phạm phi ngữ cảnh G [1], [3], [4] xác định thông qua thành phần: , , S, P : tập ký hiệu kết thúc : tập ký hiệu chưa kết thúc S: ký hiệu bắt đầu, S P: tập sản xuất có dạng A với A; ()*; A vế trái; vế phải Ví dụ: S0S | 1S | | Văn phạm phi ngữ cảnh sản sinh ngôn ngữ số nhị phân Một văn phạm phi ngữ cảnh sản sinh ngơn ngữ Văn phạm phải thỏa mãn điều kiện sau: - Không sử dụng dấu cách ký hiệu Ký hiệu A gọi ký hiệu vô sinh * A≠+ - Khơng có ký hiệu khơng đạt đến Ký hiệu A gọi ký hiệu không đạt đến S ≠+ A Giải pháp thực Giải pháp đề xây dựng lớp đối tượng để mô tả thành phần văn phạm hoạt động kiểm tra thành phần Đầu vào: Văn phạm phi ngữ cảnh G(, , S, p) Đầu ra: Văn phạm G hay không Thiết kế cấu trúc liệu: - Cấu trúc lưu trữ sản xuất public struct clsanxuat{ //vế trái sản xuất public string vetrai; //vế phải sản xuất public string[] vephai; //vế phải sản xuất public string[] vephai; //số ký hiệu vế phải public int sokhvephai; } - Lớp văn phạm clvanpham ISSN 1859-1531 - TẠP CHÍ KHOA HỌC VÀ CƠNG NGHỆ ĐẠI HỌC ĐÀ NẴNG, SỐ 7(104).2016 public class clvanpham{ //tập ký hiệu kết thúc public static IList khkt; //tập ký hiệu chưa kết thúc public static IList khckt; //ký hiệu bắt đầu public static IList khckt ; //tập ký hiệu chưa kết thúc public static string khbd; //số sản xuất public static int sosx; //tập sản xuất public static clsanxuat[] sanxuat; // Hàm kiểm tra tất ký hiệu văn phạm có sử dụng dấu cách khơng? private bool kokyhieusudungdaucach(){ foreach(string obj in clvanpham.khkt) f(obj.indexof(“ ”)!=-1) return false; foreach(string obj in clvanpham.khckt) if(obj.indexof(“ ”)!=-1) return false; return true; } //Hàm kiểm tra ký hiệu kết thúc a có? private static bool dasudungkhkt(string a) { foreach (clsanxuat obj in clvanpham.sanxuat) if (obj.vephai.Contains(a)) return true; return false; } //Hàm xác định tập ký hiệu kết thúc chưa sử dụng private static IList tapkhktchuasudung(){ IList t = new List(); foreach (string obj in clvanpham.khkt) if (!dasudungkhkt(obj)) t.Add(obj); return t; } //Hàm kiểm tra ký hiệu chưa kết thúc A sử dụng chưa? private static bool dasudungkhckt(string A){ foreach (clsanxuat obj in clvanpham.sanxuat) if (obj.vetrai == A) return true; if (dasudungkhkt(A)) return true; return false; } //Hàm xác định tập ký hiệu chưa kết thúc chưa sử dụng private static IList tapkhcktchuasudung() { IList t = new List(); foreach (string obj in clvanpham.khckt) if (!dasudungkhckt(obj)) t.Add(obj); 91 return t; } //Hàm kiểm tra văn phạm có sản xuất mà vế trái vế phải hay không? private bool kosxvetraibangvephai(){ foreach(clsanxuat obj in clvanpham.sanxuat) if((obj.vetrai.trim()==obj.vephai[0].trim()) &&(obj.vephai.count==1)) return false; return true; } //Hàm kiểm tra ký hiệu chưa kết thúc A có phải ký hiệu không vô sinh không? private static bool kovosinh(string A){ bool ok = false; if((A=="epsilon")|| (clvanpham.khkt.Contains(A))) return true; for (int i = 0; i < clvanpham.sosx; i++) if (clvanpham.sanxuat[i].vetrai == A){ ok = true; break; } if (!ok) return false; for (int i = 0; i < clvanpham.sosx; i++) if((clvanpham.sanxuat[i].vetrai==A)&& (!clvanpham.sanxuat[i].vephai.Contains(A))){ ok = true; for(int j=0; j