อะไรคือความแตกต่างระหว่างตัวแยกวิเคราะห์ LR, SLR และ LALR


103

อะไรคือความแตกต่างที่แท้จริงระหว่างตัวแยกวิเคราะห์ LR, SLR และ LALR ฉันรู้ว่า SLR และ LALR เป็นประเภทของตัวแยกวิเคราะห์ LR แต่อะไรคือความแตกต่างที่แท้จริงของตารางแยกวิเคราะห์

และจะแสดงได้อย่างไรว่าไวยากรณ์เป็น LR, SLR หรือ LALR? สำหรับไวยากรณ์ LL เราต้องแสดงให้เห็นว่าเซลล์ใด ๆ ของตารางการแยกวิเคราะห์ไม่ควรมีกฎการผลิตหลายข้อ กฎที่คล้ายกันสำหรับ LALR, SLR และ LR หรือไม่

ตัวอย่างเช่นเราจะแสดงให้เห็นว่าไวยากรณ์ได้อย่างไร

S --> Aa | bAc | dc | bda
A --> d

LALR คือ (1) แต่ไม่ใช่ SLR (1)?


แก้ไข (ybungalobill) : ฉันไม่ได้รับคำตอบที่น่าพอใจว่าความแตกต่างระหว่าง LALR และ LR คืออะไร ดังนั้นตารางของ LALR จึงมีขนาดเล็กลง แต่สามารถจดจำไวยากรณ์ LR ได้เพียงบางส่วนเท่านั้น ใครช่วยอธิบายเพิ่มเติมเกี่ยวกับความแตกต่างระหว่าง LALR และ LR ได้โปรด? LALR (1) และ LR (1) จะเพียงพอสำหรับคำตอบ ทั้งคู่ใช้ 1 โทเค็นมองไปข้างหน้าและทั้งคู่ขับเคลื่อนด้วยตาราง! ต่างกันอย่างไร?


แม้ว่าฉันกำลังมองหาคำตอบที่เหมาะสมเกี่ยวกับเรื่องนี้ LALR (1) เป็นเพียงการปรับเปลี่ยน LR (1) เล็กน้อยซึ่งขนาดตารางจะลดลงเพื่อให้เราสามารถลดการใช้หน่วยความจำได้ ...
— vikkyhacks

คำตอบ:


65

ตัวแยกวิเคราะห์ SLR, LALR และ LR สามารถใช้งานได้โดยใช้เครื่องจักรที่ขับเคลื่อนด้วยตารางเดียวกัน

โดยพื้นฐานแล้วอัลกอริทึมการแยกวิเคราะห์จะรวบรวมโทเค็นอินพุตถัดไป T และให้คำปรึกษาสถานะปัจจุบัน S (และ lookahead, GOTO และตารางการลดที่เกี่ยวข้อง) เพื่อตัดสินใจว่าจะทำอย่างไร:

  • SHIFT: หากตารางปัจจุบันบอกว่าให้ SHIFT บนโทเค็น T คู่ (S, T) จะถูกผลักลงบนสแต็กแยกวิเคราะห์สถานะจะเปลี่ยนไปตามที่ตาราง GOTO ระบุสำหรับโทเค็นปัจจุบัน (เช่น GOTO (T) ) โทเค็นอินพุตอื่น T 'จะถูกดึงออกมาและกระบวนการจะทำซ้ำ
  • การลด: ทุกสถานะมี 0, 1 หรือการลดที่เป็นไปได้มากมายที่อาจเกิดขึ้นในสถานะ ถ้าตัวแยกวิเคราะห์เป็น LR หรือ LALR โทเค็นจะถูกตรวจสอบเทียบกับชุด lookahead สำหรับการลดที่ถูกต้องทั้งหมดสำหรับสถานะ ถ้าโทเค็นตรงกับ lookahead ที่ตั้งค่าไว้สำหรับการลดสำหรับกฎไวยากรณ์ G = R1 R2 .. Rn การลดสแต็กและการเลื่อนจะเกิดขึ้น: การดำเนินการเชิงความหมายสำหรับ G ถูกเรียกสแต็กจะโผล่ n (จาก Rn) ครั้งคู่ ( S, G) ถูกผลักลงบนสแต็กสถานะใหม่ S 'ถูกตั้งค่าเป็น GOTO (G) และวงจรจะทำซ้ำด้วยโทเค็นเดียวกัน T ถ้าตัวแยกวิเคราะห์เป็นตัวแยกวิเคราะห์ SLR จะมีกฎการลดมากที่สุดหนึ่งกฎสำหรับ สถานะและดังนั้นการดำเนินการลดสามารถทำได้โดยสุ่มสี่สุ่มห้าโดยไม่ต้องค้นหาเพื่อดูว่าการลดใช้ข้อใด เป็นประโยชน์สำหรับตัวแยกวิเคราะห์ SLR เพื่อทราบว่ามีหรือไม่เป็นการลดลงหรือไม่ นี่เป็นเรื่องง่ายที่จะบอกได้ว่าแต่ละรัฐบันทึกจำนวนการลดที่เกี่ยวข้องอย่างชัดเจนหรือไม่และการนับนั้นจำเป็นสำหรับเวอร์ชัน L (AL) R ในทางปฏิบัติอยู่ดี
  • ข้อผิดพลาด: หากไม่สามารถ SHIFT หรือ REDUCE ได้แสดงว่าข้อผิดพลาดทางไวยากรณ์จะถูกประกาศ

