it-swarm.com.ru

В чем разница между LALR и LR-анализом?

Я понимаю, что LR и LALR являются алгоритмами синтаксического анализа снизу вверх, но в чем разница между ними?

В чем разница между разбором LR (0), LALR (1) и LR (1)? Как я могу определить, является ли грамматика LR (0), LALR (1) или LR (1)?

31
AAB

На высоком уровне разница между LR (0), LALR (1) и LR (1) заключается в следующем:

  • Парсер LALR (1) является «обновленной» версией парсера LR (0), который отслеживает более точную информацию для устранения неоднозначности грамматики. Парсер LR (1) является значительно более мощным парсером, который отслеживает даже более точную информацию, чем парсер LALR (1).

  • Парсеры LALR (1) имеют постоянный коэффициент, больший, чем парсеры LR (0), а парсеры LR (1) обычно экспоненциально больше, чем парсеры LALR (1).

  • Любая грамматика, которая может быть проанализирована с помощью синтаксического анализатора LR (0), может быть проанализирована с помощью синтаксического анализатора LALR (1), а любая грамматика, которая может быть проанализирована с помощью синтаксического анализатора LALR (1), может быть проанализирована с помощью синтаксического анализатора LR (1). Есть грамматики, которые являются LALR (1), но не LR (0) и LR (1), но не LALR (1).

Более формально, анализатор LR (k) - это анализатор снизу вверх, который работает, поддерживая стек терминалов и нетерминалов. Синтаксический анализатор управляется конечным автоматом, который на основе текущего состояния синтаксического анализатора и следующих k токенов ввода определяет, следует ли переместить новый токен в стек или уменьшить верхние символы стек, применяя производство в обратном порядке.

Чтобы отслеживать достаточно информации для определения того, сдвигать или уменьшать, парсеры LR (k) имеют каждое состояние, соответствующее «конфигурирующему набору», набору производств, снабженному следующей информацией:

  • Какая часть производства была замечена до сих пор, и
  • Какие токены следует ожидать после завершения производства (lookahead)

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

Проблемы возникают в парсере LR (k), когда возникают конфликты относительно того, что парсер должен делать в данном состоянии. Один тип конфликта - конфликт shift/Reduce возникает, когда анализатор находится в состоянии, в котором производство было завершено, но символы предпросмотра для этого производственного конфликта также используются другим незавершенным производством в состоянии. Это означает, что синтаксический анализатор не может определить, выполнять ли сокращение или нет. Второй тип конфликта - это конфликт уменьшать/уменьшать, когда анализатор знает, что он должен сделать сокращение, но возможно два или более сокращения, и он не может сказать, что делать.

Интуитивно понятно, что по мере того, как k становится все больше и больше, анализатор получает все более и более точную информацию, доступную ему, чтобы определить, когда сдвигать, а когда уменьшать. Например, если грамматика не является LR (0), то у синтаксического анализатора может быть состояние, в котором вообще не предвидится, что он не может определить, сдвигаться или уменьшаться. Тем не менее, эта грамматика все еще может быть LR (1), потому что, учитывая дополнительный токен прогнозирования, она может быть в состоянии распознать, что она должна определенно сдвигаться, а не уменьшаться или определенно уменьшаться и не сдвигаться.

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

LALR (1) был изобретен как компромисс между пространственной эффективностью парсеров LR (0) и выразительной силой парсеров LR (1). Есть несколько способов подумать о том, что такое парсер LALR (1). Первоначально парсеры LALR (1) были определены как преобразование, которое превращает автоматы LR (1) в меньшие автоматы. Хотя синтаксический анализатор LR (1) может иметь гораздо больше состояний, чем автомат LR (0), единственное отличие состоит в том, что синтаксический анализатор LR (1) может иметь несколько копий любого конкретного состояния в автомате LR (0), каждое из которых отмечено другая прогнозная информация. Парсер LALR (1) может быть сформирован, начиная с парсера LR (1), затем комбинируя вместе все состояния, которые имеют одинаковое «ядро» (набор произведений и их позиции), затем агрегируя всю информацию о перспективах вместе. Это приводит к тому, что синтаксический анализатор имеет такое же количество состояний, что и анализатор LR (0), но сохраняет некоторое количество информации о запросах, чтобы избежать конфликтов LR.Другое представление грамматик LALR (1) использует метод "LALR-by-SLR". Парсеры LALR (1) могут быть созданы, начиная с парсера LR (0) для грамматики, затем создавая новую грамматику для языка, которая аннотирует нетерминалы с информацией о том, каким состояниям в парсере LR (0) они соответствуют. Информация о наборах FOLLOW для нетерминалов в этой грамматике затем может быть использована для вычисления ориентиров в синтаксическом анализаторе LR (0).

