ข้อดีของ Antlr (เทียบกับ lex / yacc / bison) [ปิด]


143

ฉันเคยใช้ lex และ yacc (มักจะเป็นวัวกระทิง) ในอดีตสำหรับโครงการต่าง ๆ โดยทั่วไปแล้วนักแปล (เช่นกลุ่มย่อยของ EDIF ที่สตรีมไปยังแอป EDA) นอกจากนี้ฉันต้องสนับสนุนรหัสตามไวยากรณ์ lex / yacc ย้อนหลังไปหลายสิบปี ดังนั้นฉันรู้วิธีของฉันรอบ ๆ เครื่องมือแม้ว่าฉันไม่มีผู้เชี่ยวชาญ

ฉันเคยเห็นความคิดเห็นเชิงบวกเกี่ยวกับ Antlr ในเวทีต่าง ๆ ในอดีตและฉันอยากรู้ว่าสิ่งที่ฉันอาจจะหายไป ดังนั้นหากคุณใช้ทั้งคู่โปรดบอกฉันว่ามีอะไรที่ดีกว่าหรือสูงกว่าใน Antlr ข้อ จำกัด ในปัจจุบันของฉันคือฉันทำงานในร้าน C ++ และผลิตภัณฑ์ใด ๆ ที่เราจัดส่งจะไม่รวม Java ดังนั้นตัวแยกวิเคราะห์ผลลัพธ์จะต้องปฏิบัติตามกฎนั้น

คำตอบ:


145

อัปเดต / เตือน: คำตอบนี้อาจล้าสมัย!


ความแตกต่างที่สำคัญอย่างหนึ่งคือ ANTLR สร้างตัวแยกวิเคราะห์ LL (*) ในขณะที่ YACC และ Bison ต่างก็สร้างตัวแยกวิเคราะห์ที่เป็น LALR นี่คือความแตกต่างที่สำคัญสำหรับแอปพลิเคชั่นจำนวนหนึ่งตัวดำเนินการที่ชัดเจนที่สุด:

expr ::= expr '+' expr
       | expr '-' expr
       | '(' expr ')'
       | NUM ;

ANTLR ไม่สามารถจัดการไวยากรณ์นี้ได้ตามที่ต้องการ ในการใช้ ANTLR (หรือตัวแยกวิเคราะห์ LL อื่น ๆ ) คุณจะต้องแปลงไวยากรณ์นี้เป็นสิ่งที่ไม่ใช่แบบเรียกซ้ำ อย่างไรก็ตามกระทิงไม่มีปัญหากับไวยากรณ์ของแบบฟอร์มนี้ คุณจะต้องประกาศ '+' และ '-' ในฐานะผู้ประกอบการด้านซ้าย แต่ไม่จำเป็นสำหรับการเรียกซ้ำทางซ้ายอย่างเคร่งครัด ตัวอย่างที่ดีกว่าอาจจะส่งไป:

expr ::= expr '.' ID '(' actuals ')' ;

actuals ::= actuals ',' expr | expr ;

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

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


2
ดังนั้นข้อได้เปรียบที่ยิ่งใหญ่และมีความโดดเด่นในการรับรู้ของคุณก็คือ Antlr จะสร้างข้อผิดพลาดน้อยลงเช่น sr และ rr ในระหว่างการก่อสร้าง ฉันหวังว่าฉันจะให้มันลอง แต่อาจจะจบลงติดกับสิ่งที่ฉันรู้ ...
ดอนเวก

1
ใช่ว่ามันสวยมาก :-) ฉันไม่เห็นด้วยกับความเห็นยอดนิยมที่ ANTLR นั้นง่ายกว่า Bison ดังนั้นฉันคิดว่าฉันจะเห็นด้วยกับการตัดสินใจของคุณ
Daniel Spiewak

