วันจันทร์ที่ 28 กุมภาพันธ์ พ.ศ. 2554

Compiler : Intermediate Code

       เรื่องของโค้ดกลางหรือภาษากลาง (Intermediate Code) นี้ถูกใช้กับคอมไพเลอร์แทบทุกภาษา โดยเป็นที่ตกลงกันว่าต้องมีรูปแบบ (ไวยากรณ์) อย่างโน้นอย่างนี่ สำหรับเพื่อนๆที่ต้องส่งงานชิ้นนี้ให้กับอาจารย์ผู้สอน จึงต้องตกลงกันกับอาจารย์ผู้สอนว่าจะให้โปรแกรมคอมไพเลอร์ที่เขียนขึ้นนี้สร้างโค้ดกลางขึ้นมาในรูปแบบใด...

เกร็ดเล็กเกร็ดน้อย : โปรแกรมเมอร์ภาษา Basic.NET, C++.NET, C#.NET ฯลฯ ภายหลังคอมไพล์โค้ดต้นฉบับ (source code) จะได้โค้ดกลางที่เรียกว่า MSIL เหมือนกันทั้งหมด เป็นเหตุให้โครงการ (project) ที่พัฒนาด้วย .NET แม้เขียนจากภาษาที่หลากหลายยังสามารถทำงานร่วมกันได้เป็นอย่างดี หรือ bytecode ของภาษา Java ก็เป็นจัดเป็นโค้ดกลางเช่นกัน

เป็นที่ตกลง (ณ ขณะที่ผมเรียน) ให้รูปแบบของโค้ดกลางเป็นดังนี้
operator, operand1, operand2, result

โดยเฉพาะ result หมายถึง ตัวแปรชื่อใดๆก็ได้สำหรับเก็บผลลัพธ์ และตามตัวอย่างด้านล่างนี้จะใช้ชื่อเป็น t0, t1, t2, ... ไปเรื่อยๆครับ

ตัวอย่าง 3 + 2 - 1 เมื่อความสำคัญการบวกและลบเท่ากัน
+ , 3 , 2 , t0
- , t0, 1, t1

ตัวอย่าง 3 + 2 * 1 เมื่อความสำคัญการคูณมากกว่าการบวก
* , 2 , 1 , t0
+ , 3 , t0 , t1

ตัวอย่าง a = b % 10 * 5 เมื่อความสำคัญ % เท่ากับ * และมันทั้งสองมากกว่า =
% , b , 10 , t0
* , t0 , 5 , t1
= , t1 , , a

ตัวอย่าง a != b || c - ( d && f ) * 3 เมื่อความสำคัญ ( ) สูงสุด
&& , d , f , t0
* , t0 , 3 , t1
- , c , t1 , t2
|| , b , t2 , t3
!= , a , t3 , t4

...และอื่นๆ ศึกษาเพิ่มเติมในหนังสือและชั้นเรียนนะครับ

       เราจะอาศัยโปรแกรมคอมไพล์เลอร์ที่ชื่อ Grammar2 จากหัวข้อที่แล้วมาประยุกต์สร้าง intermediate code สำหรับการบวก, การลบ การคูณและการหารขึ้น โดยให้ชื่อว่า Grammar3 มีรูปแบบดังนี้

<S> -> <AddSubDigit>
<AddSubDigit> -> <MulDivDigit> <AddSubDigit2>
<AddSubDigit2> -> <AddSubSymbol> <MulDivDigit> <AddSubDigit2> | empty
<MulDivDigit> -> <Digit> <MulDivDigit2>
<MulDivDigit2> -> <MulDivSymbol> <Digit> <MulDivDigit2> | empty
<AddSubSymbol> -> "+" | "-"
<MulDivSymbol> -> "*" | "/"
<Digit> -> "1" | "2" | "3"

- จากชื่อ AddDigit เป็น AddSubDigit สำหรับการบวกและการลบ
- จากชื่อ AddDigit2 เป็น AddSubDigit2 สำหรับการบวกและการลบ
- เพิ่ม MulDivDigit สำหรับการคูณและการหาร
- เพิ่ม MulDivDigit2 สำหรับการคูณและการหาร
- เพิ่ม non-terminal ชื่อ AddSubSymbol สำหรับเลือก terminal เป็น + หรือ -
- เพิ่ม non-terminal ชื่อ MulDivSymbol สำหรับเลือก terminal เป็น * หรือ /
- ลำดับความสำคัญการคูณและการหารเท่ากันจากซ้ายไปขวา
- ลำดับความสำคัญการบวกและการลบเท่ากันจากซ้ายไปขวา
- ลำดับความสำคัญการคูณและการหาร มากกว่า การบวกและการลบ
- ดาวน์โหลดโปรแกรม Compiler ที่เขียนด้วย Grammar 3 (Run ด้วย NetBeans IDE)

รูปประกอบ : source code ที่ใช้ทดสอบ

รูปประกอบ : ผลลัพธ์

อ่านเนื้อหาที่เกี่ยวข้อง ก่อนหน้า หรือ ถัดไป

ไม่มีความคิดเห็น:

แสดงความคิดเห็น