Compiler
Posted by ejeepss on กันยายน 19th, 2007
คอมไพเลอร์ นักพัฒนาระบบงานหลายคนรู้จักกันดี มันคือการแปลงโปรแกรมที่พัฒนาขึ้นด้วยภาษาระดับสูง ไปเป็นภาษาเครื่อง แต่นั่นมันสมัยก่อน สมัยนี้มีภาษาจาวา (Java) , ดอดเน็ต (.NET FramWork) การคอมไพล์ได้เปลี่ยนไปเป็นการแปลเป็นภาษาเป้าหมาย และหากเป็นจาวา ก็ใช้ จาวาวิชวลเมอฃีน (Java Visual Machine : JVM) หรือหากเป็น ดอดเน็ต จะใช้ (Just In Time :JIT Compiler) เพื่อแปลไปเป็นภาษาเครื่อง ตามแต่สภาวะแวดล้อมของเครื่อง (Environment) ในขณะนั้น เพื่อทำงานต่อไป
บทความนี้จะแสดงถึงขึ้นตอนการทำงานหลัก ๆ ของคอมไพเลอร์ ซึ่งในปัจจุบัน คอมไพเลอร์สมัยใหม่ อาจมีขั้นตอนมากกว่า และมีเทคนิคเพิ่มเติมขึ้นมาก ซึ่งแต่ละผลิตภัณฑ์ จะไม่บอกรายละเอียดการทำงาน เนื่องจากเป็นความลับของแต่ละผลิตภัณฑ์ของตน แต่บทความนี้เป็นหลักการทำงาน ที่ทุก ๆ คอมไพเลอร์จะต้องมีใช้งานอย่างน้อย
1. ความหมายของคอมไพเลอร์
ภาษาเครื่อง (Machine Language) นั้น เป็นภาษาที่เครื่องคอมพิวเตอร์สามารถเข้าใจ และสามารถติดต่อได้โดยตรงกับเครื่องคอมพิวเตอร์ ซึ่งอยู่ในรูปแบบของบิท (Bit) ริจิสเตอร์ (Register) ซึ่งเป็นเรื่องยากที่มนุษย์จะทำความเข้าใจและเขียนคำสั่งดังกล่าว จึงทำให้เกิดการพัฒนาภาษาสัญลักษณ์ (Symbol Language) ได้แก่ ภาษาแอสเซมบลี (Assembly Language) แต่ภาษาสัญลักษณ์นั้นยังคงยากสำหรับมนุษย์ จึงได้เกิดการพัฒนาภาษาในระดับสูงซึ่งมีความคล้ายเคียงกับภาษามนุษย์ ได้แก่ ภาษาซี (C language) และภาษาจาวา เป็นต้น และใช้คอมไพเลอร์แปลภาษาระดับสูงดังกล่าวให้เป็นภาษาเครื่องอีกครั้ง
2. ขั้นตอนการทำงานของคอมไพเลอร์
เริ่มตั้งแต่การตรวจสอบความถูกต้องของคำสั่งจากภาษานั้น ๆ ถูกต้องตามกฎเกณฑ์หรือไม่ ตัวอย่างเช่นกฎเกณฑ์ภาษาจาวา ไม่สามารถเขียนเพียงตัวแปรเพียงตัวเดียวได้ เช่น X; แต่สามารถเขียนการกระทำกับตัวแปร เช่น X++; หรือ X=5; ได้ และเมื่อคำสั่งถูกต้องตามกฎเกณฑ์ จึงดำเนินการแปลเป็นภาษาเครื่อง และทำงานได้ผลลัพท์เช่นเดียวกับโปรแกรมที่เขียนขึ้นจากภาษาต้นแบบ ซึ่งขั้นตอนการทำงานของคอมไพเลอร์นั้นประกอบด้วยขั้นตอน 5 ขั้นตอนหลัก (Aho et. al., 1988) ดังแสดงในภาพ 1

