
สร้างโปรแกรมอิงแนวคิด Compiler อย่างง่ายด้วยภาษาจาวาและซีชาร์ป
ขั้นตอนหลักๆของ Compiler โดยทั่วไปแล้วมักกระทำดังนี้
1) อ่านไฟล์จากภายนอกเข้ามา
2) ไฟล์ที่อ่านคือ Source Code หรือภาษาโปรแกรมที่เราเขียนขึ้นตาม Grammar
3) กระบวนการ Lexical เริ่มจากแยกภาษาโปรแกรมนั้นออกเป็น Token จำแนกแต่ละ Token หรือคำเป็นประเภทต่างๆตามที่เรากำหนด เช่น Keyword, Operator, Separator, Identifier, Integer_const, Floating_const และอื่นๆ
4) บรรจุแต่ละคำไว้ใน Symbol Table ให้ลำดับแก่คำเหล่านั้น
5) บรรจุแต่ละคำจาก Symbol Table ใส่ลงใน Token Stream
6) ส่ง Symbol Table และ Token Stream ให้กระบวนการ Parser
7) ตรวจสอบไวยากรณ์ของ Token Stream ตาม Grammar
8) นิยามความหมายที่ต้องการตามเพื่อตรวจสอบการประกาศตัวแปรหรือฟังก์ชัน, การเรียกชื่อตัวแปรหรือฟังก์ชัน, ลำดับการคำนวณทางคณิตศาสตร์และอื่นๆ
9) ในการนิยามความหมายจะมีการสร้าง Intermediate Code เพื่อนำไปสร้างเป็นโค้ดภาษาเครื่อง
10) สร้างโค้ดภาษาเครื่องจาก Intermediate Code

โดยส่วนตัวแล้วผมรู้สึกว่าไม่ได้ยาก แม้เนื้อหาจะลึกแต่ก็มีเรื่องสนุกๆอยู่เต็มไปหมด (จริงเหรอ) จริงแท้เลยล่ะครับ เวลาที่ผมได้พบปะกับเพื่อนหลายๆคน เรื่องทฤษฎีไม่มีติดขัดกันเลย ทำได้หมดไม่ว่าจะมาแนวไหน แล้วปัญหาที่แท้จริงมันอยู่ที่ไหนล่ะ

- กล่าวถึงออบเจ็กต์ที่ถูกเรียกใช้แบบ instance และแบบ object เอง
- สร้าง array ของคำ โดยสร้างสมาชิกแบบ object
- การเขียน for-each และ for แบบธรรมดาเพื่อเรียกดูลายละเอียดของออบเจ็กต์

- อธิบายการใช้งานเมธอด toString หรือ ToString เพื่อแสดงรายละเอียดของคำ
- เขียนโปรแกรมเพิ่มและแสดงคำอย่างง่ายๆ

- ดึงข้อมูลจากเมธอทโดยใช้คีย์ ref สำหรับ C#
- หรือดึงข้อมูลจากเมธอทโดยใช้การสร้างออบเจ็กต์ใหม่แล้ว Pass by Value แทนการ Pass by Reference ซึ่งใช้ได้ทั้ง Java และ C#

- แนะนำโครงสร้างข้อมูล ArrayList ขั้นต้น สำหรับภาษา Java และ C#

- แนะนำการใช้เมธอด a.get(int index) สำหรับภาษา Java และ a[int index] สำหรับภาษา C# เมื่อต้องการข้อมูลจากโครงสร้าง ArrayList ที่ชื่อ a
- ความแตกต่างระหว่าง Generic Type กับ Object Type เมื่อ Generic Type ลดการแปลงข้อมูลได้มากกว่าแบบ Object Type

- เริ่มต้นการวางคลาสที่ใช้ในการตัดคำ ใช้วิเคราะห์แกรมม่า ใช้สังเคราะห์โค้ดภาษาเครื่อง ที่ตั้งชื่อว่า MyLexical, MyParser, MyCodeGen ตามลำดับ
- ส่งสตริงโค้ดต้นฉบับ (Source Code) ให้กับออบเจ็กต์ MyLexical เพื่อเตรียมนำไปตัดคำ
- สั่งให้ออบเจ็กต์ MyLexical เรียกเมธอด Do เพื่อตัดคำ โดยเริ่มจากอ่านตัวอักษร (Character) ทีละหนึ่งตัวอักษรแล้วรวมกันเป็นคำ (Word) ก่อนจะแสดงผลออกมาว่าถูกแยกเป็น Keyword Integer Operator หรือ Separator

