โปรแกรมแยกวิเคราะห์ที่ทรงพลังที่สุดคืออะไร?


28

ในฐานะโปรเจ็กต์ด้านข้างฉันกำลังเขียนภาษาโดยใช้ Python ฉันเริ่มต้นด้วยการใช้ดิ้น / วัวกระทิงที่เรียกว่า Ply แต่มากับขอบในอำนาจของสิ่งที่ฉันสามารถแสดงด้วยรูปแบบของไวยากรณ์นั้นและฉันไม่สนใจที่จะแฮ็คภาษาของฉันเพราะความต้านทานไม่ตรงกัน เครื่องมือ ดังนั้นฉันไม่รังเกียจที่จะเขียนของตัวเอง

ดังนั้นโปรแกรมแยกวิเคราะห์ที่ทรงพลังที่สุดคืออะไร? ยินดีต้อนรับการอ้างอิงถึงเอกสาร (รวมถึงบทความเบื้องต้นเพิ่มเติม)

(ฉันรู้ว่า 'พลัง' ไม่ได้นิยามไว้อย่างชัดเจน แต่ลองมาดูกันหน่อยสิและดูว่าคำตอบนั้นไปที่ใด)


1
Downvoted: ไม่ใช่ระดับการวิจัย
Warren Schudy

3
@Warren: ฉันตรวจสอบคำถามที่พบบ่อยก่อนถาม - ที่ดูเหมือนจะไม่เป็นข้อกำหนด
Paul Biggar

1
จริงๆแล้วมีคำถามที่พบบ่อยสองข้อหนึ่งข้อสำหรับไซต์ทั่วไปและอีกคำถามหนึ่งสำหรับ CStheory CStheory หนึ่งบ่งชี้ว่าคำถามที่สามารถตอบโดยการอ่านวิกิพีเดียเป็นนอกหัวข้อ; โปรดดู "คำถามประเภทใดบ้างที่ธรรมดาเกินไป" ในmeta.cstheory.stackexchange.com/questions/225/
Warren Schudy

1
@Warren: นั่นเป็นคำถามที่พบบ่อยฉันอ่าน ฉันได้อ่านวิกิพีเดีย แต่ฉันรู้สึกว่านี่ต้องมีความเข้าใจที่แท้จริง
Paul Biggar

1
คุณหมายถึง parsers ในการผลิตหรือคนในทางทฤษฎีคือคนที่ครอบคลุมไวยากรณ์ประเภทอื่นที่ไม่ใช่ CFG?
Raphael

คำตอบ:


33

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

มันบอกว่าที่นี่ที่เร่ใช้parser LALR นี่คือตัวแยกวิเคราะห์ LRที่ตารางการค้นหาย่อตัวอาจแนะนำการแยกวิเคราะห์ความขัดแย้งลดความหมายของไวยากรณ์ LR (เช่นไวยากรณ์อิสระบริบทที่ตัวแยกวิเคราะห์ LR สามารถแยกวิเคราะห์) หากคุณต้องการทราบเกี่ยวกับข้อ จำกัด ของสาขานี้โดยเฉพาะของ parsers และของ parsers อื่น ๆ ภาพรวมของทุกชนิดของการแยกวิเคราะห์เทคนิค (LL, LR และอื่น ๆ ) จะได้รับที่นี่

ในการตอบคำถามของคุณ: มีอัลกอริทึมการแยกวิเคราะห์ที่มีความสามารถในการแยกวิเคราะห์ภาษาที่ไม่มีบริบทใด ๆ แม้ว่าภาษานั้นจะคลุมเครือ (เช่นมีวิธีการตีความอินพุตมากกว่าหนึ่งวิธี):

อัลกอรึทึมแรกนั้นคืออัลกอริธึมCYKซึ่งน่าเสียดายที่มีเวลาทำงานของโดยที่คือความยาวของสตริงอินพุตและn | G |O(n3|G|)n|G|คือขนาดของไวยากรณ์และดังนั้นจึงเป็นไปไม่ได้สำหรับการแยกภาษา

