วันอาทิตย์ที่ 31 ตุลาคม พ.ศ. 2553

Compiler : การตรวจสอบ Syntax (ภาษา Java)

กระบวนการ Parser (ต่อ) : ขั้นตอนการตรวจสอบ Syntax
    เราจะใช้วิธีการให้ค่าล่วงหน้าแก่ currentToken หนึ่งค่าเสมอ เพื่อนำค่าที่ได้ไปตรวจสอบกับ Terminal ของแต่ละ Grammar ย่อยที่จะถูกเปลี่ยนให้อยู่ในรูปแบบเมธอด ดังนี้
(รูปหมายเลข 181)
- กลับไปยังบทความ โปรแกรม Compiler 2 (ภาษา Java) เพื่อคัดลอก Grammar ที่ออกแบบไว้แล้วมาใช้ (ตัวอักษรสีน้ำเงิน)

(รูปหมายเลข 182)
- วาง Grammar ที่คัดลอกไว้ส่วนท้ายสุดของคลาส Parser (แต่ยังอยู่ภายในขอบเขตของคลาสนะครับ) แล้วใส่ Comment ไว้ตามรูป

(รูปหมายเลข 183)
- แต่ละ Grammar ย่อยจะหมายถึงหนึ่งเมธอดที่มี private void นำเสมอ
- เปลี่ยน Grammar ย่อยทั้งหมดให้เป็นเมธอดที่มีชื่อเหมือนตัวผลิตของ Grammar ย่อยเหล่านั้น (ดังตัวอย่างรูปข้างต้น)

*** หมายเหตุ ตัวผลิตหมายถึง Non-Terminal ทางซ้ายของเครื่องหมาย ->

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

(รูปหมายเลข 184)
- กรณีตัวผลิต (ซ้ายของเครื่องหมาย ->) ระบุถึงผลผลิต Non-Terminal ใดๆ (ขวาเครื่องหมาย ->) ให้เรียกไปยังเมธอดของผลผลิตนั้นได้เลย
- จากรูปตัวผลิต start ระบุถึงผลผลิต variableDeclaration ตามด้วย mainFunction จึงเรียกเมธอด variableDeclaration() และ mainFunction() ตามลำดับครับ

(รูปหมายเลข 185)
- กรณีนี้ผลผลิตมีสองทางเลือก คือไปทาง type name ass... หรือไปทาง empty
- เราจะต้องโค้ดให้คอมพิวเตอร์เลือกทางหนึ่งทางใด ดังนั้นบรรทัดที่ 98 (จากรูป) ผมจึงถามว่า currentToken ปัจจุบันใช่ type หรือไม่ หากใช่จึงเลือกทาง type name ass... หากไม่ใช่จึงเลือกทาง empty
- นอกจากนี้ภายใน Grammar ย่อยนี้ยังพบว่าทางเลือก type name ass... มี Terminal ที่เป็น ";" อยู่ด้วย บรรทัดที่ 107 (จากรูป) จึงต้องตรวจสอบ currentToken ปัจจุบัน ใช่สัญลักษณ์ ";" หรือไม่ ถ้าไม่ใช่จะต้องแจ้ง error ครับ แต่ถ้าใช่จึงผ่านไป พร้อมกับให้ค่า currentToken เป็นค่าต่อไปด้วยการเรียกเมธอด read (เพราะ ";" เป็นส่วนหนึ่งของ Grammar ย่อยนี้)

(รูปหมายเลข 186)
- กรณีที่มีสองทางเลือกขึ้นไป และมี Terminal ขึ้นต้นในหนึ่งหรือหลายทางเลือกเหล่านั้น เราสามารถใช้ Terminal ดังกล่าวเป็นตัวเลือกทางเลือกได้
- บรรทัดที่ 121 (จากรูป) ใช้ Terminal ที่เป็น "," เลือกระหว่าง "," name ass... กับ empty
- สำหรับทางเลือก "," name ass... หลังจากถามถึง "," ต้องเรียกเมธอด read ด้วย (เพราะ "," เป็นส่วนหนึ่งของ Grammar ย่อยนี้)

(รูปหมายเลข 187)
- กรณี Grammar ย่อยผลิตได้เฉพาะ Terminal เพียงอย่างเดียว (จะกี่ทางเลือกก็ตาม) เช่น addSubSymbol, mulDivSymbol, name, type, literal และอื่นๆ ให้เขียนเรียกเมธอด read เพื่อให้ค่าแก่ currentToken ได้เลย

(รูปหมายเลข 188)
- รูปนี้เป็นอีกกรณีตัวอย่างของกรณีที่ผ่านมา (งงเปล่า) คือสามารถใช้ Terminal เป็นทางเลือกได้
- ให้สังเกตว่า "(" expression แล้วจะต้องปิดท้ายด้วย ")" ดังนั้นกรณีเช่นนี้ก็อย่าลืมถามถึง ")" ในบรรทัดที่ 212 (ตามรูป)

คำถามที่ถามกันบ่อย : จะรู้ได้อย่างไรว่าเมื่อไหร่ควรเรียกเมธอด read ?
- เมื่อใดก็ตามที่ Grammar ย่อยนั้นมี Terminal ที่เป็นผลผลิตอยู่ภายใน จะเรียกเมธอด read
- หรืออีกความหมายหนึ่งคือ จะไม่เรียกเมธอด read หากเพียงถามถึง Terminal ที่ไม่มีอยู่ใน Grammar ย่อยหรือเมธอดที่กำลังพิจารณาอยู่ เช่น ไม่เรียกเมธอด read ในเมธอด isType เพราะไม่มี Grammar ย่อยระบุตัวตนของ "int" หรือ "float"

(รูปหมายเลข 189)
- เมื่อเพื่อนๆโค้ดการทำงานภายในของเมธอดเสร็จสิ้นแล้ว ก่อนเราจะทดสอบ Syntax ภาษา ให้เพิ่มโค้ดเรียกเมธอด read เพื่อเริ่มต้นให้ค่า currentToken ตามด้วยเมธอด start ที่ Constructor ของคลาส Parser นี้ด้วยครับ

ทดสอบ
(รูปหมายเลข 190)
- บรรทัดที่ 17 (จากรูป) เปิด Comment ในส่วนของ Parser แล้ว Run ครับ
- หากทำถูกวิธีและไม่ได้ปรับเปลี่ยน Source Code ที่อยู่ในไฟล์ SourceCode.txt จะไม่เกิด error ใดๆครับ (ไม่มีอะไรเกิดขึ้นเลย)

***หมายเหตุ อยากให้ลองปรับเปลี่ยน Source Code ที่อยู่ในไฟล์ SourceCode.txt ให้ไม่เป็นไปตาม Grammar แล้ว Run ดูผล error ที่เกิดขึ้นนะครับ

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

1 ความคิดเห็น:

  1. I've been browsing on-line more than 3 hours today, yet I never discovered any fascinating article like yours. It is lovely price enough for me. In my view, if all web owners and bloggers made excellent content as you probably did, the net will be a lot more helpful than ever before.

    Review my web page ... new cellulite treatment

    ตอบลบ