Abstract Syntax Tree และการทำ Type Checking

Slides:



Advertisements
งานนำเสนอที่คล้ายกัน
คำสั่งเงื่อนไข (Conditioning Statements)
Advertisements

Liang, Introduction to Java Programming, Sixth Edition, (c) 2007 Pearson Education, Inc. All rights reserved Java Programming Language.
1 C Programming An Introduction. 2 Preprocessing Directives เขียนได้ 2 รูปแบบ #include คอมไพเลอร์จะทำ การค้นหาเฮดเดอร์ไฟล์ที่ระบุ จากไดเร็คทอรีที่ใช้
Lecture 5: ทางเลือกแบบหลายทาง
Computer Programming 1 LAB Test 3
VARIABLES, EXPRESSION and STATEMENTS. Values and Data Types Value เป็นสิ่งพื้นฐาน มีลักษณะเป็น ตัวอักษร หรือ ตัวเลข อาทิ 2+2 หรือ “Hello world” Value.
Intermediate Representation (รูปแบบการแทนในระยะกลาง)
Type Judgments และ Type Rules. คำศัพท์ที่จะใช้ Type judgment: การตัดสินความถูกต้องของ type สำหรับ expression หรือ statement ใน โปรแกรม – เป็นบทสรุป (conclusion)
Data Structures and Algorithms
โครงสร้างข้อมูลแบบรายการโยง (Linked Lists) Data Structures and Algorithms อ. ธารารัตน์ พวงสุวรรณ คณะวิทยาศาสตร์และศิลปศาสตร์ มหาวิทยาลัยบูรพา วิทยาเขตสารสนเทศจันทบุรี
ระบบการจัดเก็บในคลังสินค้า
ฟังก์ชัน (Function).
Structure Programming
AVL Tree.
REGULAR EXPRESSION การบรรยายแบบสม่ำเสมอ
LAB # 5 Computer Programming 1 1.
Shell Script Programming (Function)
คำสั่งเพื่อการกำหนดเงื่อนไข
Linked-List (รายการโยง)
EECP0110 C Language Computer Programming
Lecture no. 10 Files System
การประกาศตัวแปร “ตัวแปร” คือสิ่งที่เราสร้างขึ้นมาเพื่อใช้เก็บค่าต่างๆและอ้างอิงใช้งานภายในโปรแกรม ตามที่เรากำหนดขึ้น การสร้างตัวแปรขึ้นมาเราเรียกว่า.
SQL Server using Transact-SQL
Stored Procedure.
Functions Standard Library Functions User-defined Functions.
LOGO Array. ประเภทของ Array - อาเรย์ 1 มิติ (One) - อาเรย์ 2 มิติ (Two) - อาเรย์ 3 มิติ (Three) 2.
Lex & Yacc โดย...นายชัชวาลย์ ฮาสุวรรณกิจ.
WEEK#16: Method เมธอดคือกลุ่มคําสั่งที่ถูกกําหนดขึ้นเพื่อทำงาน อย่างใดอย่างหนึ่งเพื่อให้ได้ผลลัพธ์ตาม ต้องการ การประกาศเมธอด มีรูปแบบดังนี้ [modifier]
 เป็นเมธอดที่มีคุณลักษณะของ Polymorphism รูปแบบหนึ่ง โดยใช้ชื่อเมธอดเดียวกัน มากกว่า 1 เมธอด เพื่อทำงานในแบบเดียวกัน  คลาสลูกสามารถเขียนทับ เมธอดของคลาสแม่ได้
