Quy trình thực thi của JPlag

Một phần của tài liệu Nghiên cứu giải pháp và công cụ hỗ trợ gợi ý sửa lỗi cho các chương trình java (Trang 30 - 32)

3.3.2. Phân tích chương trình thành chuỗi các Tokens

Các chương trình cần so sánh được phân tích thành các thẻ Tokens, việc này được hiểu là chuyển các dòng lệnh sang dạng các mã thông báo, các mã thông báo là căn cứ để so sánh ở bước sau. Mã thông báo đặc trưng cho bản chất của câu lệnh chứ không phụ thuộc vào hình thức thể hiện của tên biến, tên hàm. Ngoài ra JPlag cũng quy định các lời gọi phương thức, các ngoại lệ, dòng chú thích hay các dòng trắng sẽ không được gắn mã thông báo, do đây là điểm dễ thay đổi mà không ảnh hưởng đến chương trình. Danh sách các mã thông báo đầy đủ trong phụ lục mã Tokens của công cụ JPlag tại phần cuối của luận văn.

Để hiểu về cách phân tích chượng trình thành các mã thông báo ta xem xét ví dụ Mã nguồn 3.2. Dòng 1, 4, 18, 19, 20 là các dòng chú thích, không được gắn mã thông báo. Dòng 17 là dòng trống, dòng 22 là ngoại lệ cũng bị bỏ qua không gắn mã. Các dòng còn lại được chuyển thành các mã thông báo (sau đây gọi là các Tokens) phản ánh đúng ý nghĩa của câu lệnh. Các dòng lệnh bắt đầu và kết thúc class, hàm, vòng lặp, khởi tạo một đối tượng được chuyển thành các Tokens đặc trưng với BEGINCLASS, BEGINMENTHOD, BEGINWHILE, BEGINIF và ENDCLASS,ENDMENTHOD, ENDWHILE, ENDIF. Dòng 3 khởi tạo lớp được chuyển thành Token BEGINCLASS. Dòng 5 khởi tạo một phượng thức và khai báo 2 biến đầu vào nên được chuyển thành 2 Tokens VARDEF và Token BEGINMENTHOD. Dòng lệnh 6, 7 là bắt đầu câu lệnh while và if được chuyển thành Tokens BEGINWHILE và BEGINIF. Các câu lệnh 8 và 10 là câu lệnh gán giá trị cho biến, vì vậy dù là 2 câu lệnh khác nhau nhưng đều được chuyển thành Token ASSIGN. Tượng tự với những câu lệnh khác.

20

Code Tokens

1 //import your library

2 import java.util.Scanner; IMPORT

3 public class Solution { BEGINCLASS

4 //Type your main code here

5 public static int gcd(int a, int b){ VARDEF, VARDEF,

BEGINMENTHOD

6 if (a==0) BEGINIF

7 return b; RETURN, ENDIF

8 while (a != b) { BEGINWHILE 9 if (a > b) { BEGINIF 10 a -= b; ASSIGN 11 } else { ELSE 12 b -= a; ASSIGN 13 } ENDIF 14 } ENDWWHILE 15 return a; RETURN 16 } ENDMENTHOD 17 18 /** 19 * Main. 20 */

21 public static void main(String[] args) VARDEF, BEGINMENTHOD

22 throws java.io.IOException {

23 int gcd; VARDEF

24 Scanner sc = newScanner(System.in); VARDEF,NEWCLASS,ASSIGN

25 int a = sc.nextInt(); VARDEF, ASSIGN

26 int b = sc.nextInt(); VARDEF, ASSIGN

27 gcd = gcd(a,b); ASSIGN

28 System.out.println(gcd); APPLY

29 } ENDMENTHOD

30 } ENDCLASS

Mã nguồn 3.2. Tách mã nguồn thành các Tokens

Chuyển chương trình thành các Tokens có ý nghĩa lớn trong khâu so sánh tại bước tiếp theo của bài toán này. Việc so sánh kiểu từ với từ giữa các chương trình để tìm chương trình tương đương là không khả thi. Bởi vì học sinh ở giai đoạn mới lập trình thường được yêu cầu sử dụng các chú thích để giải thích đoạn lệnh nên chương trình của mỗi học sinh có nhiều chú thích khác nhau. Ngoài ra do học sinh chưa hoàn thiện thói quen định dạng code nên các lệnh có sử dụng mở đóng ngoặc có thể bị dịch xuống nhiều dòng, thừa dòng trắng giữa các câu lệnh. Việc chuyển mã chương trình

21

thành các mã thông báo giúp giải quyết các vấn đề trên, cho phép tìm ra các chương trình đúng có độ tương tự tốt nhất với chương trình đang cần sửa chữa.

3.3.3. So sánh các chuỗi Tokens

Đầu vào của mô-đun gợi ý chương trình là chương trình lỗi của học sinh và rất nhiều chương trình mẫu khác được lưu trong bộ sưu tập. Vì vậy, việc so sánh được hiểu là so sánh chương trình lỗi với tất cả các chương trình mẫu trong bộ sưu tập. Để thực hiện việc này, chương trình lỗi sẽ so sánh lần lượt với từng chương trình mẫu (Hình 3.6). Với mỗi bộ chương trình lỗi – chương trình mẫu sẽ tính ra tỉ lệ tương đồng, kết quả này được hiển thị cho người dùng là căn cứ lựa chọn chương trình mẫu nào làm gợi ý.

Bước phân tích chương trình thành chuỗi các Tokens như mô tả ở Mục 3.3.2 cho kết quả mỗi chương trình được phân tách thành nhiều Tokens khác nhau, ta gọi là chuỗi các Tokens. So sánh hai chuỗi Tokens trong JPlag sử dụng thuật toán Greedy-String- Tiling (GST) [30] được phát triển bởi Michael Wise, sau đó các tác giả đã cải tiến bằng cách kết hợp với thuật toán Karp-Rabin để nâng cao hiệu quả.

So sánh hai chuỗi Tokens A và B, mục đích là tìm ra chuỗi con chung lớn nhất của hai mã nguồn từ đó tính ra tỉ lệ trùng lắp so với tổng thể chương trình. Chuỗi con này phải đảm bảo nguyên tắc:

i. Một Token trong A chỉ được so khớp với một Token trong B

ii. Các chuỗi con được tìm thấy phải độc lập với vị trí của chúng trong chuỗi. Hay việc thay đổi vị trí các thành phần trong mã nguồn chương trình không làm ảnh hưởng tới việc so sánh.

Chương trình lỗi Chương trình mẫu 1 . . . . Chương trình mẫu n Chương trình mẫu 2 So sánh So sánh So sánh

Một phần của tài liệu Nghiên cứu giải pháp và công cụ hỗ trợ gợi ý sửa lỗi cho các chương trình java (Trang 30 - 32)