Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

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

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

Определение [ править ]

Грамматика является леворекурсивной тогда и только тогда, когда существует нетерминальный символ, который может образовывать сентенциальную форму с самим собой в качестве крайнего левого символа. [1] Символично,

,

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

Прямая левая рекурсия [ править ]

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

где - последовательность нетерминалов и терминалов. Например, правило

является непосредственно леворекурсивным. Парсер рекурсивного спуска слева направо для этого правила может выглядеть так:

недействительным  Выражение ()  {  Выражение ();  совпадение ( '+' );  Срок (); }

и такой код при выполнении попадет в бесконечную рекурсию.

Косвенная левая рекурсия [ править ]

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

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

затем выдает как крайний левый в своей окончательной форме предложения.

Удаление левой рекурсии [ править ]

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

Удаление прямой левой рекурсии [ править ]

Общий алгоритм удаления прямой левой рекурсии следующий. В этот метод внесено несколько улучшений. [2] Для леворекурсивного нетерминала отбросьте все правила формы и рассмотрите оставшиеся:

где:

  • каждый - непустая последовательность нетерминалов и терминалов, и
  • каждый - это последовательность нетерминалов и терминалов, не начинающаяся с .

Замените их двумя наборами продукции, один набор для :

и еще один набор для свежего нетерминала (часто называемого "хвостом" или "остальным"):

Повторяйте этот процесс до тех пор, пока не останется прямой левой рекурсии.

В качестве примера рассмотрим набор правил

Это можно переписать, чтобы избежать левой рекурсии, как

Удаление всей левой рекурсии [ править ]

Установив топологический порядок на нетерминалах, вышеупомянутый процесс может быть расширен, чтобы также исключить косвенную левую рекурсию [ необходима цитата ] :

Входы Грамматика: набор нетерминалов и их продукции
Выходные данные Измененная грамматика, генерирующая тот же язык, но без левой рекурсии.
  1. Для каждого нетерминала :
    1. Повторяйте, пока итерация не оставит грамматику неизменной:
      1. Для каждого правила , представляющего собой последовательность терминалов и нетерминалов:
        1. Если начинается с нетерминального и :
          1. Пусть будет без его руководства .
          2. Удалите правило .
          3. Для каждого правила :
            1. Добавьте правило .
    2. Удалите прямую левую рекурсию, как описано выше.

Обратите внимание, что этот алгоритм очень чувствителен к нетерминальному порядку; оптимизации часто сосредотачиваются на правильном выборе этого порядка. [ требуется разъяснение ]

Ловушки [ править ]

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

Ассоциативность особенно уязвима; левоассоциативные операторы обычно появляются в правой ассоциативной структуре в соответствии с новой грамматикой. Например, начиная с этой грамматики:

стандартные преобразования для удаления левой рекурсии дают следующее:

Анализ строки «1-2-3» с первой грамматикой в ​​анализаторе LALR (который может обрабатывать леворекурсивные грамматики) привел бы к дереву синтаксического анализа:

Леворекурсивный разбор двойного вычитания

Это дерево синтаксического анализа группирует термины слева, давая правильную семантику (1-2) - 3 .

Парсинг со второй грамматикой дает

Праворекурсивный разбор двойного вычитания

который при правильной интерпретации означает 1 + (-2 + (-3)) , также правильный, но менее точный для ввода и намного сложнее реализовать для некоторых операторов. Обратите внимание, как термины справа появляются глубже в дереве, так же как праворекурсивная грамматика упорядочивает их для 1 - (2 - 3) .

Учет левой рекурсии при синтаксическом анализе сверху вниз [ править ]

Формальная грамматика , которая содержит левую рекурсию не может быть проанализирована с помощью LL (к) -parser или другого наивныма метода рекурсивного спуска , если он не преобразуется в слабо эквивалентную правой рекурсии формы. Напротив, левая рекурсия предпочтительнее для парсеров LALR, потому что она приводит к меньшему использованию стека, чем правая рекурсия . Однако более сложные нисходящие синтаксические анализаторы могут реализовать общие контекстно-свободные грамматики с помощью сокращения. В 2006 году Фрост и Хафиз описали алгоритм, который учитывает неоднозначные грамматики с прямыми леворекурсивными производственными правилами . [3]Этот алгоритм был расширен до полного алгоритма синтаксического анализа для размещения косвенной, а также прямой левой рекурсии за полиномиальное время и для генерации компактных представлений полиномиального размера потенциально экспоненциального числа деревьев синтаксического анализа для весьма неоднозначных грамматик Фростом, Хафизом и Каллаганом в 2007 году. . [4] Затем авторы реализовали алгоритм в виде набора комбинаторов синтаксического анализатора, написанных на языке программирования Haskell . [5]

См. Также [ править ]

  • Хвостовая рекурсия

Ссылки [ править ]

  1. ^ Заметки по теории формального языка и синтаксическому анализу , Джеймс Пауэр, факультет компьютерных наук Национального университета Ирландии, Мейнут Мейнут, графство Килдэр, Ирландия. JPR02
  2. Мур, Роберт С. (май 2000 г.). «Удаление левой рекурсии из контекстно-свободных грамматик» (PDF) . 6-я конференция по прикладной обработке естественного языка : 249–255.
  3. ^ Frost, R .; Р. Хафиз (2006). «Новый алгоритм нисходящего синтаксического анализа для устранения неоднозначности и левой рекурсии за полиномиальное время» . Уведомления ACM SIGPLAN . 41 (5): 46–54. DOI : 10.1145 / 1149982.1149988 ., доступный у автора по адресу http://hafiz.myweb.cs.uwindsor.ca/pub/p46-frost.pdf. Архивировано 8 января 2015 г. на Wayback Machine.
  4. ^ Frost, R .; Р. Хафиз; П. Каллаган (июнь 2007 г.). «Модульный и эффективный анализ сверху вниз для неоднозначных леворекурсивных грамматик» (PDF) . 10-й Международный семинар по технологиям синтаксического анализа (IWPT), ACL-SIGPARSE : 109–120. Архивировано из оригинального (PDF) 27 мая 2011 года.
  5. ^ Frost, R .; Р. Хафиз; П. Каллаган (январь 2008 г.). Комбинаторы синтаксического анализатора для неоднозначных леворекурсивных грамматик (PDF) . 10-й Международный симпозиум по практическим аспектам декларативных языков (PADL), ACM-SIGPLAN . Конспект лекций по информатике. 4902 . С. 167–181. DOI : 10.1007 / 978-3-540-77442-6_12 . ISBN  978-3-540-77441-9.

Внешние ссылки [ править ]

  • Практические соображения по грамматике LALR (1)