หน่วยที่ 17 แอเรย์ของสตรัคเจอร์. แอเรย์ของข้อมูลสตรัคเจอร์ student_info student[30]; Student[0]Student[0].Name Student[0].Midterm Student[0].Assignment.
Javascripts.
PHP Connect Database.
คำสั่งควบคุมการทำงาน
การติดต่อกับฐานข้อมูล(MySQL)
ครั้งที่ 3.
คำสั่งควบคุมการ ทำงาน การเขียนโปรแกรมโดยปกติ มีทั้งให้ทำงาน เป็นลำดับ ที่ละคำสั่ง บางครั้งมีการให้เปลี่ยน ลำดับในการทำคำสั่ง เพื่อให้การเขียน โปรแกรมมีประสิทธิภาพสูงสุด.
พื้นฐานการโปรแกรม ต้องทราบการใช้คำสั่ง การควบคุม
Liang, Introduction to Java Programming, Sixth Edition, (c) 2007 Pearson Education, Inc. All rights reserved Java Programming Language.
Java Programming Language สาขาวิชาระบบสารสนเทศ คณะบริหารธุรกิจ มหาวิทยาลัยเทคโนโลยีราชมงคลกรุงเทพ.
Thread Thread ส่วนของ process ที่ให้ CPU ประมวลผล.
STACK ADT By Pantharee S.. Stack Model  A list with the restriction that insertions deletions can be performed in only one position (LIFO)  Push – insert.
การสร้าง WebPage ด้วย Java Script Wachirawut Thamviset.
บทที่ 5 Link List Link List.
Linked List List is group of nodes that consists of data and link.
21 August ดรุณี ศมาวรรตกุล 1 2. ADT List - Unsorted list ADT - list implementation - Sorted List - Circular list - Doubly linked list.
Object-Oriented Programming with Java Burapha University, 2001 Java Array and String Week #3 Jarungjit Parnjai.
วิชา COSC2202 โครงสร้างข้อมูล (Data Structure)
คำสั่งแบบมีเงื่อนไข Conditional Statements
รายการโยง (linked lists) หอยทอด 30 ข้าวผัด 30 ไก่ย่าง 50 เนื้อทอด 30
โครงสร้างข้อมูลแบบลิงก์ลิสต์
หน่วยที่ 4 โครงสร้างโปรแกรมภาษาซี
1 สตริง (String) การประกาศค่าตัวแปรสตริง การกำหนดค่าสตริง การอ้างอิงตัวอักษรแต่ละตัวในสตริง ฟังก์ชั่นที่ใช้ในการจัดการสตริง ฟังก์ชั่นในการเปลี่ยนรูปแบบของสตริง.
Programming assignments ชื่องาน (subject) : program เขียนด้วยภาษา C หรือ C++ มีทั้งหมด 7 ข้อ กำหนดส่ง 29 กรกฎาคม 2554.
Computer Programming Asst. Prof. Dr. Choopan Rattanapoka
Linked List (2) Sanchai Yeewiyom School of Information & Communication Technology University of Phayao.
Linked List ( ต่อ ) Lecturer : Kritawan Siriboon, Room no. 913 Text : Data Structures & Algorithm Analysis in C, C++,… Mark Allen Weiss, Addison Wesley.
Queue Sanchai Yeewiyom School of Information & Communication Technology University of Phayao.
ฟังก์ชันในภาษา C. ฟังก์ชัน (Functions) 2 การออกแบบโปรแกรมในภาษาซี จะอยู่บนพื้นฐานของการออกแบบ โมดูล (Module Design) โดยการแบ่ง โปรแกรมออกเป็นงานย่อย ๆ.
โครงสร้างภาษาซี C ++ structure
C Programming By Mr. Sanae Sukprung.
Chapter 9 ตัวชี้ pointer.
Data Structure & Algorithm Concept
Stack Sanchai Yeewiyom
ภาษา C เบื้องต้น.
Computer Programming การเขียนโปรแกรมคอมพิวเตอร์
บทที่ 4 ตัวแปร (Variables)
Linked List Lecturer : Kritawan Siriboon, Room no. 913
Queue [2] ผู้สอน อาจารย์ ยืนยง กันทะเนตร
Linked List (ต่อ) Lecturer : Kritawan Siriboon, Room no. 913
Dr.Surasak Mungsing CSE 221/ICT221 การวิเคราะห์และออกแบบขั้นตอนวิธี Lecture 05: การวิเคราะห์ความซับซ้อนของ ขั้นตอนวิธีการเรียงลำดับข้อมูล.
ใบสำเนางานนำเสนอ:

Abstract Syntax Tree และการทำ Type Checking

เฟสของคอมไพเลอร์ที่ผ่านมา

AST Abstract Syntax Tree เป็นโครงสร้างข้อมูลที่ใช้แทนภาษาโปรแกรมที่จะแปลสู่ภาษาระดับล่าง เฟสของคอมไพเลอร์หลังจากการทำ parsing จะใช้ AST ในการปฏิบัติการหลายๆอย่าง Type checking Optimization ต่างๆ การผลิตโค๊ดระหว่างกลาง (Intermediate Code Generation)

การสร้าง AST ค่อยๆสร้างแบบ bottom-up ใส่โค๊ดในการสร้าง node และ link ไว้ที่ semantic action Semantic action คือสิ่งที่จะถูกดำเนินการขณะที่ non-terminal หรือ terminal ด้านขวาของ CFG ได้รับการประมวลเรียบร้อยแล้ว นั่นคือเวลาที่ production rule ของ CFG ได้ปฏิบัติการ rule นั้นเสร็จเรียบร้อยแล้ว

