Можно написать Regex, для которого в некоторых случаях требуется экспоненциальное время работы. Такой пример (aa|aa)*
. Если есть вход нечетного числа a
, ему требуется экспоненциальное время работы.
Это легко проверить. Если вход содержит только a
и имеет длину 51, для вычисления Regex требуется несколько секунд (на моей машине). Вместо этого, если длина ввода равна 52, его вычислительное время не заметно (я тестировал это со встроенным анализатором Regex JavaRE).
Я написал регекс-парсер, чтобы найти причину такого поведения, но я его не нашел. Мой анализатор может построить AST или NFA на основе Regex. После этого он может перевести NFA в DFA. Для этого используется алгоритм построения графиков.
Когда я разбираю Rgex, упомянутый выше, парсер создает NFA с 7 состояниями - после преобразования в DFA осталось только 3 состояния. DFA представляет более разумное Regex (aa)*
, которое можно проанализировать очень быстро.
Таким образом, я не понимаю, почему существуют парсеры, которые могут быть настолько медленными. Что является причиной этого? Разве они не переводят NFA в DFA? Если да, почему бы и нет? И каковы технические причины, по которым они так медленно вычисляются?