O(n3)O(n2)

ที่นี่คุณสามารถค้นหาบทความเกี่ยวกับการใช้งานจริงของอัลกอริทึม Earley (การปรับตัว) พวกเขาสรุปว่า: "เมื่อพิจารณาถึงความเป็นเอกเทศของ Earley เมื่อเทียบกับ LALR (1) การแยกวิเคราะห์ ((ซึ่งประมาณคร่าวๆว่า PLY ทำอะไร)) และเมื่อพิจารณาว่าแม้แต่ PEP (การใช้อัลกอริธึมของ Earley)) ผู้ใช้นี่เป็นผลลัพธ์ที่ยอดเยี่ยม "

ประเภทสุดท้ายของการแยกวิเคราะห์เป็นตัวแยกวิเคราะห์จี นี่เป็นเวอร์ชันทั่วไปของการแยกวิเคราะห์ LR ซึ่งสามารถแยกวิเคราะห์ภาษาที่ไม่มีบริบท

การดำเนินผู้ใหญ่ของจีเป็นASF + ไอ้เวร กระทิงยังสามารถสร้างตัวแยกวิเคราะห์ GLR แม้ว่าการใช้งานจะแตกต่างจากอัลกอริทึม 'มาตรฐาน' GLR เล็กน้อย Elkhound ขั้นตอนวิธีการเป็นขั้นตอนวิธีไฮบริดจี / LALR มันใช้ LALR เมื่อเป็นไปได้และ GLR เมื่อจำเป็นเพื่อที่จะได้อย่างรวดเร็วและมีความสามารถในการแยกไวยากรณ์ใด ๆ

นอกเหนือจากไวยากรณ์ฟรีตามบริบทแล้วยังมีไวยากรณ์ที่มีความอ่อนไหวตามบริบทแต่โดยทั่วไปแล้วยากที่จะแยกวิเคราะห์และไม่เพิ่มความหมายมาก: คุณสามารถทำอะไรกับมันได้มากขึ้น แต่สำหรับแอปพลิเคชันส่วนใหญ่การใช้งานพิเศษไม่เกี่ยวข้อง ภาษาธรรมชาติ

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

สุดท้ายนี้การใช้ parser-generator ของคุณเองไม่ใช่เรื่องเล็กน้อยโดยเฉพาะอย่างยิ่งที่จะทำให้มันเร็ว ฉันเพิ่งเสร็จสิ้นการสร้าง flex ของตัวเอง (ตัวกำเนิด lexer) และในขณะนี้ดูเหมือนว่าการออกกำลังกายในปัญหาอัลกอริธึมที่ค่อนข้างง่าย แต่มันค่อนข้างซับซ้อนที่จะทำให้ถูกต้องโดยเฉพาะอย่างยิ่งเมื่อฉันพยายามสนับสนุน Unicode พิจารณาใช้การใช้งานที่มีอยู่แล้วแทนที่จะเขียนเอง


1
คำตอบที่ยอดเยี่ยม !! มีความคิดเห็นเกี่ยวกับวิธีที่ PEGs เหมาะสมอย่างไร
Paul Biggar

2
PEG นั้นแตกต่างจาก CFGs: มี CFG ที่ไม่ใช่ PEG และในทางกลับกัน ผมหมายถึงคุณที่นี่: stackoverflow.com/questions/1857022/...
Alex สิบ Brink

นอกจากนี้ยังอาจจะเป็นที่น่าสนใจ: blogs.ethz.ch/copton/2009/07/08/parsing-expression-grammars
Alex สิบ Brink