ดังนั้นถ้าพวกเขาใช้เครื่องจักรเดียวกันทั้งหมดประเด็นคืออะไร?

ค่าที่อ้างว่าใน SLR คือความเรียบง่ายในการนำไปใช้งาน คุณไม่จำเป็นต้องสแกนผ่านการตรวจสอบการลดจำนวนที่เป็นไปได้ในการตรวจสอบชุด lookahead เนื่องจากมีอยู่มากที่สุดและนี่เป็นการดำเนินการเพียงอย่างเดียวหากไม่มี SHIFT ออกจากสถานะ การลดที่ใช้สามารถแนบกับสถานะโดยเฉพาะดังนั้นเครื่องจักรแยกวิเคราะห์ SLR จึงไม่จำเป็นต้องตามล่าหามัน ในทางปฏิบัติตัวแยกวิเคราะห์ L (AL) R จะจัดการกับชุดภาษาที่มีประโยชน์มากขึ้นและมีงานพิเศษเพียงเล็กน้อยในการนำไปใช้ซึ่งไม่มีใครใช้ SLR ยกเว้นเป็นการฝึกหัดทางวิชาการ

ความแตกต่างระหว่าง LALR และ LR จะทำอย่างไรกับโต๊ะเครื่องกำเนิดไฟฟ้า. LR parser generator ติดตามการลดลงที่เป็นไปได้ทั้งหมดจากสถานะเฉพาะและชุด lookahead ที่แม่นยำ คุณจะลงเอยด้วยสถานะที่การลดทุกครั้งเชื่อมโยงกับผู้มองที่ตั้งค่าไว้จากบริบทด้านซ้าย สิ่งนี้มีแนวโน้มที่จะสร้างรัฐที่ค่อนข้างใหญ่ ตัวสร้างตัวแยกวิเคราะห์ LALR ยินดีที่จะรวมสถานะหากตาราง GOTO และชุด lookhead สำหรับการลดเข้ากันได้และไม่ขัดแย้งกัน สิ่งนี้ทำให้เกิดสถานะจำนวนน้อยกว่ามากในราคาที่ไม่สามารถแยกแยะลำดับสัญลักษณ์บางอย่างที่ LR สามารถแยกแยะได้ ดังนั้นตัวแยกวิเคราะห์ LR สามารถแยกวิเคราะห์ภาษาชุดใหญ่กว่าตัวแยกวิเคราะห์ LALR แต่มีตารางแยกวิเคราะห์ที่ใหญ่กว่ามาก ในทางปฏิบัติเราสามารถค้นหาไวยากรณ์ LALR ซึ่งใกล้เคียงกับภาษาเป้าหมายมากพอที่ขนาดของเครื่องสถานะนั้นคุ้มค่าที่จะปรับให้เหมาะสม

