เราจะใช้วิธีการให้ค่าล่วงหน้าแก่ currentToken หนึ่งค่าเสมอ เพื่อนำค่าที่ได้ไปตรวจสอบกับ Terminal ของแต่ละ Grammar ย่อยที่จะถูกเปลี่ยนให้อยู่ในรูปแบบเมธอด ดังนี้
(รูปหมายเลข 181)
(รูปหมายเลข 182)
(รูปหมายเลข 183)
- เปลี่ยน Grammar ย่อยทั้งหมดให้เป็นเมธอดที่มีชื่อเหมือนตัวผลิตของ Grammar ย่อยเหล่านั้น (ดังตัวอย่างรูปข้างต้น)
*** หมายเหตุ ตัวผลิตหมายถึง Non-Terminal ทางซ้ายของเครื่องหมาย ->
รูปต่อจากนี้เป็นตัวอย่าง การเรียกเมธอดในหลายกรณีที่เกิดขึ้นจากลักษณะของ Grammar ให้เพื่อนๆใช้กรณีตัวอย่างเหล่านี้กับทุกๆเมธอดที่สร้างจาก Grammar ย่อย (ครั้นจะเอาโค้ดมาแปะให้ดูหมดก็ไม่ไหว ลองโค้ดและคิดตามไปนะครับ ส่วนท้ายของบทความผมมีให้โหลดตัวที่สำเร็จไว้แล้ว ค่อยตรวจดูว่าตรงกันหรือไม่ เข้าใจในเรื่องเดียวกันหรือไม่ ? ^^)
(รูปหมายเลข 184)
- จากรูปตัวผลิต start ระบุถึงผลผลิต variableDeclaration ตามด้วย mainFunction จึงเรียกเมธอด variableDeclaration() และ mainFunction() ตามลำดับครับ
(รูปหมายเลข 185)
- เราจะต้องโค้ดให้คอมพิวเตอร์เลือกทางหนึ่งทางใด ดังนั้นบรรทัดที่ 98 (จากรูป) ผมจึงถามว่า currentToken ปัจจุบันใช่ type หรือไม่ หากใช่จึงเลือกทาง type name ass... หากไม่ใช่จึงเลือกทาง empty
- นอกจากนี้ภายใน Grammar ย่อยนี้ยังพบว่าทางเลือก type name ass... มี Terminal ที่เป็น ";" อยู่ด้วย บรรทัดที่ 107 (จากรูป) จึงต้องตรวจสอบ currentToken ปัจจุบัน ใช่สัญลักษณ์ ";" หรือไม่ ถ้าไม่ใช่จะต้องแจ้ง error ครับ แต่ถ้าใช่จึงผ่านไป พร้อมกับให้ค่า currentToken เป็นค่าต่อไปด้วยการเรียกเมธอด read (เพราะ ";" เป็นส่วนหนึ่งของ Grammar ย่อยนี้)
(รูปหมายเลข 186)
- บรรทัดที่ 121 (จากรูป) ใช้ Terminal ที่เป็น "," เลือกระหว่าง "," name ass... กับ empty
- สำหรับทางเลือก "," name ass... หลังจากถามถึง "," ต้องเรียกเมธอด read ด้วย (เพราะ "," เป็นส่วนหนึ่งของ Grammar ย่อยนี้)
(รูปหมายเลข 187)
(รูปหมายเลข 188)
- ให้สังเกตว่า "(" expression แล้วจะต้องปิดท้ายด้วย ")" ดังนั้นกรณีเช่นนี้ก็อย่าลืมถามถึง ")" ในบรรทัดที่ 212 (ตามรูป)
คำถามที่ถามกันบ่อย : จะรู้ได้อย่างไรว่าเมื่อไหร่ควรเรียกเมธอด read ?
- เมื่อใดก็ตามที่ Grammar ย่อยนั้นมี Terminal ที่เป็นผลผลิตอยู่ภายใน จะเรียกเมธอด read
- หรืออีกความหมายหนึ่งคือ จะไม่เรียกเมธอด read หากเพียงถามถึง Terminal ที่ไม่มีอยู่ใน Grammar ย่อยหรือเมธอดที่กำลังพิจารณาอยู่ เช่น ไม่เรียกเมธอด read ในเมธอด isType เพราะไม่มี Grammar ย่อยระบุตัวตนของ "int" หรือ "float"
(รูปหมายเลข 189)
ทดสอบ
(รูปหมายเลข 190)
- หากทำถูกวิธีและไม่ได้ปรับเปลี่ยน Source Code ที่อยู่ในไฟล์ SourceCode.txt จะไม่เกิด error ใดๆครับ (ไม่มีอะไรเกิดขึ้นเลย)
***หมายเหตุ อยากให้ลองปรับเปลี่ยน Source Code ที่อยู่ในไฟล์ SourceCode.txt ให้ไม่เป็นไปตาม Grammar แล้ว Run ดูผล error ที่เกิดขึ้นนะครับ
อ่านเนื้อหาที่เกี่ยวข้อง ก่อนหน้า หรือ ถัดไป