Удаление левой рекурсии из грамматики без контекста - упорядочение непомощных

cs.stackexchange https://cs.stackexchange.com/questions/2792

Вопрос

Недавно я внедрил алгоритм Паула для удаления левой рекурсии из грамматики без контекста:

Назначьте заказ $ a_1, dots, a_n $ неледиям грамматики.

за $ i: = 1 $ to $ n $, делайте начало
$ Quad $ за $ j: = 1 $ до i-1 $ do begin
$ Quad Quad $ для каждого производства формы $ a_i to a_j alpha $ do begin
$ Quad Quad Quad $ удалить $ a_i to a_j alpha $ из грамматики
$ Quad Quad Quad $ для каждого производства формы $ a_j to beta $ do begin
$ Quad Quad Quad Quad $ добавить $ a_i to beta alpha $ в грамматику
$ Quad Quad Quad $ End
$ Quad Quad $ End
$ Quad $ End
$ Quad $ Transform $ a_i $ -productions для устранения прямой левой рекурсии
конец

Согласно с этот документ, эффективность алгоритма решает, что зависит от упорядочения неледниц, выбранных в начале; В документе подробно обсуждается этот вопрос и предлагает оптимизации.

Некоторые обозначения:

Мы скажем, что символ $ x $ - это Прямой левый угол из непонмерального $ a $, если есть $ $-$-продукция с $ x $ в качестве самого левого символа с правой стороны. Мы определяем Отношение левого коря быть рефлексивным транзитивным закрытием отношения прямого левого углу, и мы определяем Надлежащее левое отношение быть переходным закрытием отношения с прямым левым углом. Непомонец есть оставил рекурсивный Если это правильный левый угол себя; Непомонец есть непосредственно оставил рекурсивным Если это прямой левый угол себя; и непонамер косвенно оставил рекурсивным Если он остается рекурсивным, но не остается непосредственно рекурсивным.

Вот что предлагают авторы:

Во внутреннем цикле алгоритма Паулла для непосмерлов $ a_i $ и $ a_j $, так что $ i> J $ и $ a_j $ - прямой левый угол $ a_i $, мы заменяем все случаи $ a_j $ как прямой Левый угол $ a_i $ со всеми возможными расширениями $ a_j $.

Это только способствует ликвидации левой рекурсии из грамматики, если $ a_i $ является левой рекурсивным, и $ a_j $ лежит на пути, который делает $ a_i $ левой рекурсивным; То есть, если $ a_i $ является левым углом $ a_j $ (в дополнение к $ a_j $ является левым углом $ a_i $).

Мы могли бы устранить замены, которые бесполезны при удалении левой рекурсии, если бы мы могли заказать непосродные грамматики, чтобы, если $ i> j $ и $ a_j $ - прямой левый угол $ a_i $, то $ a_i $ также является Левый угол $ a_j $.

Мы можем достичь этого, упорядочив не терминалы в порядке уменьшения количества отдельных левых углов, которые у них есть.

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

Кроме того, поскольку мы определили, что отношение левого коря является рефлексивным, B является левым углом.

Следовательно, если C является прямым левым углом B, он должен следовать B в порядке уменьшения количества отдельных левых углов, если B не является левым углом C.

Все, что я хочу, - это знать, как заказать неледы вначале, но я не получаю его от бумаги. Может кто -нибудь объяснить это более простым образом? Псевдокод поможет мне лучше понять это.

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

Решение

Это на самом деле не очень сложно. Я предполагаю, что Epsilon Productions уже были исключены из языка, потому что это только скрывает ключевую концепцию «левого углу».

Сформируйте график g, где вершины-все не терминалы грамматики. Теперь нарисуйте направленное преимущество от A до B, если есть какое -либо производственное правило, которое выглядит как «a -> b [...]». В статье вызовы B A «прямой левый угол» A. В более общем плане, какой-то другой некомминальный C называется «левым углом» A, если есть какой-то путь от A до C вдоль краев этого графика. Это можно сделать путем вычисления Переходное закрытие G, назовите это H.

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

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

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