ทั้งสามใช้เครื่องจักรเดียวกัน SLR นั้น "ง่าย" ในแง่ที่คุณสามารถเพิกเฉยต่อเครื่องจักรเล็ก ๆ น้อย ๆ แต่มันก็ไม่คุ้มกับปัญหา LR แยกวิเคราะห์ชุดภาษาที่กว้างขึ้น แต่ตารางสถานะมักจะค่อนข้างใหญ่ นั่นทำให้ LALR เป็นตัวเลือกที่ใช้ได้จริง

จากที่กล่าวมาทั้งหมดนี้เป็นสิ่งที่ควรค่าแก่การรู้ว่าตัวแยกวิเคราะห์GLRสามารถแยกวิเคราะห์ภาษาที่ไม่มีบริบทโดยใช้เครื่องจักรที่ซับซ้อนกว่าแต่เป็นตารางเดียวกัน (รวมถึงเวอร์ชันที่เล็กกว่าที่ใช้โดย LALR) ซึ่งหมายความว่า GLR มีประสิทธิภาพมากกว่า LR, LALR และ SLR อย่างเคร่งครัด ค่อนข้างมากถ้าคุณสามารถเขียนไวยากรณ์ BNF มาตรฐาน GLR จะแยกวิเคราะห์ตามนั้น ความแตกต่างในเครื่องจักรคือ GLR ยินดีที่จะลองใช้การแยกวิเคราะห์หลาย ๆ ครั้งเมื่อมีข้อขัดแย้งระหว่างตาราง GOTO และหรือชุดผู้ค้นหา (GLR มีประสิทธิภาพอย่างไรเป็นอัจฉริยะอย่างแท้จริง [ไม่ใช่ของฉัน] แต่จะไม่พอดีกับโพสต์ SO นี้)

สำหรับฉันแล้วเป็นความจริงที่มีประโยชน์มหาศาล ฉันสร้างเครื่องวิเคราะห์โปรแกรมและตัวแปลงรหัสและตัวแยกวิเคราะห์เป็นสิ่งที่จำเป็น แต่ "ไม่น่าสนใจ"; งานที่น่าสนใจคือสิ่งที่คุณทำกับผลลัพธ์ที่แยกวิเคราะห์ดังนั้นจึงมุ่งเน้นไปที่การทำงานหลังการแยกวิเคราะห์ การใช้ GLR หมายความว่าฉันสามารถสร้างไวยากรณ์ที่ใช้งานได้ค่อนข้างง่ายเมื่อเทียบกับการแฮ็กไวยากรณ์เพื่อเข้าสู่รูปแบบที่ใช้งานได้ของ LALR สิ่งนี้มีความสำคัญมากเมื่อพยายามจัดการกับภาษาที่ไม่ใช่เชิงวิชาการเช่น C ++ หรือ Fortran ซึ่งคุณต้องการกฎหลายพันข้อเพื่อจัดการกับภาษาทั้งหมดได้ดีและคุณไม่ต้องการใช้ชีวิตของคุณในการพยายามแฮ็กกฎไวยากรณ์เพื่อ ตรงตามข้อ จำกัด ของ LALR (หรือแม้แต่ LR)

เป็นตัวอย่างที่มีชื่อเสียง C ++ ถือว่ายากมากที่จะแยกวิเคราะห์ ... โดยผู้ชายที่ทำการแยกวิเคราะห์ LALR C ++ นั้นตรงไปตรงมาในการแยกวิเคราะห์โดยใช้เครื่องจักร GLR โดยใช้กฎที่ให้ไว้ด้านหลังของคู่มืออ้างอิง C ++ (ฉันมีตัวแยกวิเคราะห์อย่างแม่นยำและไม่เพียง แต่จัดการกับวานิลลา C ++ เท่านั้น แต่ยังรวมถึงภาษาถิ่นของผู้ขายอีกด้วยซึ่งเป็นไปได้ในทางปฏิบัติเท่านั้นเนื่องจากเราใช้ตัวแยกวิเคราะห์ GLR, IMHO)

