กลับไปหน้าบทความ

อ่าน 2 นาที

ตัวแยกวิเคราะห์แบบเรียกซ้ำหาง

อัลกอริทึมการแยกวิเคราะห์

ในวิทยาการคอมพิวเตอร์ ตัวแยกวิเคราะห์แบบเรียกซ้ำส่วนท้าย ( tail recursive parsers)เป็นการดัดแปลงมาจากตัวแยกวิเคราะห์แบบเรียกซ้ำลง (recursive descent parsers ) ที่พบได้ทั่วไป

ตัวแยกวิเคราะห์แบบเรียกซ้ำหาง

ในวิทยาการคอมพิวเตอร์ ตัวแยกวิเคราะห์แบบเรียกซ้ำส่วนท้าย ( tail recursive parsers)เป็นการดัดแปลงมาจากตัวแยกวิเคราะห์แบบเรียกซ้ำลง (recursive descent parsers ) ที่พบได้ทั่วไป ตัวแยกวิเคราะห์แบบเรียกซ้ำส่วนท้ายมักใช้ในการแยกวิเคราะห์ไวยากรณ์แบบเรียกซ้ำทางซ้าย (left recursive grammars) โดยใช้พื้นที่สแต็กน้อยกว่าตัวแยกวิเคราะห์แบบเรียกซ้ำลงทั่วไป หากเครื่องมือรันไทม์หรือเครื่องมือคอมไพล์มีวิธีในการปรับแต่งการเรียกส่วนท้ายให้เป็นการกระโดด นอกจากนี้ยังเขียนได้ง่ายอีกด้วย ตัวแยกวิเคราะห์แบบเรียกซ้ำลงทั่วไปทำให้การแยกวิเคราะห์ไวยากรณ์แบบเรียกซ้ำทางซ้ายเป็นไปไม่ได้ (เนื่องจากปัญหาวงวนไม่สิ้นสุด) ตัวแยกวิเคราะห์แบบเรียกซ้ำส่วนท้ายใช้วิธีการรีพาเรนต์โหนดที่ทำให้สามารถทำเช่นนั้นได้

ตัวอย่าง

เมื่อกำหนด ไวยากรณ์ EBNFดังต่อไปนี้:

E : T T : T { '+' F } | F F : F { '*' I } | I I : < ตัวระบุ>

ตัวแยกวิเคราะห์แบบเรียกซ้ำหางอย่างง่ายสามารถเขียนได้คล้ายกับตัวแยกวิเคราะห์แบบเรียกซ้ำลงล่าง โดยทั่วไปแล้วอัลกอริทึมสำหรับการแยกวิเคราะห์ไวยากรณ์แบบนี้โดยใช้ต้นไม้ไวยากรณ์นามธรรมมีดังนี้:

  1. วิเคราะห์ไวยากรณ์ระดับถัดไปและรับโครงสร้างต้นไม้ผลลัพธ์ กำหนดให้เป็นต้นไม้แรกF
  2. แม้ว่าจะมีโทเค็นสิ้นสุดTที่สามารถกำหนดให้เป็นโหนดแม่ของโหนดนี้ได้:
    1. จัดสรรโหนดใหม่N
    2. กำหนดให้ตัวดำเนินการปัจจุบันของN เป็นโทเค็นอินพุตปัจจุบัน
    3. เลื่อนอินพุตไปหนึ่งโทเค็น
    4. กำหนดให้ซับทรีด้านซ้ายของN เป็น F
    5. แยกวิเคราะห์ลงไปอีกระดับหนึ่ง แล้วจัดเก็บผลลัพธ์นี้เป็นโครงสร้างต้นไม้ถัดไปX
    6. กำหนดให้ซับทรีด้านขวาของN เป็น X
    7. ตั้งค่าFเป็นN
  3. ส่งคืนN

ตัวอย่างพื้นฐานของตัวแยกวิเคราะห์ประเภทนี้ในภาษาซีแสดงไว้ที่นี่แล้ว รายละเอียดการใช้งานถูกละเว้นเพื่อความง่าย

typedef struct _exptree exptree ; struct _exptree { char token ; exptree * left ; exptree * right ; };exptree * parse_e ( void ) { return parse_t (); }exptree * parse_t ( void ) { exptree * first_f = parse_f (); while ( cur_token () == '+' ) { exptree * replace_tree = alloc_tree (); replace_tree -> token = cur_token (); replace_tree -> left = first_f ; next_token (); replace_tree -> right = parse_f (); first_f = replace_tree ; }คืนค่าfirst_f ; }exptree * parse_f ( void ) { exptree * first_i = parse_i (); while ( cur_token () == '*' ) { exptree * replace_tree = alloc_tree (); replace_tree -> token = cur_token (); replace_tree -> left = first_i ; next_token (); replace_tree -> right = parse_i (); first_i = replace_tree ; } return first_i ; }exptree * parse_i ( void ) { exptree * i = alloc_tree (); i -> left = i -> right = NULL ; i -> token = cur_token (); next_token (); return i ; }

ดูเพิ่มเติม

อ่านเพิ่มเติม

  • บทความในวารสาร Dr. Dobbs Journal ฉบับเดือนมกราคม 2549 เรื่อง "Recursive Descent, Tail Recursion, & the Dreaded Double Divide"
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Tail_recursive_parser&oldid=1334861274 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ ตัวแยกวิเคราะห์แบบเรียกซ้ำหาง

ในวิทยาการคอมพิวเตอร์ ตัวแยกวิเคราะห์แบบเรียกซ้ำส่วนท้าย ( tail recursive parsers)เป็นการดัดแปลงมาจากตัวแยกวิเคราะห์แบบเรียกซ้ำลง (recursive descent parsers ) ที่พบได้ทั่วไป

อ่านเพิ่มเติม

บทความในวารสาร Dr. Dobbs Journal ฉบับเดือนมกราคม 2549 เรื่อง "Recursive Descent, Tail Recursion, & the Dreaded Double Divide" ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Tail_recursive_parser&oldid=1334861274 "