442
правки
Изменения
→Построение НКА
Это произошло из-за того, что обычного функционала регулярных выражений зачастую недостаточно, не хватает выразительной мощности. В языках PCRE, Ruby, Python, Perl добавили поддержку обратных ссылок (англ. ''back reference''). Она позволяет связывать ранее найденное сгруппированное выражение в скобках с числом от <tex>1</tex> до <tex>9</tex>. Например: <tex>\mathtt{(cat|dog)\backslash1}</tex> найдет <tex>\mathtt{catcat}</tex> или <tex>\mathtt{dogdog}</tex>, но никак не <tex>\mathtt{catdog}</tex> или <tex>\mathtt{dogcat}</tex>. Интересно, что с добавлением обратных ссылок регулярные выражения перестаю относиться к классу регулярных языков. К сожалению, лучшая реализация требует экспоненциального времени работы. Приведенная на графике синяя кривая является реализацией построения НКА по регулярному выражению написанная на C, занимающая чуть меньше, чем <tex>400</tex> строк и описанная в [https://swtch.com/~rsc/regexp/regexp1.html данной статье].
=== Построение НКА ===
Для построения автомата нам нужно построить отдельно части НКА для каждой части выражения, финальным шагом будет соединение всего автомата вместе. Для примера напишем программу на '''C''', представим Представим НКА как связанный список структур состояний <tex>\mathrm{state}</tex>
'''struct''' state:
'''int''' c
<tex>\mathrm{start}</tex> указывает на стартовое состояние фрагмента, а <tex>\mathrm{out}</tex> {{---}} лист указателей на <tex>\mathrm{state*}</tex> указатели, которые ещё не соединены.
Некоторые полезные функции для управления списком указателей:
'''fun''' list1('''state''' **outp): '''ptrList''' '''fun''' append('''ptrList''' *l1, '''ptrList''' *l2): '''ptrList''' '''fun''' patch('''ptrList''' *l, '''state''' *s)
<tex>\mathrm{list1}</tex> создает новый список указателей состоящий из одного указателя <tex>\mathrm{outp}</tex>. <tex>\mathrm{append}</tex> конкатенирует два списка указателей, возвращая результат. <tex>\mathrm{patch}</tex> связывает повисшую стрелку в списке <tex>\mathrm{l}</tex> с состоянием <tex>\mathrm{s}</tex>.
Используя данные примитивы и стек фрагментов можно реализовать построение НКА.