Переваги Antlr (порівняно з lex / yacc / bison) [закрито]


143

У минулому я використовував lex та yacc (частіше зубрів) для різних проектів, як правило, перекладачів (таких як підмножина EDIF, що передається в додаток EDA). Крім того, мені довелося підтримувати код, заснований на граматиках lex / yacc, що датуються десятиліттями. Тож я знаю свій шлях навколо інструментів, хоча я не фахівець.

У минулому я бачив позитивні коментарі про 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правила, і правила є рекурсивними. Це створює набагато ефективніший AST, коли настає час для генерації коду, оскільки це дозволяє уникнути необхідності в декількох регістрах та непотрібному розливі (дерево, що спирається ліворуч, може бути згорнуте, тоді як дерево, що спирається на право, не може).

Що стосується особистого смаку, я вважаю, що граматики LALR набагато простіше побудувати та налагодити. Мінусом є те, що вам доведеться стикатися з дещо критичними помилками, такими як "зменшити-зменшити" та "бояться" зменшити-зменшити. Це помилки, які Bison виявляє під час генерації аналізатора, тому це не впливає на досвід кінцевого користувача, але може зробити процес розробки трохи цікавішим. Звичайно, ANTLR вважається простішим у використанні, ніж YACC / Bison саме з цієї причини.


2
Отже, великою, можливо, єдиною перевагою Antlr у вашому сприйнятті є те, що він створює менше помилок, таких як sr та rr під час фази будівництва? Я сподіваюся, що спробую, але, мабуть, закінчуватимуться того, що я знаю ...
Дон Уейкфілд

1
Так, це майже все. :-) Я не погоджуюся ні з поширеною думкою, що ANTLR легше, ніж Бізон, тому я думаю, що я погодився б з вашим рішенням.
Даніель Шпієк

2
Чи потрібне правило "фактичне" друге правило, яке вказує на те, що простий "expr" є фактичним? Інакше приємне пояснення.
Джонатан Леффлер

8
Ще один коментар, який я знайшов нещодавно, хоч і десятиліття, робить розумне спостереження за результатами : compilers.iecc.com/comparch/article/98-11-040 : "ANTLR / PCCTS - це LL, що ускладнює написання граматики складнішим, але згенерований код читається. Як, що є ЛАЛР (це, звичайно, ви знаєте), полегшує написання граматики, але згенерований код може бути ієрогліфічним ".
Дон Уейкфілд

72
Я тільки що завершив негайну підтримку лівої рекурсії для наступного випуску v3.4 ANTLR. Обробляє правила вираження LR та подібні речі, такі як правила декларатора C. :)
Теренс Парр

117

Найбільш істотна відмінність YACC / Bison від ANTLR - це тип граматик, які ці інструменти можуть обробляти. YACC / Bison ручка граматики LALR, ANTLR - граматики LL.

Часто людям, які довгий час працювали з граматиками LALR, буде здаватися, що працювати з граматиками LL буде складніше і навпаки. Це не означає, що граматики чи інструменти по суті важче працювати. Який інструмент вам легше використовувати, здебільшого зводиться до ознайомлення з типом граматики.

Що стосується переваг, то є аспекти, коли граматики LALR мають переваги перед граматиками LL та є інші аспекти, коли граматики LL мають переваги перед граматиками LALR.

YACC / Bison генерує парсери, керовані таблицею, а це означає, що "логіка обробки" міститься в даних програми аналізатора, а не стільки в коді аналізатора. Відплата полягає в тому, що навіть аналізатор дуже складної мови має відносно невеликий слід коду. Це було важливіше у 1960-70-ті роки, коли обладнання було дуже обмеженим. Генератори парсерів, керовані таблицями, повертаються до цієї епохи, і тоді головна вимога була невеликим слідом коду.

ANTLR генерує рекурсивні парсери зниження, що означає, що "логіка обробки" міститься в коді аналізатора, оскільки кожне правило виробництва граматики представлене функцією в коді аналізатора. Окупність полягає в тому, що легше зрозуміти, що робить аналізатор, прочитавши його код. Крім того, рекурсивні аналізатори спуску, як правило, швидші, ніж керовані таблицею. Однак для дуже складних мов слід коду буде більшим. Це було проблемою у 1960-х та 1970-х роках. Тоді лише такі невеликі мови, як, наприклад, Pascal, були реалізовані таким чином через обмеження обладнання.