ภาพที่ 1 แสดงขั้นตอนการทำงานของคอมไพเลอร์
![]()
ภา่พที่ 2 แสดงขั้นตอนการทำงานของ Compiler อย่างละเอียดจาก Wikipedia
1. เลกซิคัลอนาไลเซอร์
ทำหน้าที่อ่านอักขระจากโปรแกรมต้นแบบแล้วแยกอักขระเหล่านั้นออกเป็นกลุ่ม ๆ เรียกว่า โทเคน (Token) ตามลักษณะหน้าที่ที่ได้ระบุไว้ในโครงสร้างและกฎเกณฑ์ของภาษา ซึ่งเมื่อแยกอักขระแล้วจะได้ ตัวแปร และโอเปอร์เรเตอร์
2. ซีนแทกอนาไลเซอร์
ทำหน้าที่ตรวจสอบความถูกต้องโครงสร้างของภาษา ต้นแบบว่าถูกต้องตามกฎไวยากรณ์ของภาษานั้น ๆ หรือไม่
3. ซีแมนติกอนาไลเซอร์
ทำหน้าตรวจสอบความหมาย ของภาษาและโครงสร้างของรหัสชุดคำสั่งที่ผ่านการตรวจสอบความถูกต้องของโครงสร้างแล้ว นำมาทำรหัสระหว่างกลาง ตัวอย่างรหัสระหว่างกลาง ได้แก่ สัญกรพลิช (Polish Notation) เป็นต้น ซึ่งรหัสระหว่างกลางสามารถที่จะถูกแปลงเป็นภาษาเครื่องต่าง ๆ ที่ไม่เหมือนกันได้ง่าย
4. โค้ดออฟติไมเซอร์
เป็นขั้นตอนการแก้ไข ปรับปรุง รหัสระหว่างกลาง ให้มีความสามารถมากยิ่งขึ้น เช่น หากโปรแกรมมีการคำนวณค่าเดิม ๆ ซ้ำ โค้ดออฟติไมเซอร์จะทำการลดขั้นตอนการคำนวณลง โดยให้ใช้ค่าที่ได้คำนวณแล้วแทน
5. โค้ดเจนเนอเรเตอร์
เป็นส่วนที่เพิ่มเติมเพื่อปรับปรุงภาษากลางให้เป็นภาษาเครื่อง ซึ่งจะขึ้นอยู่กับซีพียู และเครื่องปลายทาง เช่น การกำหนดตำแหน่งของข้อมูลในหน่วยความจำ การกำหนดรีจิสเตอร์ต่าง ๆ ที่จะใช้
6. การจัดการตาราง
เป็นอีกหน้าที่ที่สำคัญของคอมไพเลอร์ จะต้องทำการบันทึก ชื่อตัวแปร ชื่อโพรซีเดอร์ ชื่อฟังก์ชั่น ที่ปรากฎอยู่ในโปรแกรมต้นแบบไว้ในตาราง รวมทั้งบันทึกรายละเอียดต่าง ๆ เช่น ชนิด และแอดเดรสของแต่ละตัวแปร
7. การตรวจจับและดำเนินการต่อเมื่อพบความผิดพลาด
คอมไพเลอร์ที่ดีหากโปรแกรมต้นแบบเขียนผิดหลักภาษา จะต้องแสดงข้อผิดพลาดที่ใกล้เคียงความจริงมากที่สุดให้กับผู้พัฒนาโปรแกรมทราบ นอกจากการตรวจจับข้อผิดพลาดแล้ว คอมไพเลอร์ที่ดีจะต้องสามารถดำเนินการต่อเพื่อตรวจสอบข้อผิดพลาดอื่น ๆ ได้อีก ไม่หยุดการทำงานเมื่อพบข้อผิดพลาดเพียงครั้งเดียว คอมไพเลอร์ที่ดีจะต้องพยายามที่จะแก้ไขความผิดพลาดที่เกิดขึ้น (Error Correction) เพื่อให้สามารถคอมไพล์โปรแกรมต้นแบบต่อไป และนำส่วนที่พยายามแก้ไขให้ถูกต้องนั้นรายงานให้กับผู้พัฒนาโปรแกรมทราบเมื่อเสร็จสิ้นการคอมไพล์
ขอบคุณที่สนใจอ่าน
Reference
V. Aho, R. Sethi and J. D. Ullman. Compilers Principles, Techniques, and Tools, Addison-
Wesley. 1988.