Чи використовують сучасні мови генератори парсера?


38

Я досліджував про набір компіляторів GCC на вікіпедії тут , коли це придумав:

GCC почав використовувати парсери LALR, створені разом із Bison, але поступово перейшов на рукописний рекурсивно-десертний парсер; для C ++ в 2004 році, а для C і Objective-C в 2006 році. В даний час усі передні торці використовують рукописні рекурсивно-розбірні аналізатори

Отже, в останньому реченні (і стільки, наскільки я довіряю вікіпедії), я можу однозначно сказати, що "C (gcc), C ++ (g ++), Objective-C, Objective-C ++, Fortran (gfortran), Java (gcj), Ада (GNAT), Go (gccgo), Pascal (gpc), ... Ртуть, Modula-2, Modula-3, PL / I, D (gdc) і VHDL (ghdl) "- це всі передні частини, які ні більше використовувати генератор парсера. Тобто всі вони використовують рукописні парсери.

Тож моє запитання: чи є така практика всюдисуща? Зокрема, я шукаю точні відповіді на те, "чи стандартна / офіційна реалізація x має рукописний аналізатор" для x в [Python, Swift, Ruby, Java, Scala, ML, Haskell]? (Насправді тут також вітається інформація про будь-які інші мови.) Я впевнений, що зможу знайти це самостійно після багатьох копань. Але я також впевнений, що громада легко відповідає за це. Спасибі!


3
Точка даних: CPython має генератор парного розбору LALR для домашнього приготування (pgen). Не знаю про решту.

8
Точка даних: Ghc (haskell) використовує генератор аналізатора LALR (щасливий), як і OCaml.
Twan van Laarhoven

1
Повинно бути "Зробити сучасні високоефективні компілятори ..." або подібне, тому що мова є специфікацією, а не реалізацією, тоді як компілятор робить або не використовує машинний генерований аналізатор.
dmckee

@dmckee, так, ти прав. Однак найменування починає набирати великої тривалості і менше. Не соромтесь редагувати це, хоча ви творчіші за мене!
eatonphil

Що стосується ML: MLton використовує генератор парсера, характерний для ML, я на 90% впевнений, що SML / NJ робить занадто, хоча я менш знайомий з ним. Ви можете чи не хочете вважати це "написаним від руки".
Патрік Коллінз

Відповіді:


34

AFAIK, GCC використовують рукописний аналізатор, зокрема, для вдосконалення синтаксичної діагностики помилок (тобто надання людям значущих повідомлень про синтаксичні помилки).

Теорія розбору (і генератори розбору, що сходять від неї), здебільшого стосується розпізнавання та розбору правильної вхідної фрази. Але ми очікуємо від компіляторів, що вони дадуть змістовне повідомлення про помилку (і що вони можуть змістовно проаналізувати решту вхідних даних після синтаксичної помилки) для деякого неправильного введення.

Крім того, старі застарілі мови, як-от C11 або C ++ 11- (які концептуально старі, навіть якщо їх остання редакція становить лише три роки), зовсім не є контекстними. Справа з цією контекстною чутливістю в граматиках для генераторів парсеру (тобто зубрів або навіть менгір ) нудно важко.


2
Збіг. Добре відновлення помилок розбору (коли ви не хочете зупиняти розбір на першій помилці, а-ля старий Borland Pascal) та створювати повідомлення про помилки хорошої якості (включаючи підказки та пропозиції щодо вирішення, як хочуть люди) - це іманентно контекст -чутливі, евристичні завдання. Їх можна зробити дещо на виході генератора запасів парсера, але це гасло.
Джонатан Юніс

2
Dealing with that context sensitiveness in grammars for parser generators is boringly difficult. Це також більш-менш неможливо, оскільки ці інструменти генерують без контекстних аналізаторів. Правильне місце для перевірки наявності всіх контекстно-залежних обмежень є після того, як ви створили дерево розбору, якщо ви використовуєте такі інструменти.
dtech

7

Генератори парсера та парсерні двигуни є досить загальними. Перевага загальності полягає в тому, що побудувати точний аналізатор швидко та зробити його функціональним легко у загальній схемі речей.

Сам парсерний двигун страждає на передній частині продуктивності через свою загальність. Будь-який написаний вручну код завжди буде значно швидше, ніж двигуни для розбору таблиць.

Друга сфера, в якій генератори / двигуни парсеру мають труднощі, - це те, що всі реальні мови програмування залежать від контексту, часто досить тонко. Мови LR є безконтекстними, це означає, що існує багато тонкощів щодо позиціонування та оточення, які неможливо правильно передати у синтаксисі. Граматики, що приписуються, намагаються вирішити основні мовні правила, такі як "оголосити перед використанням" тощо. Підключення цієї контекстної чутливості до рукописного коду прямо вперед.


15
Цитування заявки на виконання, будь ласка? Керування таблицями може бути значною оптимізацією продуктивності, і генератори мають доступ до алгоритмів, які дуже ефективні, але практично ніколи не реалізуються вручну (саме тому, що вони є непроникною безладдям таблиць і магічних чисел).

2
А щодо другої області: Багато багатьох основних реальних мов програмування не є контекстно-чутливими в будь-якому сенсі, що застосовується (вам доведеться посилатися на набір усіх дійсних програм після перевірки типу і таких, що ніколи не є рукописним або сформований аналізатор намагається проаналізувати). Це правда, що рукописні парсери є більш гнучкими, і це корисно для деяких мов, але здебільшого в царині відновлення помилок і звітування, наростання тощо. Генератори парсера рідко уникаються через владу розпізнавання (чи ти хочу написати таку граматику - це інша історія). -1

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

1
C і C ++ потребують інформації таблиці символів під час розбору (або приймають набагато менш специфічне дерево розбору, де не робиться різниці між, наприклад, операторами вираження та оголошеннями змінної). Але я про це не думав. Такі мови, як Java, Lisps, JavaScript, Ruby, Python, Go, Rust, Scala, Swift, Haskell (і, напевно, ще кілька, можливо, також C # та ML?), Не потребують такої інформації для створення типу AST, який ви хотіли б. хочу все одно. Багато з них насправді мають граматики LL (1) або навіть LALR граматики.

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