[แก้ไขพฤศจิกายน 2554: เราได้ขยายโปรแกรมแยกวิเคราะห์เพื่อรองรับ C ++ 11 ทั้งหมด GLR ช่วยให้ทำได้ง่ายขึ้นมาก แก้ไขสิงหาคม 2014: ตอนนี้จัดการ C ++ 17 ทั้งหมด ไม่มีอะไรพังหรือแย่ลง GLR ยังคงเป็นแมวเหมียว]


ไม่สามารถแยกวิเคราะห์ AFAIK C ++ ด้วย LR ได้เนื่องจากต้องการการมองไปข้างหน้าอย่างไม่มีที่สิ้นสุด ดังนั้นฉันไม่สามารถนึกถึงแฮ็กใด ๆ ที่จะทำให้สามารถแยกวิเคราะห์ด้วย LR ได้ นอกจากนี้การแยกวิเคราะห์ LRE ยังมีแนวโน้มดี
— Yakov Galka

5
GCC ใช้ในการแยกวิเคราะห์ C ++ โดยใช้ Bison == LALR คุณสามารถเพิ่มโปรแกรมแยกวิเคราะห์ของคุณได้ตลอดเวลาด้วยสารที่หนาพิเศษเพื่อจัดการกับกรณีต่างๆ (lookahead, is-this-a-typename) ที่ทำให้คุณปวดใจ คำถามคือ "แฮ็คเจ็บปวดแค่ไหน" สำหรับ GCC มันค่อนข้างเจ็บปวด แต่พวกเขาก็ทำให้มันได้ผล ไม่ได้หมายความว่าแนะนำให้ใช้ซึ่งเป็นประเด็นของฉันเกี่ยวกับการใช้ GLR
— Ira Baxter

ฉันไม่เข้าใจว่าการใช้ GLR ช่วยคุณในเรื่อง C ++ ได้อย่างไร หากคุณไม่รู้ว่าบางสิ่งเป็นชื่อประเภทหรือไม่คุณก็ไม่รู้วิธีการแยกวิเคราะห์x * y;- การใช้ GLR ช่วยได้อย่างไร
— user541686

2
ประเด็นคือตัวแยกวิเคราะห์ GLR จะสร้างการแยกวิเคราะห์ทั้งสอง (เป็น "แผนผังย่อยที่ไม่ชัดเจน" ใน "ทรี" ที่แยกวิเคราะห์แบบบูรณาการ (DAG จริงๆ) คุณสามารถแก้ไขได้ว่าต้องการเก็บ subrees ใดในภายหลังโดยการนำอื่น ๆ ข้อมูลบริบทตัวแยกวิเคราะห์ C ++ ของเราเกี่ยวข้องกับปัญหานี้อย่างน่าทึ่ง: มันไม่ได้พยายามแก้ปัญหานั่นหมายความว่าเราไม่ต้องยุ่งเกี่ยวกับการสร้างตารางสัญลักษณ์ด้วยการแยกวิเคราะห์ดังนั้นทั้งตัววิเคราะห์และตารางสัญลักษณ์ของเราสำหรับ C ++ มีความสะอาดเป็นรายบุคคลดังนั้นแต่ละอย่างจึงต้องสร้างและบำรุงรักษา
— Ira Baxter

18

ตัวแยกวิเคราะห์ LALR จะรวมสถานะที่คล้ายกันภายในไวยากรณ์ LR เพื่อสร้างตารางสถานะตัวแยกวิเคราะห์ที่มีขนาดเท่ากับไวยากรณ์ SLR ที่เทียบเท่ากันทุกประการซึ่งโดยปกติจะมีลำดับขนาดที่เล็กกว่าตารางแยกวิเคราะห์ LR แท้ อย่างไรก็ตามสำหรับไวยากรณ์ LR ที่ซับซ้อนเกินไปที่จะเป็น LALR สถานะที่ผสานเหล่านี้จะทำให้เกิดความขัดแย้งของตัวแยกวิเคราะห์หรือสร้างตัวแยกวิเคราะห์ที่ไม่รู้จักไวยากรณ์ของ LR ดั้งเดิมอย่างสมบูรณ์

BTW, ฉันพูดถึงบางสิ่งเกี่ยวกับเรื่องนี้ในขั้นตอนวิธีการคิดอัตราดอกเบี้ย MLR (k) ตารางการแยกของฉันที่นี่

ภาคผนวก

คำตอบสั้น ๆ ก็คือตารางการแยกวิเคราะห์ LALR มีขนาดเล็กกว่า แต่เครื่องมือวิเคราะห์คำเหมือนกัน ไวยากรณ์ LALR ที่กำหนดจะสร้างตารางการแยกวิเคราะห์ที่ใหญ่กว่ามากหากสร้างสถานะ LR ทั้งหมดโดยมีสถานะซ้ำซ้อนจำนวนมาก (ใกล้เคียงกัน)

ตาราง LALR มีขนาดเล็กลงเนื่องจากสถานะที่คล้ายกัน (ซ้ำซ้อน) ถูกรวมเข้าด้วยกันทำให้สามารถทิ้งข้อมูลบริบท / ผู้มองหาที่เข้ารหัสสถานะแยกกันได้อย่างมีประสิทธิภาพ ข้อดีคือคุณจะได้ตารางการแยกวิเคราะห์ที่เล็กกว่ามากสำหรับไวยากรณ์เดียวกัน

ข้อเสียเปรียบคือไม่สามารถเข้ารหัสไวยากรณ์ LR ทั้งหมดเป็นตาราง LALR ได้เนื่องจากไวยากรณ์ที่ซับซ้อนมากขึ้นมี lookaheads ที่ซับซ้อนมากขึ้นส่งผลให้มีสองสถานะหรือมากกว่าแทนที่จะเป็นสถานะที่ผสานเพียงสถานะเดียว

ความแตกต่างที่สำคัญคืออัลกอริทึมในการสร้างตาราง LR จะมีข้อมูลเพิ่มเติมระหว่างการเปลี่ยนจากสถานะเป็นสถานะในขณะที่อัลกอริทึม LALR ไม่มี ดังนั้นอัลกอริทึม LALR จึงไม่สามารถบอกได้ว่าควรปล่อยให้สถานะที่ผสานที่กำหนดเป็นสถานะแยกกันตั้งแต่สองสถานะขึ้นไปหรือไม่


3
+1 ฉันชอบไอเดีย Honalee เครื่องแยกวิเคราะห์ G / L (AL) R ของฉันมีเมล็ดของสิ่งนี้อยู่ในนั้น มันผลิตเครื่อง LALR ที่น้อยที่สุดจากนั้นฉันจะแยกสถานะที่มีความขัดแย้ง แต่ฉันไม่เคยผ่าน นี่เป็นวิธีที่ดีในการสร้าง "LR" ขนาดเล็กเช่นชุดตารางแยกวิเคราะห์ แม้ว่า GLR จะไม่ช่วยในแง่ของสิ่งที่สามารถแยกวิเคราะห์ได้ แต่ก็อาจลดจำนวนการแยกวิเคราะห์แบบขนานที่ GLR ต้องพกพาและนั่นจะเป็นประโยชน์
— Ira Baxter

12

อีกคำตอบหนึ่ง (YAA)

อัลกอริทึมการแยกวิเคราะห์สำหรับ SLR (1), LALR (1) และ LR (1) นั้นเหมือนกันตามที่ Ira Baxter กล่าว
อย่างไรก็ตามตารางตัวแยกวิเคราะห์อาจแตกต่างกันเนื่องจากอัลกอริทึมการสร้างตัวแยกวิเคราะห์

ตัวสร้างตัวแยกวิเคราะห์ SLR สร้างเครื่องสถานะ LR (0) และคำนวณการมองไปข้างหน้าจากไวยากรณ์ (ชุด FIRST และ FOLLOW) นี่เป็นแนวทางที่เรียบง่ายและอาจรายงานความขัดแย้งที่ไม่มีอยู่จริงในเครื่องสถานะ LR (0)

ตัวสร้างตัวแยกวิเคราะห์ LALR จะสร้างเครื่องสถานะ LR (0) และคำนวณการมองล่วงหน้าจากเครื่องสถานะ LR (0) (ผ่านการเปลี่ยนขั้ว) นี่เป็นแนวทางที่ถูกต้อง แต่บางครั้งรายงานความขัดแย้งที่จะไม่มีอยู่ในเครื่องสถานะ LR (1)

ตัวสร้างตัวแยกวิเคราะห์ LR Canonical จะคำนวณเครื่องสถานะ LR (1) และการมองล่วงหน้าเป็นส่วนหนึ่งของเครื่องสถานะ LR (1) อยู่แล้ว ตารางตัวแยกวิเคราะห์เหล่านี้อาจมีขนาดใหญ่มาก

ตัวสร้างตัวแยกวิเคราะห์ LR ขั้นต่ำจะคำนวณเครื่องสถานะ LR (1) แต่จะรวมสถานะที่เข้ากันได้ในระหว่างกระบวนการจากนั้นคำนวณการมองไปข้างหน้าจากเครื่องสถานะ LR (1) ขั้นต่ำ ตารางตัวแยกวิเคราะห์เหล่านี้มีขนาดเท่ากันหรือใหญ่กว่าตารางตัวแยกวิเคราะห์ LALR เล็กน้อยซึ่งเป็นทางออกที่ดีที่สุด

LRSTAR 10.0สามารถสร้างตัวแยกวิเคราะห์ LALR (1), LR (1), CLR (1) หรือ LR (*) ใน C ++ สิ่งที่จำเป็นสำหรับไวยากรณ์ของคุณ ดูแผนภาพนี้ซึ่งแสดงความแตกต่างระหว่างตัวแยกวิเคราะห์ LR

[การเปิดเผยข้อมูลทั้งหมด: LRSTAR เป็นผลิตภัณฑ์ของฉัน]


5

สมมติว่าโปรแกรมแยกวิเคราะห์ที่ไม่มีผู้มองหากำลังแยกวิเคราะห์สตริงสำหรับไวยากรณ์ของคุณอย่างมีความสุข

การใช้ตัวอย่างของคุณมันมาเจอกับสตริงdcมันทำอะไร? มันลดเป็นSเพราะdcสตริงที่ถูกต้องที่สร้างโดยไวยากรณ์นี้หรือไม่? หรือบางทีเราพยายามแยกวิเคราะห์bdcเพราะนั่นเป็นสตริงที่ยอมรับได้?

ในฐานะที่เป็นมนุษย์เรารู้ว่าคำตอบนั้นง่ายเพียงแค่ต้องจำไว้ว่าเราเพิ่งแยกวิเคราะห์bหรือไม่ แต่คอมพิวเตอร์โง่ :)

เนื่องจากตัวแยกวิเคราะห์ SLR (1) มีอำนาจเพิ่มเติมเหนือ LR (0) ในการค้นหาส่วนหัวเราจึงทราบว่าผู้มองหาจำนวนเท่าใดก็ไม่สามารถบอกเราได้ว่าต้องทำอย่างไรในกรณีนี้ แต่เราต้องมองย้อนกลับไปในอดีตของเรา ดังนั้นตัวแยกวิเคราะห์ LR ที่เป็นที่ยอมรับจึงมาช่วย มันจำบริบทในอดีต

วิธีที่จำบริบทนี้ได้ก็คือการสร้างวินัยให้กับตัวเองว่าเมื่อใดก็ตามที่พบกับ a bมันจะเริ่มเดินบนเส้นทางสู่การอ่านbdcซึ่งเป็นความเป็นไปได้อย่างหนึ่ง ดังนั้นเมื่อมันเห็นdมันก็รู้ว่ามันกำลังเดินไป ดังนั้นตัวแยกวิเคราะห์ CLR (1) สามารถทำสิ่งที่ตัวแยกวิเคราะห์ SLR (1) ทำไม่ได้!

แต่ตอนนี้เนื่องจากเราต้องกำหนดเส้นทางจำนวนมากสถานะของเครื่องจึงมีขนาดใหญ่มาก!

