Вопрос

Почему ll (k) и ll (∞) несовместимы с левой рекурсией? Я понимаю, что язык LL (k) может поддерживать левую рекурсивность при условии, что с токенами K-Overahead может быть разрешена любая двусмысленность. Но с грамматикой LL (∞) какой тип неоднозначности нельзя решить?

Это было полезно?

Решение

Проблема, которую имеют варианты $ ll $ с левой рекурсией, присуща тем, как работает $ ll $: это анализатор типа нисходящего вниз, что означает, что он заменяет неподмеси на их постановки.

Ак-стиль стиля $ ll $ работает следующим образом. Он пересекает вход слева направо за один ход. Если мы находимся в какой -то точке ввода, то мы знаем, что все слева от этой точки в порядке. Для всех справа от этого момента анализатор построил «приближение» того, что он ожидает увидеть дальше. Рассмотрим, например, эта грамматика:

1: $ e to e + e $
2: $ e to x $

Обратите внимание, что грамматика не является $ ll $, но мы все еще можем проанализировать входные данные в стиле $ ll $. При вводе $ x+x+x $, анализатор $ ll $ -Style может в конечном итоге оказаться в позиции $ x+ bullet x+x $. Давайте предположим, что он решил, что левая часть, $ x+$, в порядке, а для остальной части ввода она ожидает увидеть $ x+e $. Затем он узнает, что $ x+x+$ в порядке, оставшаяся $ e $. Затем он может заменить этот $ e $ на производство, в частности, производство 2 выше. С оставшимся $ x $, анализатор примет вход.

Затем хитрость заключается в том, чтобы правильно определить замену производства для данного непонцерального. Грамматика - это $ ll (k) $, если мы можем сделать это, просто посмотрев на следующие символы ввода $ k $, и известны другие методы, которые более мощные.

Теперь рассмотрим следующую грамматику:

1: $ a to a $
2: $ a to varepsilon $

Если анализатор $ ll $ пытается заменить $ A $ на производство, он должен принять решение между производством 1 и 2.

Давайте рассмотрим, каким будет правильный курс действий, если бы наш анализатор был всеведущим. Каждый раз, когда он заменяет $ A $ By Production 1, он «добавляет» $ a $ к тому, что ожидает от оставшегося вклада (ожидаемый остаток переходит от $ $ $ $ $ $ $ aaa $ ...), Но $ A $ в начале не уходит. В конце концов, он должен выбрать Production 2, после чего $ A $ исчезает, и никогда больше не может добавить $ A $ S к ожиданиям.

Поскольку нет шансов сопоставить еще несколько входных символов, анализатор должен точно решить в той входной позиции, сколько раз производство 1 должно быть сопоставлено. Это означает, что он должен точно знать, сколько раз в нашем случае $ A $ появится в оставшейся части вклада в данный момент.

Тем не менее, $ ll (k) $ может видеть только символы $ k $ впереди. Это означает, что если производство 1 должно быть выбрано более чем $ k $ раз, то парсер не может «увидеть» это, и поэтому обречено на неудачу. $ Ll (*) $ лучше в диапазоне, чем $ ll (k) $, потому что он может видеть произвольно далеко впереди, но решающая деталь (которая не всегда упоминается) заключается в том, что этот Lookahead обычный.

Чтобы представить, что произойдет, вы можете просмотреть алгоритм следующим образом: когда он должен решить, какую продукцию взять, он запускает конечную машину (DFA, которая эквивалентна власти для регулярных выражений) и позволяет этой машине смотреть на Остальная часть ввода. Затем эта машина может сообщить «Использовать эту производство». Тем не менее, эта машина сильно ограничена в том, что она может сделать. Хотя это строго лучше, чем смотреть только на следующие символы $ K $, он не может, например, «считать», что означает, что он не может помочь в вышеуказанной ситуации.

Даже если вы должны были «взломать» какую-то функцию подсчета в этом конечном автомате, то все еще существуют левые грамматики, для которых вам действительно нужно больше мощности. Например, для этой грамматики:

$ A to ab $
$ A to varepsilon $
$ B to (b) $
$ B to varepsilon $

Вам придется соответствовать «башням» подходящих брекетов, что не может сделать конечный автомат. Что еще хуже:

$ A to bcade $
$ A to '$
$ A ' to' de $
$ A ' to varepsilon $
$ B to b a mid b b b mid a mid bb $
$ C to c c c mid d c d mid cc mid dd $
$ D to e d e mid f d f mid ee mid ff $
$ E to g e g mid h h mid gg mid hh $

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с cs.stackexchange
scroll top