Шаги по созданию NFA из регулярного выражения

У меня возникли проблемы с описанием каждого шага при создании НКА из регулярного выражения. Вопрос заключается в следующем:

преобразуйте следующее регулярное выражение в недетерминированный конечный автомат (NFA), четко описывающий шаги используемого алгоритма: (b|a)*b(a / b)

Я сделал простую машину 3-го состояния, но это очень много от интуиции. Это вопрос из прошлого экзамена, написанного моим лектором, который также написал следующее объяснение алгоритма Томпсона:http://www.cs.may.ie/staff/jpower/Courses/Previous/parsing/node5.html

может ли кто-нибудь прояснить, как "четко описать каждый шаг"? Это просто кажется набором основных правил, а не алгоритмом с шагами, которым нужно следовать.

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

2 ответов


краткая версия для общего подхода.
Там есть Альго, называемый алгоритмом построения Томпсона-Макнотона-Ямады, или иногда просто "Томпсон Констракшн"."Строятся промежуточные NFAs, заполняя куски по пути, соблюдая приоритет оператора: сначала круглые скобки, затем Kleene Star (например, a*), затем конкатенация (например, ab), а затем чередование (например, a|b).

вот подробное пошаговое руководство для построения (b|a)*b(a / b)'S NFA

строительство верхнего уровня

  1. ручки скобки. Примечание: в фактической реализации, это может иметь смысл для обработки круглых скобках через рекурсивный вызов на их содержание. Для ясности, я отложу оценку чего-либо внутри родителей.

  2. Kleene Stars: только один * там, поэтому мы строим заполнитель Kleene Star machine под названием P (который позже будет содержать b|a). Промежуточный результат:
    Non-Deterministic Finite Automata for P*

  3. конкатенация: присоедините P к b и присоедините b к машине-заполнителю Q (которая будет содержать (a|b). Промежуточный результат:
    Non-Deterministic Finite Automata for P*bQ

  4. нет чередования вне скобок, поэтому мы пропустим это.

теперь мы сидим на машине P*bQ. (Обратите внимание, что наши заполнители P и Q-это просто машины конкатенации.) Мы заменяем край P на NFA для b / a и заменяем Q edge с NFA для a / b через рекурсивное применение вышеуказанных шагов.


Здание P

  1. пропустить. Нет фаренс.

  2. пропустить. Никаких звезд Клина.

  3. пропустить. Нет contatenation.

  4. Построьте машину перемежения для Б/ А. Промежуточный результат:
    NFA for b or a


интеграция P

затем мы возвращаемся к этой машине P*bQ и вырываем край P. У нас есть источник края P служить в качестве начального состояния для машины P и назначение края P служить государству местом для машины. Мы также заставляем это государство отвергать (отбирать его свойство быть принимающим государством). Результат выглядит так:
enter image description here


дом Q

  1. пропустить. Нет фаренс.

  2. пропустить. Никаких звезд Клина.

  3. пропустить. Нет contatenation.

  4. Построьте машину перемежения для a / b. Кстати, чередование коммутативно, поэтому a|b логически эквивалентно b|A. (Читайте: пропуская эту небольшую диаграмму сноски из лени.)


Интеграция Q

мы делаем то, что мы сделали с P выше, за исключением замены края Q на intermedtae B|A машину, которую мы построили. Вот результат:
enter image description here

Тада! Э-э, я имею в виду, что и требовалось доказать.


хотите узнать больше?

все изображения выше были сгенерированы с помощью онлайн-инструмент для автоматического преобразования регулярных выражений в недетерминированные конечные автоматы. Вы можете найти его исходный код для Thompson-McNaughton-Yamada Алгоритм построения онлайн.

алгоритм также рассматривается в компиляторы Aho: принципы, методы и инструменты, хотя его объяснение скудно по деталям реализации. Вы также можете узнать из реализация конструкции Томпсона в C от превосходного Расса Кокса, который описал его некоторые детали в популярной статье о регулярные выражения.


в репозитории GitHub ниже вы можете найти Java-реализацию конструкции Томпсона, где сначала создается NFA из регулярного выражения, а затем сопоставляется входная строка с этим NFA:

https://github.com/meghdadFar/regex