2
กฎ 'actuals' จำเป็นต้องมีกฎข้อที่สองเพื่อระบุว่า 'expr' แบบง่ายเป็นของจริงหรือไม่? มิฉะนั้นคำอธิบายที่ดี
Jonathan Leffler

8
ความคิดเห็นอื่นที่ฉันพบเมื่อเร็ว ๆ นี้แม้ว่าทศวรรษเก่าทำให้การสังเกตที่เหมาะสมของการส่งออก : compilers.iecc.com/comparch/article/98-11-040 : "ANTLR / PCCTS เป็น LL ซึ่งทำให้การเขียนไวยากรณ์ยากขึ้น แต่ รหัสที่สร้างขึ้นสามารถอ่านได้ Yacc กำลัง LALR (แน่นอนคุณรู้ว่า) ทำให้การเขียนไวยากรณ์ง่ายขึ้น แต่รหัสที่สร้างขึ้นอาจเป็นอักษรอียิปต์โบราณ "
Don Wakefield

72
ฉันเพิ่งเสร็จสิ้นการสนับสนุนการเรียกซ้ำทางซ้ายทันทีสำหรับ ANTLR รุ่นถัดไป v3.4 จัดการกฎการแสดงออก LR และสิ่งที่คล้ายกันเช่นกฎ C declarator :)
Terence Parr

117

ความแตกต่างที่สำคัญที่สุดระหว่าง YACC / Bison และ ANTLR คือประเภทของไวยากรณ์ที่เครื่องมือเหล่านี้สามารถดำเนินการได้ YACC / Bison จัดการ LALR grammars, ANTLR จัดการ LL grammars

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

เท่าที่ความได้เปรียบมีหลายแง่มุมที่ LALR grammars มีข้อดีเหนือ LL grammars และมีแง่มุมอื่น ๆ ที่ LL grammars มีข้อดีเหนือ LALR grammars

YACC / Bison สร้างตัวแยกวิเคราะห์แบบอิงตารางซึ่งหมายความว่า "ตรรกะการประมวลผล" มีอยู่ในข้อมูลโปรแกรมตัวแยกวิเคราะห์ไม่มากในรหัสตัวแยกวิเคราะห์ ผลตอบแทนก็คือแม้กระทั่งตัวแยกวิเคราะห์สำหรับภาษาที่ซับซ้อนมากมีรอยเท้ารหัสที่ค่อนข้างเล็ก สิ่งนี้สำคัญกว่าในทศวรรษ 1960 และ 1970 เมื่อฮาร์ดแวร์มีข้อ จำกัด มาก เครื่องกำเนิดไฟฟ้าตัวแยกวิเคราะห์ตารางขับเคลื่อนกลับไปยังยุคนี้และรอยขนาดเล็กของรหัสเป็นข้อกำหนดหลักในตอนนั้น

ANTLR สร้างตัวแยกวิเคราะห์สืบเชื้อสายซ้ำซึ่งหมายความว่า "ตรรกะการประมวลผล" ที่มีอยู่ในรหัส parser เป็นกฎการผลิตของไวยากรณ์แต่ละครั้งจะถูกแสดงโดยฟังก์ชั่นในรหัสของตัวแยกวิเคราะห์ ผลตอบแทนก็คือการทำความเข้าใจกับสิ่งที่โปรแกรมวิเคราะห์คำทำได้ง่ายขึ้นโดยการอ่านโค้ด นอกจากนี้ตัวแยกวิเคราะห์แบบสืบเชื้อสายโดยทั่วไปจะเร็วกว่าตัวแยกตาราง อย่างไรก็ตามสำหรับภาษาที่ซับซ้อนมากรหัสรอยจะใหญ่ขึ้น นี่เป็นปัญหาในปี 1960 และ 1970 ย้อนกลับไปมีการใช้งานภาษาที่ค่อนข้างเล็กเช่นปาสกาลด้วยวิธีนี้เนื่องจากข้อ จำกัด ด้านฮาร์ดแวร์