1
ที่จริงแล้วตัวแยกวิเคราะห์ทั่วไปส่วนใหญ่ (yacc, Antlr, bison) อนุญาตแนวคิดที่ไม่ใช่ CF โดยเพรดิเคตหรือโค้ดโดยพลการที่ตรวจสอบกฎหนึ่งข้อที่สามารถใช้ได้ ตัดสินใจนำหน้า สิ่งนี้สามารถใช้ในการใช้ความหมายแบบสแตติกส่วนใหญ่เนื่องจากไวยากรณ์พื้นฐานยังคงอยู่ในบริบทสำคัญฟรี
Raphael

1
ภาษาแบบเรียกซ้ำนั้นเป็นภาษาที่สามารถตัดสินใจได้อย่างแม่นยำด้วยทัวริง Machines ภาษาที่มีความอ่อนไหวตามบริบทใด ๆ ก็มีการเรียกซ้ำด้วยเช่นกัน แต่เนื่องจากภาษาที่มีความอ่อนไหวทางบริบทนั้นสามารถตัดสินใจได้ในเวลาแบบเอ็กซ์โพเนนเชียล ไวยากรณ์ไม่ จำกัด มีประสิทธิภาพยิ่งขึ้น: ปัญหาการหยุดชะงักสามารถอธิบายได้ด้วยไวยากรณ์ที่ไม่ จำกัด แต่ไม่ใช่ภาษาแบบเรียกซ้ำ
Alex ten Brink

15

กระดาษที่ ICFP 2010 ในปีนี้Total Parser Combinatorsอธิบายถึงไลบรารี combinator parser ที่สิ้นสุดและพิสูจน์ได้ว่าใน "ห้องสมุด combinator parser นั้นแสดงออกได้ดีที่สุด" โดยที่ parser รับประกันว่าจะยุติ น่าเสียดายที่ฉันไม่จำคำอธิบายที่ผู้เขียนให้กับสิ่งที่ "มีความหมายมากที่สุด" แต่ดูเหมือนว่าจะเกี่ยวข้องกับคำถามของคุณเกี่ยวกับ "พลัง"


1
ฉันมีรถยนต์ที่ไม่ก่อให้เกิดมลพิษจริง ๆ แล้วมันก็ไม่ขยับอย่างใดอย่างหนึ่ง ... ดังนั้นคำถามคือ: ห้องสมุดนี้แยกวิเคราะห์ภาษาอะไร ไม่ได้หมายความว่างานนี้ไม่น่าสนใจแน่นอน
babou

2

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

ในการประมวลผลภาษาธรรมชาติรสนิยมจะแตกต่างกันเช่นการจัดการกับความกำกวม (เช่น: ความกำกวมโดยธรรมชาติ) และการเรียงลำดับคำฟรีมีบทบาทสำคัญมาก ต่อไปนี้เป็นคำหลักที่มีความอ่อนไหวต่อบริบทของภาษาและการรีสตาร์ทอัตโนมัติอาจช่วยให้คุณเริ่มอ่านได้


1
เมื่อพิจารณาถึงวิธีการถามคำถามและการร้องเรียนว่า CF มีข้อ จำกัด มากเกินไปคำตอบของคุณดีที่สุดอย่างชัดเจน ดังนั้นมันจึงไป ...
babou

0

เครื่องมือสร้าง Parser:

ANTLRดีมาก หรือคุณสามารถดูJavaCC


ฉันไม่ใช่นักวิทยาศาสตร์คอมพิวเตอร์ (แม้ปริญญาของฉันจะพูดถึง;) ดังนั้นคำพูดของฉันอาจมีน้ำหนักเบา ฉันเห็นด้วยกับ Sazzad - ANTLR เป็นเครื่องมือที่ทรงพลังมาก มันสมบูรณ์มากและฉันยังไม่พบปัญหาใด ๆ กับตัวแยกวิเคราะห์ (LL (k) หากฉันจำได้ถูกต้อง) ในทางตรงกันข้ามฉันยังไม่ได้ใช้คอมไพเลอร์สำหรับไวยากรณ์ที่ค่อนข้างซับซ้อน ...
Jörgen Sigvardsson

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