หัวใจในการสร้าง AST ต้อง abstract ใส่เฉพาะ node ที่จำเป็นใน AST เราต้องการ tree ที่ abstract ในลักษณะนี้ Tree ที่ได้จากการ parse expression (1 + 2) + 3 แบบนี้ไม่ abstract เท่าไหร่ ทั้งนี้เพราะเราใส่ node เข้าไปที่ AST ทุกๆครั้งที่ production rule ที่จะทำการสร้าง expression นี้ ดำเนินการเสร็จ

คอมไพเลอร์ยุคเก่า รันบนเครื่องคอมพิวเตอร์ที่มีหน่วยความจำหลักน้อย หน่วยความจำหลักไม่เพียงพอที่จะบรรจุ AST ของทั้งโปรแกรมได้ จะผลิตโค๊ดและทำการ type checking ที่ semantic action โดยตรงเลย คอมไพเลอร์ขนาดเล็กและเข้าใจได้ง่าย แต่ ไม่ถูกต้องตามหลักการวิศวกรรมซอฟแวร์ที่ดี ปฏิบัติการหลายๆอย่างทำได้ลำบาก คอมไพเลอร์ CSubset ไม่มีการสร้าง AST

โค๊ดการสร้าง AST: node ของ tree typedef struct A_exp_ *A_exp; struct A_exp_ {enum {A_varExp, A_intExp, A_callExp, A_opExp, A_assignExp, A_ifExp, A_whileExp, A_arrayExp} kind; A_pos pos; union {A_var var; /* nil; - needs only the pos */ int intt; struct {S_symbol func; A_expList args;} call; struct {A_oper oper; A_exp left; A_exp right;} op; struct {A_var var; A_exp exp;} assign; struct {A_exp test, then, elsee;} iff; /* elsee is optional */ struct {A_exp test, body;} whilee; } u; };

โค๊ดการสร้าง AST: ตัวอย่าง prototype A_exp A_OpExp(A_pos pos, A_oper oper, A_exp left, A_exp right); A_exp A_AssignExp(A_pos pos, A_var var, A_exp exp); A_exp A_IfExp(A_pos pos, A_exp test, A_exp then, A_exp elsee); A_exp A_WhileExp(A_pos pos, A_exp test, A_exp body);

โค๊ดการสร้าง AST: OpExp A_exp A_OpExp(A_pos pos, A_oper oper, A_exp left, A_exp right) { A_exp p = malloc(sizeof(*p)); p->kind=A_opExp; p->pos=pos; p->u.op.oper=oper; p->u.op.left=left; p->u.op.right=right; return p; }

โค๊ดการสร้าง AST: AssignExp A_exp A_AssignExp(A_pos pos, A_var var, A_exp exp) { A_exp p = malloc(sizeof(*p)); p->kind=A_assignExp; p->pos=pos; p->u.assign.var=var; p->u.assign.exp=exp; return p; }

โค๊ดการสร้าง AST: IfExp A_exp A_IfExp(A_pos pos, A_exp test, A_exp then, A_exp elsee) { A_exp p = malloc(sizeof(*p)); p->kind=A_ifExp; p->pos=pos; p->u.iff.test=test; p->u.iff.then=then; p->u.iff.elsee=elsee; return p; }

โค๊ดการสร้าง AST: WhileExp A_exp A_WhileExp(A_pos pos, A_exp test, A_exp body) { A_exp p = malloc(sizeof(*p)); p->kind=A_whileExp; p->pos=pos; p->u.whilee.test=test; p->u.whilee.body=body; return p; }

สร้าง AST ที่ semantic action จาก production: expr = expr + expr ใส่ semantic action (ให้ expr ด้านขวาคือ e1 และ e2 ตามลำดับ): {return A_OpExp(A_pos pos, A_oper A_plusOp, A_exp e1, A_exp e2);} จาก production: stmt = if (expr) stmt else stmt ใส่ semantic action (ให้ expr และ stmt ทั้งสองที่อยู่ด้านขวาเป็น e1 s1 และ s2 ตามลำดับ): {return A_IfExp(A_pos pos, A_exp e1, A_exp s1, A_exp s2);}

