1. Trang chủ
  2. » Luận Văn - Báo Cáo

Đề tài khoa học và công nghệ cấp cơ sở: Nghiên cứu ứng dụng Lex/Yacc trong tự động phát sinh mã nguồn

59 12 0

Đ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

Mục tiêu nghiên cứu đề tài là áp dụng lý thuyết vào xây dựng công cụ ứng dụng vào việc phát sinh mã nguồn sang ngôn ngữ lập trình C nhằm tạo điều kiện để tiếp tục nghiên cứu và xây dựng việc tự động phát sinh ca kiểm thử từ ngôn ngữ mô hình hóa.

ĐẠI HỌC ĐÀ NẴNG TRƯỜNG CĐ CÔNG NGHỆ THÔNG TIN BÁO CÁO TỔNG KẾT ĐỀ TÀI KHOA HỌC VÀ CÔNG NGHỆ CẤP CƠ SỞ NGHIÊN CỨU ỨNG DỤNG LEX/YACC TRONG TỰ ĐỘNG PHÁT SINH MÃ NGUỒN Mã số: T2016-07-04 Chủ nhiệm đề tài: ThS Dương Thị Mai Nga Đà Nẵng, 12/2016 ĐẠI HỌC ĐÀ NẴNG TRƯỜNG CĐ CÔNG NGHỆ THÔNG TIN BÁO CÁO TỔNG KẾT ĐỀ TÀI KHOA HỌC VÀ CÔNG NGHỆ CẤP CƠ SỞ NGHIÊN CỨU ỨNG DỤNG LEX/YACC TRONG TỰ ĐỘNG PHÁT SINH MÃ NGUỒN Mã số: T2016-07-04 Xác nhận quan chủ trì đề tài Chủ nhiệm đề tài Đà Nẵng, 12/2016 MỤC LỤC MỞ ĐẦU CHƯƠNG 1: TỔNG QUAN VỀ TRÌNH BIÊN DỊCH 1.1 KHÁI NIỆM TRÌNH BIÊN DỊCH 1.2 PHÂN TÍCH CHƯƠNG TRÌNH NGUỒN 10 TỔNG KẾT CHƯƠNG 14 CHƯƠNG 2: CÔNG CỤ LEX/ YACC 15 2.1 GIỚI THIỆU VỀ LEX/YACC 15 2.2 LEX 17 2.3 YACC 21 2.4 CÀI ĐẶT CÁC ỨNG DỤNG 25 TỔNG KẾT CHƯƠNG 25 CHƯƠNG 3: XÂY DỰNG CÔNG CỤ SINH MÃ NGUỒN 26 3.1 GIỚI THIỆU NGÔN NGỮ ĐẶC TẢ TTT 26 3.1.1 Cấu trúc chương trình 26 3.1.2 Các lệnh ngôn ngữ TTT 26 3.1.3 Các thành phần khác 27 3.2 XÂY DỰNG GIẢI PHÁP DỊCH NGÔN NGỮ TTT SANG NGÔN NGỮ C 29 3.3 XÂY DỰNG TRÌNH BIÊN DỊCH VÀ THỬ NGHIỆM 35 KẾT LUẬN VÀ KIẾN NGHỊ 38 TÀI LIỆU THAM KHẢO 39 PHỤ LỤC 40 DANH MỤC BẢNG BIỂU Số hiệu bảng Tên bảng Trang Bảng 2.1 Mô tả cách biểu diễn biểu thức quy 18 Bảng 2.2 Biểu diễn số ví dụ biểu thức quy 18 Bảng 2.3 Danh sách macro, biến định nghĩa trước lex 20 Bảng 3.1 Thứ tự ưu tiên phép toán 28 Bảng 3.2 Bảng 3.3 Bảng 3.4 Bảng chuyển đổi từ vựng ngôn ngữ TTT ngôn ngữ C Bảng chuyển đổi cú pháp ngôn ngữ TTT ngơn ngữ C Chuyển đổi phép tốn CTT ngôn ngữ TTT sang ngôn ngữ C 29 31 33 DANH MỤC CÁC HÌNH Số hiệu hình Tên hình Trang Hình 1.1 Một trình biên dịch Hình 1.2 Giao diện phân tích từ vựng trình biên dịch 11 Hình 1.3 Giao diện phân tích cú pháp trình biên dịch 12 Hình 1.4 Cây phân tích cú pháp cho câu lệnh: position := initial + rate * 60 13 Hình 2.1 Hình 2.2 Ví dụ trình tự biên dịch đoạn mã nguồn a = b + c * d Quy trình vận dụng cách đặt tên với Lex, Yacc 15 16 DANH MỤC CÁC TỪ VIẾT TẮT Từ viết tắt/ Thuật ngữ Tiếng Anh Tiếng Việt TTT Task Tree Test Kiểm thử nhiệm vụ CTT Concur Task Tree Cây nhiệm vụ tương tranh BNF Backus-Naur Form Hình thức BNF ĐẠI HỌC ĐÀ NẴNG CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM TRƯỜNG CĐ CÔNG NGHỆ THÔNG TIN Độc lập – Tự – Hạnh phúc THÔNG TIN KẾT QUẢ NGHIÊN CỨU Thông tin chung: - Tên đề tài: Nghiên cứu ứng dụng Lex/Yacc tự động phát sinh mã nguồn - Mã số: T2016-07-04 - Chủ nhiệm: Dương Thị Mai Nga - Cơ quan chủ trì: Trường CĐ Công nghệ Thông tin – Đại học Đà Nẵng - Thời gian thực hiện: từ 1/2016 đến 12/2016 Mục tiêu: Áp dụng lý thuyết vào xây dựng công cụ ứng dụng vào việc phát sinh mã nguồn sang ngôn ngữ lập trình C nhằm tạo điều kiện để tiếp tục nghiên cứu xây dựng việc tự động phát sinh ca kiểm thử từ ngơn ngữ mơ hình hóa Tính sáng tạo: Nghiên cứu ứng dụng cơng cụ việc xây dựng trình biên dịch, giúp q trình nhanh Tóm tắt kết nghiên cứu: Đã nghiên cứu trình biên dịch, cơng cụ hỗ trợ xây dựng trình biên dịch xây dựng trình biên dịch dựa nghiên cứu Tên sản phẩm: Cơng cụ chuyển mã nguồn từ ngôn ngữ đặc tả TTT sang ngôn ngữ C Hiệu quả, phương thức chuyển giao kết nghiên cứu khả áp dụng: Có thể sử dụng nghiên cứu áp dụng vào trình tự động sinh ca kiểm thử cho ứng dụng tương tác đặc tả ngôn ngữ TTT Đà Nẵng, ngày 08 tháng 12 năm 2016 Cơ quan chủ trì Chủ nhiệm đề tài MỞ ĐẦU Ngày song song với phát triển thiết bị phần cứng phát triển kĩ thuật phát triển phần mềm Bài toán đặt làm để lập trình nhanh, hiệu độ xác cao, kĩ thuật đảm bảo yêu cầu kĩ thuật tự động phát sinh mã nguồn Phần mềm sử dụng rộng rãi đời sống, nhiều lĩnh vực khoa học, kinh tế xã hội Vì vậy, việc xây dựng phần mềm đáp ứng mong muốn người sử dụng địi hỏi quan trọng Đó mong muốn độ xác, tính ổn định, tính tương thích giá thành ứng dụng Giá thành ứng dụng phụ thuộc vào chi phí q trình phát triển, Làm để lập trình nhanh hiệu cho tốn ln sở để phương pháp, kĩ thuật ngôn ngữ lập trình đời Một kĩ thuật đời sớm phát triển kĩ thuật tự động phát sinh mã nguồn Hiện có nhiều cơng cụ hỗ trợ phát sinh mã nguồn Lex/Yacc, Antlr… Công cụ Lex/Yacc hỗ trợ tự động sinh mã nguồn C Pascal, Antlr hỗ trợ việc tạo mã cho nhiều ngôn ngữ bao gồm C++, Java, Python, C# Trong nghiên cứu tác giả chọn cơng cụ Lex/Yacc đề xuất đề tài “Nghiên cứu ứng dụng Lex/Yacc tự động phát sinh mã nguồn” nhằm rút ngắn thời gian sinh mã nguồn, dễ dàng việc bảo trì, từ góp phần giảm giá thành sản phẩm Trong đề tài mình, tác giả thực nghiên cứu lý thuyết áp dụng lý thuyết vào xây dựng công cụ ứng dụng việc phát sinh mã nguồn ngơn ngữ lập trình C nhằm tạo điều kiện để tiếp tục nghiên cứu xây dựng việc tự động phát sinh ca kiểm thử từ ngôn ngữ mơ hình hóa Trong nghiên cứu tác giả thực cơng việc sau: tìm hiểu văn phạm phi ngữ cảnh ngơn ngữ lập trình C; tìm hiểu cơng cụ Lex/Yacc; xây dựng chế dịch ngôn ngữ; xây dụng công cụ sinh mã nguồn ngơn ngữ lập trình C; kiểm tra, thử nghiệm đưa nhận xét, kết đạt được; viết báo cáo tổng kết đề tài CHƯƠNG 1: TỔNG QUAN VỀ TRÌNH BIÊN DỊCH Chương tác giả trình bày trình biên dịch, chức trình biên dịch, cấu trúc trình biên dịch, mơi trường hoạt động trình biên dịch KHÁI NIỆM TRÌNH BIÊN DỊCH Trình biên dịch, hay cịn gọi chương trình dịch, đơn giản chương trình làm nhiệm vụ đọc chương trình viết ngơn ngữ (gọi ngơn 1.1 ngữ nguồn) dịch thành chương trình tương đương ngơn ngữ khác (gọi ngơn ngữ đích) Một phần quan trọng q trình dịch ghi nhận lại lỗi có chương trình nguồn để thơng báo lại cho người viết chương trình Chương trình nguồn Trình biên dịch Thơng báo lỗi Chương trình đích Hình 1.1 Một trình biên dịch Chỉ nhìn thống qua, số lượng trình biên dịch dường q nhiều Có đến hang ngàn ngơn ngữ nguồn, từ ngơn ngữ lập trình truyền thống Fortran C đến ngôn ngữ chuyên dụng dành riêng cho lĩnh vực ứng dụng khác Ngơn ngữ đích đa dạng thế; ngơn ngữ đích ngơn ngữ lập trình khác, ngơn ngữ máy loại máy tính, từ máy tính PC siêu máy tính Trình biên dịch phân thành loại loại lượt (single-pass), loại nhiều lượt (multi-pas), loại nạp tiến hành (loadand-go), loại gỡ rối (debugging) loại tối ưu hóa (optimizing), tùy vào cách thức xây dựng tùy vào chức mà chúng thực Mặc dù tính chất phức tạp, nhiệm vụ trình biên dịch Nhờ hiểu rõ nhiệm vụ mà xây dựng trình biên dịch cho nhiều loại ngơn ngữ nguồn ngơn ngữ đích cách sử dụng kỹ thuật giống Hiểu biết cách thức tổ chức viết trình biên dịch tiến xa kể từ trình biên dịch xuất vào đầu thập niên 50 Trong suốt thập niên 50 đó, trình biên dịch xem chương trình khó viết Từ dần khám phá kỹ thuật mang tính hệ thống để xử lý nhiều nhiệm vụ quan trọng xảy q trình biên dịch Một số ngơn ngữ để cài đặt, mơi trường lập trình cơng cụ phần mềm phát triển Với thành này, việc viết trình biên dịch có chất lượng dễ dàng Công việc biên dịch chia thành hai phần: phân tích tổng hợp Phần phân tích phân rã chương trình nguồn thành phần cấu thành tạo dạng biểu diễn trung gian cho chương trình nguồn Phần tổng hợp xây dựng ngơn ngữ đích từ dạng biểu diễn trung gian PHÂN TÍCH CHƯƠNG TRÌNH NGUỒN Khi biên dịch, q trình phân tích bao gồm ba giai đoạn: - Phân tích tuyến tính (linear analysis), dịng ký tự tạo chương trình nguồn đọc từ trái sang phải nhóm lại thành từ tố (thẻ từ 1.2 token), chuỗi ký tự hợp lại để tạo nghĩa chung Phân tích cấu trúc phân cấp (hierarchical analysis), ký tự thẻ từ nhóm thành nhóm lồng theo kiểu phân cấp để tạo nghĩa chung Phân tích ngữ nghĩa (semantic analysis), thực số kiểm tra để đảm bảo thành phần chương trình kết lại với cách có nghĩa Trong trình biên dịch, phân tích tuyến tính gọi phân tích từ vựng (lexical analysis) hay hành động quét nguyên liệu (scanning) giai đoạn trình biên dịch Nhiệm vụ chủ yếu đọc ký tự vào từ văn chương trình nguồn phân tích đưa danh sách từ tố số thơng tin thuộc tính Đầu phân tích từ vựng danh sách từ tố đầu vào cho phân tích cú pháp Trên thực tế q trình phân tích cú pháp gọi từ tố từ phân tích từ vựng để xử lý, khơng gọi lúc toàn danh sách từ tố chương trình nguồn Khi nhận yêu cầu lấy từ tố từ phân tích cú pháp, phân tích từ vựng đọc ký tự vào đưa từ tố 10 %% #define SIZEOF_NODETYPE ((char *)&p->con - (char *)p) void push(nodeType *node){ /* Luu khai bao bien dsvarNode *t; // Cap phat vung nho t = (dsvarNode*) malloc(sizeof(dsvarNode)); t->nt = node; t->link=NULL; // Them bien vao cuoi dslk if(dsvar==NULL) dsvar=t; else { dsvarNode *u; u=dsvar; while (u->link!=NULL) u=u->link; u->link=t; } } nodeType *pushfunc(nodeType *p){ funct = p; return NULL; } */ /* Luu khai bao ham */ nodeType *freefunc(){ /* Lay ham da luu va free */ nodeType *t; t = funct; funct = NULL; return t; } nodeType *pushretu(nodeType* name){ /* Luu return */ nodeType *p; size_t nodeSize; // Cap phat vung nho nodeSize = SIZEOF_NODETYPE + sizeof(oprNodeType) + * sizeof(nodeType*); if ((p = malloc(nodeSize)) == NULL) yyerror("out of memory1"); // Gan kieu va gia tri p->type = name->type; p->opr.oper = name->opr.oper; p->opr.nops = 1; p->opr.op[0] = var(name->opr.op[0]->var->gt); retu = p->opr.op[0]; return p; } void putvar(char type, char *s){ /* Day bien vao danh sach lien ket */ varNodeType *v; varNodeType *tmp; v = (varNodeType*) malloc(sizeof(varNodeType)); v->type=type; 45 v->gt = (char*) malloc(sizeof(s)+1); strcpy(v->gt, s); v->link=NULL; if(root== NULL) root=v; else { tmp=root; while(tmp->link!= NULL) tmp=tmp->link; tmp->link=v; } } varNodeType* getvar(char *s){ /* Lay bien tu dslk*/ varNodeType *tmp; for( tmp = root; tmp!=NULL; tmp = tmp->link) if(strcmp (tmp->gt,s)==0) return tmp; return NULL; } nodeType *savevar(nodeType *p, char k){ /* Luu bien */ if(p->type == typeVar) putvar(k, p->var->gt); else if(p->type == typeOpr){ savevar(p->opr.op[0], k); if(p->opr.oper == ';') savevar(p->opr.op[1], k); } return p; } nodeType *con(int value) { /* Luu so */ nodeType *p; size_t nodeSize; /* allocate node */ nodeSize = SIZEOF_NODETYPE + sizeof(conNodeType); if ((p = malloc(nodeSize)) == NULL) yyerror("out of memory5"); /* copy information */ p->type = typeCon; p->con.value = value; return p; } nodeType *var(char *v) { nodeType *p; size_t nodeSize; /* Lay gia tri bien */ /* allocate node */ nodeSize = SIZEOF_NODETYPE + sizeof(varNodeType); if ((p = malloc(nodeSize)) == NULL) yyerror("out of memory4"); p->type = typeVar; p->var = getvar(v); return p; } 46 nodeType *ktu(char *a) { nodeType *p; size_t nodeSize; /* khai bao kieu ki tu va chuoi */ /* allocate node */ nodeSize = SIZEOF_NODETYPE + sizeof(ktNodeType); if ((p = malloc(nodeSize)) == NULL) yyerror("out of memory3"); p->type = typeKt; p->kt.gt = (char*) malloc(sizeof(a)+1); strcpy(p->kt.gt, a); return p; } nodeType *newvar(char *name) /* Cap phat bien moi */ { if(getvar(name) != NULL) return var(name); else{ nodeType *p; p = (nodeType*) malloc(sizeof(nodeType)); if (p == NULL) yyerror("out of memory2"); p->type = typeVar; p->var = (varNodeType*) malloc(sizeof(varNodeType)); p->var->gt = (char*) malloc(sizeof(name)+1); strcpy(p->var->gt, name); return p; } } nodeType *opr(int oper, int nops, ) { /* Luu nodeType */ va_list ap; nodeType *p; size_t nodeSize; int i; /* allocate node */ nodeSize = SIZEOF_NODETYPE + sizeof(oprNodeType) + (nops - 1) * sizeof(nodeType*); if ((p = malloc(nodeSize)) == NULL) yyerror("out of memory1"); /* copy information */ p->type = typeOpr; p->opr.oper = oper; p->opr.nops = nops; va_start(ap, nops); for (i = 0; i < nops; i++) p->opr.op[i] = va_arg(ap, nodeType*); va_end(ap); return p; } 47 void freeNode(nodeType *p) { /* giai phong nodeType */ int i; if (p==NULL) return; if (p->type == typeOpr) { for (i = 0; i < p->opr.nops; i++) freeNode(p->opr.op[i]); } else{ if(p->type == typeKt){ free(p->kt.gt); } else{ if(p->type == typeVar){ return; } } } free(p); } void freeVar(){ /* Giai phong dslk luu bien */ for(;root!=NULL;){ varNodeType *tmp = root; root=tmp->link; free(tmp->gt); free(tmp); } } void prtab(int n){ /* in tab */ int i; for(i=0; icon.value); break; case typeVar: printf("%s", p->var->gt); break; case typeKt: printf("%s", p->kt.gt); break; case typeOpr: switch(p->opr.oper) { case TESTCTT: printf("#include \n"); printf("void main()\n"); break; case RETU: switch (p->opr.op[0]->opr.oper){ case INT: printf("int ");break; case CHAR: printf("char ");break; case FLOAT: printf("float ");break; default: printf("void "); } ex(p->opr.op[1]); break; case FUNC: ex(p->opr.op[0]); printf("()"); break; case INT: prtab(tab); printf("int "); ex(p->opr.op[0]); ex(p->opr.op[1]); printf(";\n"); break; case CHAR: prtab(tab); printf("char "); ex(p->opr.op[0]); ex(p->opr.op[1]); 49 printf(";\n"); break; case FLOAT: prtab(tab); printf("float "); ex(p->opr.op[0]); ex(p->opr.op[1]); printf(";\n"); break; case WHILE: prtab(tab); printf("while ("); ex(p->opr.op[0]); printf(")\n"); ex(p->opr.op[1]); break; case DO: prtab(tab); printf("do\n"); ex(p->opr.op[0]); prtab(tab); printf("while ("); ex(p->opr.op[1]); printf(");\n"); break; case IF: prtab(tab); printf("if ("); ex(p->opr.op[0]); printf(")\n"); if (p->opr.nops > 2) { /* if else */ ex(p->opr.op[1]); prtab(tab); printf("else\n"); ex(p->opr.op[2]); } else { /* if */ ex(p->opr.op[1]); } break; case '{': if (funct != NULL){printf("void ");ex(funct);freeNode(funct);funct=NULL;} prtab(tab++); printf("{\n"); while(dsvar!=NULL){ dsvarNode *tmp; tmp=dsvar; ex(tmp->nt); dsvar=dsvar->link; freeNode(tmp->nt); free(tmp); } 50 if(retu!=NULL){ nodeType *tmp; tmp = retu; retu=NULL; ex(p->opr.op[0]); prtab(tab); printf("return "); ex(tmp); printf(";\n"); freeNode(tmp); } else ex(p->opr.op[0]); prtab( tab); printf("}\n"); break; case INPUT: prtab(tab); printf("scanf(\"%%%c\", &", p->opr.op[0]->var->type); ex(p->opr.op[0]); printf(");\n"); break; case OUTPUT: prtab(tab); if (p->opr.op[0]->type == typeVar){ printf("printf(\"%%%c\", ", p->opr.op[0]->var->type); } else { printf("printf("); } ex(p->opr.op[0]); printf(");\n"); break; case CHOICE: printf("choice("); ex(p->opr.op[0]); printf(", "); ex(p->opr.op[1]); printf(", "); ex(p->opr.op[2]); printf(", "); ex(p->opr.op[3]); printf(", "); ex(p->opr.op[4]); printf(", "); ex(p->opr.op[5]); printf(", "); ex(p->opr.op[6]); printf(")"); break; case DROP: prtab(tab); printf("(mysql_query(conn, \"DROP TABLE IF EXISTS U_ACTIONS\"))\n"); prtab(tab); 51 printf("{ fprintf(stderr, \"%%s \\n\", mysql_error(conn));}\n"); break; case INSERT: prtab(tab); printf("sprintf(msg,\"insert into U_ACTIONS("); ex(p->opr.op[0]); ex(p->opr.op[1]); printf(") values("); ex1(p->opr.op[2]); printf("'%%%c')\", ", p->opr.op[3]->var->type); ex(p->opr.op[2]); ex(p->opr.op[3]); printf(");\n"); prtab(tab); printf("if(mysql_query(conn, msg))\n"); prtab(tab); printf("\t printf(stderr, \"%%s \\n\", mysql_error(conn));\n"); break; case MODAL: prtab(tab); printf("Modalities("); ex(p->opr.op[0]); printf(", &"); ex(p->opr.op[1]); printf(", &"); ex(p->opr.op[2]); printf(", &"); ex(p->opr.op[3]); printf(", "); ex(p->opr.op[4]); printf(", "); ex(p->opr.op[5]); printf(", "); ex(p->opr.op[6]); printf(");\n"); break; case CR_TABLE: prtab(tab); printf("if(mysql_query(conn, \""); ex(p->opr.op[0]); printf("\")){\n"); prtab(tab); printf("\tfprintf(stderr, \"%%s \\n\", mysql_error(conn));\n"); prtab(tab); printf("}\n"); break; case DOCUDTT: prtab(tab); printf("docudtt(\"udtt.txt\",conn,row,T);\n"); break; case DEACT: 52 printf("deact("); ex(p->opr.op[0]); printf(", "); ex(p->opr.op[1]); printf(", "); ex(p->opr.op[2]); printf(")"); break; case TESTR: printf("TestR_E("); ex(p->opr.op[0]); printf(", "); ex(p->opr.op[1]); printf(", "); ex(p->opr.op[2]); printf(")"); break; case '=': prtab(tab); ex(p->opr.op[0]); printf(" = "); ex(p->opr.op[1]); printf(";\n"); break; case ADD: prtab(tab); ex(p->opr.op[0]); printf(" += "); ex(p->opr.op[1]); printf(";\n"); break; case DEC: prtab(tab); ex(p->opr.op[0]); printf(" -= "); ex(p->opr.op[1]); printf(";\n"); break; case MUL: prtab(tab); ex(p->opr.op[0]); printf(" *= "); ex(p->opr.op[1]); printf(";\n"); break; case DIV: prtab(tab); ex(p->opr.op[0]); printf(" /= "); ex(p->opr.op[1]); printf(";\n"); break; case UMINUS: printf("-"); 53 ex(p->opr.op[0]); break; case NOT: printf("!"); ex(p->opr.op[0]); break; case ',': ex(p->opr.op[0]); printf(", "); break; case '.': ex(p->opr.op[0]); printf("."); ex(p->opr.op[1]); break; case '(': printf("("); ex(p->opr.op[0]); printf(")"); break; default: ex(p->opr.op[0]); switch(p->opr.oper) { case '+': printf("+"); break; case '-': printf("-"); break; case '*': printf("*"); break; case '/': printf("/"); break; case '': printf(">"); break; case GE: printf(">="); break; case LE: printf("

Ngày đăng: 24/12/2021, 10:32

Xem thêm:

TÀI LIỆU CÙNG NGƯỜI DÙNG

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN