Подтвердить что ты не робот

Анализ парсера Packrat против LALR

Многие веб-сайты заявляют, что партизаны packrat могут анализировать входные данные в линейном времени.
Поэтому при первом взгляде они меня бывают быстрее, чем парсер LALR, созданный инструментами yacc или bison.

Я хотел знать, лучше ли производительность парсера packrr/хуже, чем производительность парсера LALR при тестировании с общим входом (например, исходные файлы языка программирования), а не с любыми теоретическими вводами.

Кто-нибудь может объяснить основные различия между этими двумя подходами. Спасибо!

4b9b3361

Ответ 1

Я не эксперт в разборе пакетов, но вы можете узнать больше в Разбор грамматики выражений в Википедии.

Я не вкопался в него, поэтому я предполагаю, что линейная характеристика парсинга packrt верна.

L (AL) R парсеров также являются линейными анализаторами времени. Таким образом, теоретически, парсер Packrat и L (AL) R "быстрее".

На практике важно, конечно, реализация. Переходы состояний L (AL) R могут выполняться в очень немногих машинных инструкциях ( "смотреть код токена вверх в векторе, получать следующее состояние и действие" ), поэтому они могут быть чрезвычайно быстрыми на практике. Под "компиляцией" L (AL) R, анализируя машинный код, вы можете получить сильные синтаксические анализаторы, как показано в этой статье Том Пэннелло 1986 года о очень быстрой LR разборе. (Машины теперь на 20 лет быстрее, чем при написании статьи!).

Если парсары packrat сохраняют/кэшируют результаты по мере их поступления, они могут быть линейным временем, но я предполагаю, что постоянные накладные расходы будут довольно высокими, а затем парсеры L (AL) R на практике будут намного быстрее. Реализации YACC и Bison из того, что я слышу, довольно хороши.

Если вам нужен ответ, внимательно ознакомьтесь с основными техническими документами; если вы действительно заботитесь, тогда реализуйте один из них и проверяйте накладные константы. Мои деньги сильно зависят от L (AL) R.

Наблюдение: большинство языковых интерфейсов не проводят большую часть своего времени "разбора"; скорее, они проводят много времени в лексическом анализе. Оптимизируйте это (ваша биография говорит о вас), и скорость парсера не будет иметь большого значения.

(Я использовал генераторы парсера LALR и соответствующие синтаксические анализаторы. Я больше этого не делаю, вместо этого я использую GLR parsers, которые являются линейными время на практике, но обрабатывать произвольные контекстно-свободные грамматики. Я отказываюсь от некоторой производительности, но я могу [и делать, видеть биографию] строить десятки парсеров для многих языков без особых проблем.).

Ответ 2

Я являюсь автором LRSTAR, генератора синтаксических анализаторов LR (k) с открытым исходным кодом. Поскольку люди проявляют интерес к этому, я разместил продукт здесь онлайн LRSTAR.

Я много лет изучал скорость парсеров LALR и лексеров DFA. Статья Тома Пеннелло очень интересна, но это скорее академическое упражнение, чем реальное решение для компиляторов. Однако, если все, что вам нужно, это распознаватель образов, то это может быть идеальным решением для вас.

Проблема состоит в том, что реальным компиляторам обычно нужно делать больше, чем распознавание образов, такое как поиск в таблице символов для входящих символов, восстановление после ошибок, предоставление списка ожидания (информация о завершении оператора) и создание дерева абстрактного синтаксиса, пока разбор.

В 1989 году я сравнил скорость синтаксического анализа синтаксических анализаторов LRSTAR с "yacc" и обнаружил, что они в 2 раза превышают скорость синтаксических анализаторов "yacc". Парсеры LRSTAR используют идеи, опубликованные в статье: "Оптимизация таблиц парсеров для переносных компиляторов".

Что касается скорости лексера (лексического анализа), я обнаружил в 2009 году, что "re2c" генерирует самые быстрые лексеры, примерно в два раза быстрее, чем те, которые генерирует "flex". В то время я переписывал секцию генератора лексеров LRSTAR и нашел способ сделать лексеры почти такими же быстрыми, как "re2c", и намного меньше. Однако я предпочитаю лексеры, управляемые таблицами, которые генерирует LRSTAR, потому что они почти такие же быстрые, а код компилируется намного быстрее.

Кстати, внешние интерфейсы компилятора, сгенерированные LRSTAR, могут обрабатывать исходный код со скоростью 2400000 строк в секунду или быстрее. Сгенерированные LRSTAR лексеры могут обрабатывать 30 000 000 токенов в секунду. Тестируемый компьютер представлял собой машину с частотой 3,5 ГГц (с 2010 года).

Ответ 4

Производительность в основном зависит от языка. Для каждого языка будет создан подход, технология или генератор парсера, который наилучшим образом подходит.

Я не могу это доказать без лишних мыслей, но я думаю, что ничто не может побить нисходящий парсер с нисходящим потоком, в котором семантика управляет парсером, а парсер управляет лексером, с точки зрения производительности. Он также будет одним из самых универсальных и более легким для поддержки среди реализаций.

Ответ 5

Я знаю, что это старый пост, но примерно месяц назад я наткнулся на этот документ: https://www.mercurylang.org/documentation/papers/packrat.pdf и случайно увидел этот пост сегодня.

Разветвленная версия этого документа гласит: запоминание пакетов - это смешанное благословение. Наилучших результатов можно достичь, если у вас есть эвристика относительно того, как часто будет соответствовать это или другое правило. По сути, имеет смысл запоминать правила, которые имеют два следующих свойства: (1) несколько элементов, (2) очень распространенные.