โค๊ดการสร้าง AST ใน parser A_exp parseStmt() { A_exp result; switch (next_token) { case IF: consume(IF); consume(LPAREN); A_exp e1 = parseExpr(); consume(RPAREN); A_exp s1, s2; s1 = parseStmt(); if (next_token == ELSE) { consume(ELSE); s2 = parseStmt(); } else s2 = EmptyStmt(); result = A_IfExp(A_pos pos, A_exp e1, A_exp s1, A_exp s2); break; case ID: ... case WHILE: ...

Type Checking Traverse AST โดยใช้ recursive function Function ที่ traverse AST จะตรวจสอบ expression ที่จะ type check หนึ่งใน argument ของ function นี้คือ context หรือ environment ที่ให้ข้อมูลเพิ่มเติมเกี่ยวกับ expression ที่จะ type check Symbol table เก็บข้อมูล context Function นี้จะ return ข้อมูลเกี่ยวกับ type ของ expression ที่กำลังพิจารณา

โค๊ดสำหรับการทำ type check ข้อมูลเกี่ยวกับ type และตัวอย่างของ prototype typedef struct Ty_ty_ *Ty_ty; struct Ty_ty_ {enum {Ty_record, Ty_nil, Ty_int, Ty_string, Ty_array, Ty_name, Ty_void} kind; union { Ty_ty array; struct {S_symbol sym; Ty_ty ty;} name; } u; }; Ty_ty Ty_Int(void); Ty_ty Ty_String(void); Ty_ty Ty_Void(void); Ty_ty Ty_Array(Ty_ty ty);

โค๊ดสำหรับการทำ type check ฟังก์ชั่นที่ return ข้อมูลเกี่ยวกับ type ชนิดต่างๆ static struct Ty_ty_ tyint = {Ty_int}; Ty_ty Ty_Int(void) {return &tyint;} static struct Ty_ty_ tystring = {Ty_string}; Ty_ty Ty_String(void) {return &tystring;} static struct Ty_ty_ tyvoid = {Ty_void}; Ty_ty Ty_Void(void) {return &tyvoid;} Ty_ty Ty_Array(Ty_ty ty) { Ty_ty p = malloc(sizeof(*p)); p->kind=Ty_array; p->u.array=ty; return p; }

Function สำหรับ type check Ty_ty transExp(S_table env, A_exp a) { switch(a->kind) { case A_varExp : { return transVar(env, a->u.var); } case A_intExp: { return Ty_Int(); case A_opExp: { A_oper oper = a->u.op.oper; Ty_ty left = transExp(env, a->u.op.left); Ty_ty right = transExp(env, a->u.op.right); if (oper == A_plusOp) { if (left->kind == Ty_int && right->kind == Ty_int) return Ty_Int(); else if … else Print_Error(“Type error”) break; …

Type check สำหรับ assignment statement Ty_ty transExp(S_table env, A_exp a) { switch(a->kind) { … case A_assignExp: { // Retrieve types for the expression and variable parts of the assignment. Ty_ty assignExp = transExp(env, a->u.assign.exp); Ty_ty assignVar = transVar(env, a->u.assign.var); // Insert code to check if assignExp is type-compatible with assignVar return Ty_Void(); break; }

Type check สำหรับ if statement Ty_ty transExp(S_table env, A_exp a) { switch(a->kind) { … case A_ifExp: { Ty_ty test; Ty_ty then; Ty_ty elsee; // Grab expressions for test, then, and else. test = transExp(env, a->u.iff.test); then = transExp(env, a->u.iff.then); if (a->u.iff.elsee != NULL) elsee = transExp(env, a->u.iff.elsee); else elsee = Ty_Nil(); // Insert code to check if test is type-compatible with boolean // if then and elsee are well-typed, return Void type return Ty_Void(); break; }

Type check สำหรับ call statement case A_callExp: { E_enventry functionID = NULL; A_expList argsList = NULL; Ty_tyList formals; Ty_ty returnVal; // Verify that function has been defined previously. functionID = S_look(venv, a->u.call.func); if (functionID == NULL) { Print_Error(“No function by that name”); } returnVal = functionID->u.fun.result; if (no argument function) { return ActualTypeOf(returnVal)); // Check parameters and function call types. argsList = a->u.call.args; formals = functionID->u.fun.formals; while (argsList != NULL && formals != NULL) { Ty_ty fType = formals->head; A_exp argExp = argsList->head; Ty_ty argType = transExp(env, argExp); formals = formals->tail; argsList = argsList->tail; // Insert code to check if fType and artType are compatible break; Additional typedef typedef struct Ty_tyList_ *Ty_tyList; struct Ty_tyList_ {Ty_ty head; Ty_tyList tail;}; typedef struct A_expList_ *A_expList; struct A_expList_ {A_exp head; A_expList tail;};

ฟังก์ชั่น main ของคอมไพเลอร์ extern A_exp absyn_root; void SEM_transProg(A_exp exp) { Ty_ty exprType; // Create environments. S_table env = NULL; env = symTabConstruct(exp); // construct the symbol table exprType = transExp(env, exp); // type-checking } int main(int argc, char **argv) { if (argc!=2) { fprintf(stderr,"usage: parsetest filename\n"); exit(1); /* Step 1, get tokens from lexical analysis; Step 2, build an AST while parsing */ parseInput(argv[1]); /* Step 3, traverse AST for semantic analysis from the entry point of absyn_root. */ SEM_transProg(absyn_root); return 0;