- แยกคำออกเป็นประเภทต่างๆต่อเนื่องจาก part ที่แล้ว
- เปรียบเทียบสตริงจะใช้เมธอด equals หรือ Equals เพราะสตริงถูกจัดเก็บในหน่วยความจำในรูปแบบเฉพาะที่ต่างจากชนิดข้อมูลอื่นๆ
- เปรียบเทียบอักษรหรือตัวเลข โดยเครื่องหมาย ==

- สร้างคลาส Token เก็บชื่อคำและประเภทของคำ
- สร้างคลาส TokenStream เก็บคลาส Token อีกทีหนึ่ง
- ไม่สร้าง SymbolTable เพราะชื่อคำและประเภทของคำใช้ชนิดเป็นสตริง

- ต่อเนื่องจาก MiniCompiler (CT414) with C# and Java part 08-01 ครับ

- รู้จักกับ grammar และการสร้าง grammar จาก source code
- เมื่อกำหนดให้อักษรพิมพ์ใหญ่แทน non-terminal ส่วนอักษรพิมพ์เล็กแทน terminal โดยที่ non-terminal สามารถแยก (สร้าง) ตัวเองเป็น non-terminal และ terminal อีกเท่าใดก็ได้ ต่างจาก terminal ที่ไม่สามารถแยก (สร้าง) ตัวเองได้อีก
- ใช้ non-terminal และ terminal ข้างต้นออกแบบ grammar ของการประกาศตัวแปรอย่างทั่วไป

- แก้ความกำกวมของไวยากรณ์ อันได้แก่ Left Recursion และ Left Factoring

- อธิบาย ATG (Attribute Grammar) ของการบวกตัวเลขจำนวนเต็มบวกกี่จำนวนก็ได้ เมื่อ
- syn แทนการ Synthesized
- in แทนการ Inherited

- เขียนโปรแกรมหาผลรวมของเลขจำนวนเต็มบวกที่กำหนดให้โดยกระบวนการ Parser
- read() ล่วงหน้าทุกครั้งก่อนจะเริ่มต้นทำงานเมธอดแรกของ grammar
- เมื่อพบ terminal ให้ read() เสมอ เพื่อที่ Token ที่เรากำลังพิจารณาอยู่นั้นเปลี่ยนเป็นคำถัดไป

- เขียน grammar แสดงลำดับความสำคัญของเครื่องหมายคูณซึ่งมากกว่าเครื่องหมายบวก
- เขียนโปรแกรม Parser จาก grammar ข้างต้น เพื่อหาผลลัพธ์ของ 1 + 2 * 3 ย่อมมีค่าเท่ากับ 7 โดยใช้ภาษา C#

- จากโปรแกรมที่สามารถกระทำการบวกหรือการคูณอย่างมีลำดับชั้นความสำคัญ เราเปลี่ยนการบวกหรือคูณที่นำมาซึ่งผลลัพธ์นั้นเป็น Intermediate code ในรูปแบบ
[ operator, operand1, operand2, result ]

- การเขียน LBL ร่วมกับคำสั่ง Jump
- สำหรับตัวอย่างลูป while

- การวาง LBL ร่วมกับ JUMP เพื่อสร้าง Intermediate code ของ if, if-else และ nested if

- เสนอแนะวิธีการวาง LBL กับ JUMP สำหรับ grammar ของ loop for (โจทย์ในชั้นเรียน) เทียบกับคำสั่งภาษาเครื่องสมมติ (Code Generator)

- เตรียม grammar สำหรับเขียน compiler ทั้งในส่วน การประกาศตัวแปร การเรียกฟังก์ชัน การใช้ for และนิพจน์คำนวณอย่างมีลำดับ

- อ่านไฟล์ด้วยคลาส StreamReader สำหรับภาษา C# และคลาส FileReader สำหรับภาษา Java พร้อมเตรียมพื้นที่ลงโค้ด

- grammar ส่วนตรวจสอบไวยากรณ์

- ต่อจาก part ที่ 18 ทดสอบการทำงานของ Parser เพื่อแจ้ง error ในส่วนการตรวจสอบ syntax ด้วย grammar ที่ผลิตการประกาศตัวแปร

- จากวันเสาร์ที่ 31/05/2014 ที่ผ่านมานั้น ผมกับน้องๆกลุ่มหนึ่งได้มาฝึกเขียน mini compiler ร่วมกันครับ แล้วนี่คือความคืบหน้าของเรา

- ตัดคำแยกเป็น Keyword, Operator, Separator, Identifier, Integer, Floating-point และ String
- ตรวจสอบไวยากรณ์ สามารถผลิต Intermediate Code ได้ในไวยากรณ์การบวก ลบ คูณ และหาร
- ผลิตโค้ดเป้าหมาย (Target Code) ได้ในไวยากรณ์การบวก ลบ คูณ และหาร
ไม่มีความคิดเห็น:
แสดงความคิดเห็น