ดังนั้นเราจึงรวมเส้นทางการมองเดียวกัน แต่ตามที่คาดไว้มันอาจก่อให้เกิดปัญหาความสับสน อย่างไรก็ตามเรายินดีที่จะเสี่ยงโดยเสียค่าใช้จ่ายในการลดขนาด

นี่คือโปรแกรมแยกวิเคราะห์ LALR (1) ของคุณ


ตอนนี้วิธีการทำอัลกอริทึม

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


สิ่งนี้ไม่ถูกต้อง

4

ความแตกต่างพื้นฐานระหว่างตาราง parser ที่สร้างด้วย SLR กับ LR คือการดำเนินการลดจะขึ้นอยู่กับการติดตามที่ตั้งค่าไว้สำหรับตาราง SLR สิ่งนี้สามารถ จำกัด มากเกินไปจนทำให้เกิดข้อขัดแย้งลดการเปลี่ยนแปลงในที่สุด

ในทางกลับกันตัวแยกวิเคราะห์ LR ฐานจะลดการตัดสินใจเฉพาะในชุดของเทอร์มินัลซึ่งสามารถติดตามการลดลงของเทอร์มินัลได้ ชุดของเทอร์มินัลนี้มักเป็นชุดย่อยที่เหมาะสมของชุดการติดตามของ non-terminal ดังกล่าวดังนั้นจึงมีโอกาสน้อยกว่าที่จะขัดแย้งกับการทำงานของกะ

ตัวแยกวิเคราะห์ LR มีประสิทธิภาพมากกว่าด้วยเหตุนี้ อย่างไรก็ตามตารางแยกวิเคราะห์ LR อาจมีขนาดใหญ่มาก

ตัวแยกวิเคราะห์ LALR เริ่มต้นด้วยแนวคิดในการสร้างตารางแยกวิเคราะห์ LR แต่รวมสถานะที่สร้างขึ้นในลักษณะที่ส่งผลให้มีขนาดตารางน้อยลงอย่างมาก ข้อเสียคือโอกาสเล็กน้อยของความขัดแย้งจะถูกนำมาใช้สำหรับไวยากรณ์บางอย่างที่ตาราง LR อาจหลีกเลี่ยงได้

ตัวแยกวิเคราะห์ LALR มีประสิทธิภาพน้อยกว่าตัวแยกวิเคราะห์ LR เล็กน้อย แต่ยังมีประสิทธิภาพมากกว่าตัวแยกวิเคราะห์ SLR YACC และเครื่องแยกวิเคราะห์อื่น ๆ มักจะใช้ LALR ด้วยเหตุผลนี้

ป.ล. สำหรับความกะทัดรัด SLR, LALR และ LR ด้านบนหมายถึง SLR (1), LALR (1) และ LR (1) จริงๆดังนั้นโทเค็นหนึ่งตัวจึงมีความหมายโดยนัย


4

โปรแกรมแยกวิเคราะห์ SLR จะรับรู้ไวยากรณ์ชุดย่อยที่เหมาะสมซึ่งสามารถจดจำได้โดยตัววิเคราะห์ LALR (1) ซึ่งจะจดจำชุดย่อยที่เหมาะสมของไวยากรณ์ที่ตัววิเคราะห์ LR (1) จดจำได้

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

ตัวอย่างDragon Bookของไวยากรณ์ LALR (1) ที่ไม่ใช่ SLR คือ:

S → L = R | R
L → * R | id
R → L

นี่คือหนึ่งในสถานะของไวยากรณ์นี้:

S → L•= R
R → L•