Розроблені ANTLR парсери зазвичай знаходяться в районі 10 000 рядків коду і більше. Рукописні рекурсивні аналізатори спуску часто знаходяться в одному і тому ж бальному парку. Компілятор Wirth Oberon є, мабуть, найбільш компактним з приблизно 4000 рядками коду, включаючи генерацію коду, але Oberon - це дуже компактна мова, що містить лише близько 40 виробничих правил.

Як уже хтось зазначав, великим плюсом для ANTLR є графічний інструмент IDE, який називається ANTLRworks. Це повна лабораторія проектування граматики та мови. Він візуалізує ваші граматичні правила під час їх введення, і якщо він виявить конфлікти, він графічно покаже, що таке конфлікт і що його викликає. Він навіть може автоматично переробити і вирішити конфлікти, такі як ліва рекурсія. Після того, як у вас є безконфліктна граматика, ви можете дозволити ANTLRworks проаналізувати вхідний файл вашої мови та побудувати дерево розбору та AST для вас та графічно показати дерево в IDE. Це дуже велика перевага, оскільки це може заощадити багато годин роботи: Ви знайдете концептуальні помилки у мовній конструкції, перш ніж розпочати кодування! Я не знайшов такого інструменту для граматики LALR, схоже, такого інструмента немає.

Навіть людям, які не бажають генерувати свої парсери, але ручним кодом їх, ANTLRworks є прекрасним інструментом для мовного дизайну / складання прототипів. Цілком можливо найкращий такий інструмент. На жаль, це не допоможе вам, якщо ви хочете створити парсери LALR. Перехід з LALR на LL просто для того, щоб скористатися ANTLRworks, можливо, буде доцільним, але для деяких людей перемикання типів граматики може бути дуже болючим досвідом. Іншими словами: YMMV.


4
це подобається тому, що це пояснює історію, що стоїть за різними механізмами, завдяки чому люди негайно розуміють
цинкуючи

35

Пара переваг для ANTLR:

  • може виводити парсери на різних мовах - Java не потрібна для запуску створеного аналізатора.
  • Чудовий графічний інтерфейс спрощує налагодження граматики (наприклад, ви можете бачити створені права AST у графічному інтерфейсі, не потрібні додаткові інструменти)
  • Згенерований код насправді читається людиною (це одна з цілей ANTLR), і факт, що він генерує LL-аналізатори, безумовно, допомагає в цьому плані.
  • визначення терміналів також є без контексту (на відміну від регулярного вираження в (f) lex) - таким чином дозволяючи, наприклад, визначення терміналів, що містять правильно закриті дужки

Мої .02 $


9

Ще одна перевага ANTRL полягає в тому, що ви можете використовувати ANTLRWORKS , хоча я не можу сказати, що це сувора перевага, оскільки можуть бути подібні інструменти і для інших генераторів.


9
  • Bison і Flex призводять до зменшення пам'яті, але у вас немає графічного IDE.
  • antlr використовує більше пам'яті, але у вас є antlrworks, графічний IDE.

Використання оперативної пам'яті Bison / Flex, як правило, становить мегабайт або близько того. На противагу цьому з antlr - припустимо, що він використовує 512 байт пам'яті для кожного маркера у файлі, який ви хочете проаналізувати. 4 мільйони жетонів і у вас немає віртуальної пам’яті в 32-бітній системі.

Якщо файл, який ви хочете проаналізувати, великий, antlr може не вистачати пам'яті, тож якщо ви просто хочете розібрати файл конфігурації, це було б прийнятним рішенням. В іншому випадку, якщо ви хочете розібрати файл з великою кількістю даних, спробуйте Bison.


7
Мені цікаво. Чи можете ви вказати на документацію, що описує витрату 512 байт пам'яті на маркер? Я не пам'ятаю, як бачив цю дискусію. Мій вибір ключових слів Google теж не дає мені задоволення ...
Дон Уейкфілд,

2
Ви говорите про слід пам’яті генератора парсера під час генерації аналізатора чи ви говорите про слід пам’яті згенерованого аналізатора під час розбору входу для мови джерела? Мільйони лексем в граматиці були б абсолютно божевільними. Вам слід зачинитися в ментальному закладі, якщо ви серйозно намагалися продати таку ідею. Що стосується вхідних файлів для самого аналізатора, то можуть бути випадки, коли вони можуть мати надзвичайно велику кількість лексем, але більшість мов є модульними, ви не розбираєте весь вхід в одному файлі, окремі модулі менші.
trijezdci
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.