Чистый результат заключается в том, что.

  • Парсеры LALR (1) немного больше из-за предварительной информации, но очень выразительны.
  • Парсеры LR (1) огромны, но чрезвычайно выразительны.
  • Что касается вашего второго вопроса - как вы определяете, является ли грамматика LR (1) или LALR (1) - стандартный подход состоит в том, чтобы попытаться построить автоматы синтаксического анализа для анализатора LR (1) и анализатора LALR (1) и проверки для конфликтов. Чтобы создать синтаксический анализатор LR (1), вы создаете конфигурационные наборы LR (1), а затем проверяете, есть ли у любого из этих конфигурационных наборов конфликт сдвига/уменьшения или уменьшения/уменьшения. Чтобы создать синтаксический анализатор LALR (1), вы можете либо создать синтаксический анализатор LR (1), а затем сконденсировать конфигурирующие множества с тем же ядром, либо использовать метод LALR by-SLR на основе синтаксического анализатора LR (0) для языка. Более подробную информацию о том, как создать эти наборы настроек, можно найти в большинстве учебников по компиляторам. Вы также можете проверить лекционные заметки из курса для составителей, который я преподавал летом 2012 г. , который охватывает все перечисленные выше методы синтаксического анализа и некоторые другие.

Надеюсь это поможет!.

Hope this helps!

56
templatetypedef

Алгоритм синтаксического анализа для хорошего парсера LALR (1) отличается двумя способами: (1) он должен иметь действия с уменьшением смещения, что уменьшает число состояний примерно на 30% и ускоряет работу парсера, и (2) он должен выполните одно или несколько сокращений при обнаружении синтаксической ошибки, что усложняет восстановление после ошибки. 

Алгоритм синтаксического анализа для канонического анализатора LR (1) (1) не имеет действий уменьшения сдвига и (2) не делает никаких сокращений при обнаружении синтаксической ошибки, что упрощает восстановление после ошибки. 

Существует еще один случай, называемый минимальным LR (1), в котором используется тот же алгоритм синтаксического анализа и алгоритм восстановления после ошибок, что и LALR (1). Минимальные парсеры LR (1) имеют мощность LR (1), а их размер почти такой же, как LALR (1). Генератор синтаксических анализаторов LRSTAR создает минимальные анализаторы LR (1) для программистов на C++. 

1
Paul B Mann

Парсеры LR (0), SLR (1), LALR (1) имеют одинаковое количество состояний. Минимальные парсеры LR (1) будут иметь еще несколько состояний, если этого требует грамматика, чтобы избежать конфликтов уменьшения-уменьшения. 

У синтаксических анализаторов Canonical LR (1) будет намного больше состояний, слишком много для средних и больших компьютерных языков. 

Генераторы синтаксического анализатора SLR (1) строят конечный автомат LR (0) и определяют значения k = 1, изучая грамматику (которая может сообщать о ошибочных конфликтах). 

Генераторы синтаксического анализатора LALR (1) строят конечный автомат LR (0) и определяют значения k = 1, изучая конечный автомат LR (0) (что очень сложно). 

Канонические генераторы парсера LR (1) создают конечный автомат LR (1). 

Генераторы минимального синтаксического анализатора LR (1) создают конечный автомат LR (1) и объединяют совместимые состояния в процессе сборки. 

0
Paul B Mann