•บ่งชี้ตำแหน่งของตัวแยกวิเคราะห์ในแต่ละโปรดักชั่นที่เป็นไปได้ มันไม่รู้ว่าจริงๆแล้วมันอยู่ในโปรดักชั่นไหนจนกว่าจะถึงตอนจบและพยายามลด

ที่นี่ตัวแยกวิเคราะห์สามารถเลื่อน=หรือลดR → Lได้

ตัวแยกวิเคราะห์ SLR (aka LR (0)) จะกำหนดว่าสามารถลดได้หรือไม่โดยการตรวจสอบว่าสัญลักษณ์อินพุตถัดไปอยู่ในชุดต่อไปนี้ของR(กล่าวคือชุดของเทอร์มินัลทั้งหมดในไวยากรณ์ที่สามารถติดตามได้R) เนื่องจาก=อยู่ในชุดนี้เช่นกันตัวแยกวิเคราะห์ SLR พบข้อขัดแย้งลดการเปลี่ยนแปลง

อย่างไรก็ตามตัวแยกวิเคราะห์ LALR (1) จะใช้ชุดของเทอร์มินัลทั้งหมดที่สามารถทำตามการผลิตเฉพาะของ R ซึ่งเป็นเพียง$(กล่าวคือจุดสิ้นสุดของอินพุต) ดังนั้นจึงไม่มีความขัดแย้ง

ตามที่ผู้แสดงความคิดเห็นก่อนหน้านี้ได้ระบุไว้ตัววิเคราะห์ LALR (1) มีจำนวนสถานะเท่ากับตัวแยกวิเคราะห์ SLR อัลกอริธึมการแพร่กระจายของ Lookahead ใช้เพื่อจัดการผู้มองหาไปยังการสร้างสถานะ SLR จากสถานะ LR (1) ที่สอดคล้องกัน ตัวแยกวิเคราะห์ LALR (1) ที่เป็นผลลัพธ์สามารถแนะนำความขัดแย้งแบบลด - ลดที่ไม่มีอยู่ในตัวแยกวิเคราะห์ LR (1) แต่ไม่สามารถทำให้เกิดข้อขัดแย้งในการลดการเปลี่ยนแปลงได้

ในตัวอย่างของคุณสถานะ LALR (1) ต่อไปนี้ทำให้เกิดข้อขัดแย้งในการลดการเปลี่ยนแปลงในการใช้งาน SLR:

S → b d•a / $
A → d• / c

สัญลักษณ์หลัง/คือชุดติดตามสำหรับการผลิตแต่ละรายการในตัวแยกวิเคราะห์ LALR (1) ใน SLR ติดตาม ( A)รวมถึงaซึ่งสามารถเลื่อนได้ด้วย


2

นอกเหนือจากคำตอบข้างต้นแผนภาพนี้ยังแสดงให้เห็นว่าตัวแยกวิเคราะห์ต่างๆเกี่ยวข้องกันอย่างไร:

ป้อนคำอธิบายภาพที่นี่


-2

คำตอบง่ายๆอย่างหนึ่งคือไวยากรณ์ LR (1) ทั้งหมดเป็นไวยากรณ์ LALR (1) เมื่อเทียบกับ LALR (1) แล้ว LR (1) มีสถานะมากกว่าในเครื่อง จำกัด สถานะที่เกี่ยวข้อง (มากกว่าสองเท่า) และนั่นคือเหตุผลหลักที่ไวยากรณ์ LALR (1) ต้องการโค้ดมากขึ้นเพื่อตรวจจับข้อผิดพลาดทางไวยากรณ์มากกว่าไวยากรณ์ LR (1) และอีกสิ่งหนึ่งที่สำคัญที่ควรทราบเกี่ยวกับไวยากรณ์ทั้งสองนี้ก็คือในไวยากรณ์ LR (1) เราอาจลด / ลดความขัดแย้งได้น้อยลง แต่ใน LALR (1) มีความเป็นไปได้มากกว่าที่จะลด / ลดความขัดแย้ง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.