ตัวแยกวิเคราะห์ที่สร้างขึ้น ANTLR โดยทั่วไปจะอยู่ในบริเวณใกล้เคียงกับรหัสบรรทัด 10,000 รายการและอื่น ๆ ตัวแยกวิเคราะห์แบบสืบซ้ำแบบเขียนด้วยลายมือมักอยู่ใน ballpark เดียวกัน คอมไพเลอร์ Oberon ของ Wirth อาจเป็นคอมแพคที่สุดที่มีโค้ดประมาณ 4,000 บรรทัดรวมถึงการสร้างโค้ด แต่ Oberon เป็นภาษาที่กะทัดรัดมากโดยมีกฎการผลิตเพียง 40 ข้อเท่านั้น

ดังที่ใครบางคนชี้ให้เห็นแล้วข้อดีที่ยิ่งใหญ่สำหรับ ANTLR คือเครื่องมือ IDE กราฟิกเรียกว่า ANTLRworks เป็นห้องปฏิบัติการออกแบบไวยากรณ์และภาษาที่สมบูรณ์ มันแสดงให้เห็นกฎไวยากรณ์ของคุณในขณะที่คุณพิมพ์พวกเขาและหากพบความขัดแย้งใด ๆ มันจะแสดงให้คุณเห็นชัดเจนว่าความขัดแย้งคืออะไรและสิ่งที่ทำให้มัน มันยังสามารถปรับโครงสร้างและแก้ไขข้อขัดแย้งโดยอัตโนมัติเช่นการเรียกซ้ำทางซ้าย เมื่อคุณมีไวยากรณ์ที่ปราศจากความขัดแย้งคุณสามารถให้ ANTLRworks แยกวิเคราะห์ไฟล์อินพุตของภาษาของคุณและสร้างแผนผังการแยกวิเคราะห์และ AST ให้คุณและแสดงแผนผังแบบกราฟิกใน IDE นี่เป็นข้อได้เปรียบที่ยิ่งใหญ่มากเพราะช่วยให้คุณประหยัดเวลาทำงานหลายชั่วโมง: คุณจะพบข้อผิดพลาดทางแนวคิดในการออกแบบภาษาของคุณก่อนที่จะเริ่มการเข้ารหัส! ฉันไม่พบเครื่องมือดังกล่าวสำหรับไวยากรณ์ LALR ดูเหมือนว่าไม่มีเครื่องมือดังกล่าว

แม้แต่คนที่ไม่ต้องการสร้างเครื่องมือแยกวิเคราะห์ แต่เขียนรหัสด้วยตนเอง ANTLRworks เป็นเครื่องมือที่ยอดเยี่ยมสำหรับการออกแบบ / การสร้างต้นแบบภาษา อาจเป็นเครื่องมือที่ดีที่สุดเท่าที่มีอยู่ น่าเสียดายที่มันไม่ได้ช่วยอะไรคุณหากคุณต้องการสร้างตัวแยกวิเคราะห์ LALR การเปลี่ยนจาก LALR เป็น LL เป็นการใช้ประโยชน์จาก ANTLRworks อาจคุ้มค่า แต่สำหรับบางคนการเปลี่ยนประเภทไวยากรณ์อาจเป็นประสบการณ์ที่เจ็บปวดมาก ในคำอื่น ๆ : YMMV


4
ชอบมันเพราะมันอธิบายประวัติศาสตร์เบื้องหลังกลไกต่าง ๆ ที่ทำให้ผู้คนเข้าใจอย่าง
ผิดเพี้ยน

35

