ฉันได้อ่านบทความบทความและส่วน 4.1.4 ตอนที่ 4 ของคอมไพเลอร์: หลักการเทคนิคและเครื่องมือ (รุ่นที่ 2) (หรือที่รู้จักกันในชื่อ "The Dragon Book") ซึ่งทุกคนกล่าวถึงหัวข้อการกู้คืนข้อผิดพลาดทางไวยากรณ์ อย่างไรก็ตามหลังจากทดลองกับคอมไพเลอร์สมัยใหม่หลาย ๆ ตัวฉันได้เห็นแล้วว่าพวกเขากู้คืนจากข้อผิดพลาดทางความหมายเช่นเดียวกับข้อผิดพลาดทางไวยากรณ์
ฉันเข้าใจอัลกอริทึมและเทคนิคที่อยู่เบื้องหลังคอมไพเลอร์ที่กู้คืนจากข้อผิดพลาดเกี่ยวกับวากยสัมพันธ์ แต่ฉันไม่เข้าใจว่าคอมไพเลอร์สามารถกู้คืนจากข้อผิดพลาดทางความหมายได้อย่างไร
ขณะนี้ฉันกำลังใช้รูปแบบผู้เยี่ยมชมที่แตกต่างกันเล็กน้อยเพื่อสร้างรหัสจากแผนผังไวยากรณ์นามธรรมของฉัน พิจารณาคอมไพเลอร์ของฉันรวบรวมการแสดงออกต่อไปนี้:
1 / (2 * (3 + "4"))
คอมไพเลอร์จะสร้างแผนผังไวยากรณ์นามธรรมต่อไปนี้:
op(/)
|
-------
/ \
int(1) op(*)
|
-------
/ \
int(2) op(+)
|
-------
/ \
int(3) str(4)
ขั้นตอนการสร้างรหัสจะใช้รูปแบบผู้เยี่ยมชมเพื่อสำรวจทรีไวยากรณ์แบบนามธรรมซ้ำ ๆ และดำเนินการตรวจสอบชนิด ต้นไม้ไวยากรณ์นามธรรมจะถูก traversed จนกว่าคอมไพเลอร์มาถึงส่วนด้านในสุดของการแสดงออก; (3 + "4")
. คอมไพเลอร์ตรวจสอบแต่ละด้านของนิพจน์และเห็นว่าพวกเขาไม่เท่าเทียมกันทางความหมาย คอมไพเลอร์ทำให้เกิดข้อผิดพลาดประเภท ที่นี่ปัญหาอยู่ที่ไหน คอมไพเลอร์ควรทำอย่างไร?
เพื่อให้คอมไพเลอร์กู้คืนจากข้อผิดพลาดนี้และพิมพ์การตรวจสอบส่วนนอกของนิพจน์ต่อไปก็จะต้องส่งคืนประเภท ( หรือ) บางส่วนจากการประเมินส่วนด้านในสุดของนิพจน์ไปยังส่วนในสุดถัดไปของนิพจน์ แต่มันก็ไม่ได้มีประเภทที่จะกลับ เนื่องจากข้อผิดพลาดประเภทเกิดขึ้นจึงไม่มีการอนุมานประเภทint
str
วิธีแก้ปัญหาที่เป็นไปได้ข้อหนึ่งที่ฉันได้รับการกล่าวอ้างคือถ้าเกิดข้อผิดพลาดประเภทควรมีการยกข้อผิดพลาดและค่าพิเศษที่บ่งบอกว่าเกิดข้อผิดพลาดประเภทเกิดขึ้น หากการเรียกผ่านการสำรวจเส้นทางก่อนหน้าพบค่านี้พวกเขารู้ว่ามีข้อผิดพลาดประเภทเกิดขึ้นลึกกว่าในโครงสร้างไวยากรณ์นามธรรมและควรหลีกเลี่ยงการพยายามอนุมานประเภท ในขณะที่วิธีนี้ใช้งานได้ดูเหมือนว่าจะไม่มีประสิทธิภาพมาก หากส่วนในสุดของการแสดงออกลึกลงไปในทรีไวยากรณ์ของนามธรรมผู้แปลจะต้องทำการเรียกซ้ำหลายครั้งเพื่อให้ตระหนักว่าไม่มีการทำงานจริงและสามารถกลับมาจากแต่ละอันได้
เป็นวิธีที่ฉันอธิบายไว้ข้างต้นใช้ (ฉันสงสัยมัน) ถ้าเป็นเช่นนั้นมันไม่ได้มีประสิทธิภาพ? ถ้าไม่วิธีการที่ใช้เมื่อคอมไพเลอร์กู้คืนจากข้อผิดพลาดทางความหมายคืออะไร?