ข้อดีสองประการสำหรับ ANTLR:

  • สามารถแยกวิเคราะห์ parsers ในภาษาต่างๆ - Java ไม่จำเป็นสำหรับการเรียกใช้ parser ที่สร้าง
  • Awesome GUI ช่วยให้การดีบักไวยากรณ์ง่ายขึ้น (เช่นคุณสามารถเห็น AST ที่ถูกต้องใน GUI ไม่จำเป็นต้องใช้เครื่องมือเพิ่มเติม)
  • รหัสที่สร้างขึ้นนั้นสามารถอ่านได้โดยมนุษย์ (เป็นหนึ่งในเป้าหมายของ ANTLR) และความจริงที่ว่ามันสร้างตัวแยกวิเคราะห์ LL จะช่วยในเรื่องนี้อย่างแน่นอน
  • นิยามของเทอร์มินัลนั้นไม่มีบริบทเช่นกัน (เมื่อเทียบกับ regex ใน (f) lex) - ดังนั้นการอนุญาตเช่นคำจำกัดความของเทอร์มินัลที่มีวงเล็บปิดอย่างถูกต้อง

ของฉัน. 02 $


9

ข้อดีอีกอย่างของ ANTRL ก็คือคุณสามารถใช้ANTLRWORKSได้ แต่ฉันไม่สามารถพูดได้ว่านี่เป็นข้อได้เปรียบที่เข้มงวดเนื่องจากอาจมีเครื่องมือที่คล้ายกันสำหรับเครื่องกำเนิดไฟฟ้าอื่นเช่นกัน


9
  • Bison and Flex ส่งผลให้หน่วยความจำเล็กลง แต่คุณไม่มี IDE กราฟิก
  • antlr ใช้หน่วยความจำเพิ่มขึ้น แต่คุณมี antlrworks ซึ่งเป็น IDE กราฟิก

การใช้หน่วยความจำ Bison / Flex โดยทั่วไปแล้วจะเป็น mbyte หรือมากกว่านั้น ตรงกันข้ามกับ antlr โดยสมมติว่ามันใช้หน่วยความจำ 512 ไบต์สำหรับทุกโทเค็นในไฟล์ที่คุณต้องการแยกวิเคราะห์ โทเค็น 4 ล้านรายการและคุณมีหน่วยความจำเสมือนในระบบ 32 บิต

หากไฟล์ที่คุณต้องการแยกมีขนาดใหญ่ antlr อาจมีหน่วยความจำไม่เพียงพอดังนั้นหากคุณต้องการแยกวิเคราะห์ไฟล์กำหนดค่ามันจะเป็นทางออกที่ทำงานได้ มิฉะนั้นถ้าคุณต้องการแยกไฟล์ด้วยข้อมูลจำนวนมากลองใช้ Bison


7
ฉันอยากรู้. คุณสามารถชี้ไปที่เอกสารอธิบายการใช้หน่วยความจำ 512 ไบต์ต่อโทเค็นหรือไม่ ฉันจำไม่ได้ว่าได้เห็นการสนทนานั้น ตัวเลือกของฉันของคำ Google ไม่ให้ฉันความพึงพอใจของทั้ง ...
ดอนเวก

2
คุณกำลังพูดถึงหน่วยความจำรอยเท้าของตัวแยกวิเคราะห์ในขณะที่สร้างตัวแยกวิเคราะห์หรือคุณกำลังพูดถึงรอยเท้าหน่วยความจำของตัวแยกวิเคราะห์ที่สร้างขึ้นในขณะที่แยกวิเคราะห์สำหรับภาษาต้นฉบับ? โทเค็นนับล้านในไวยากรณ์จะเสียสติอย่างแน่นอน คุณควรถูกขังไว้ในสถาบันจิตถ้าคุณพยายามขายความคิดเช่นนั้นอย่างจริงจัง สำหรับอินพุตไฟล์สำหรับ parser เองอาจมีกรณีที่สิ่งเหล่านี้อาจมีโทเค็นจำนวนมาก แต่ภาษาส่วนใหญ่เป็นมอดูลาร์คุณไม่ต้องแยกวิเคราะห์อินพุตทั้งหมดในไฟล์เดียวโมดูลแต่ละตัวมีขนาดเล็กลง
trijezdci
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.