Regex engine internals as a library. Part 3

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.
Содержание

  • Краткий экскурс

  • Проблемы

    • Проблема: сложная композиция

    • Проблема: сложность тестирования

    • Проблема: запрос на нишевые API

    • Проблема: полностью скомпилированные ДКА

  • По пути с regex-cli

  • Поток данных

  • Литеральные оптимизации

    • Мотивация литеральных оптимизаций

    • Извлечение литералов

    • Поиск литералов

  • Тип данных - НКА

    • Простой пример НКА

    • Оптимизация НКА: разреженное состояние

    • Оптимизация НКА: минимальный автомат для UTF-8

    • Оптимизация НКА: дерево литералов

    • Дальнейшие доработки НКА

  • Движки регулярных выражений

    • Общие элементы всех движков регулярных выражений

    • Движок: PikeVM

    • Движок: BoundedBacktracker

    • Движок: однопроходный ДКА

    • Движок: ДКА

    • Движок: гибрид НКА/ДКА

    • Мета движок регулярных выражений

  • Отличия от RE2

  • Стратегия тестирования

  • Бенчмаркинг

  • Чего всё это стоило

  • Заключение

Тип данных - НКА

Если внутри крейта regex и был центральный тип данных, то, по всей вероятности, это был бы НКА. Если точнее, это НКА Томпсона, что означает, что он был построен алгоритмом, схожим с Томпсоновским алгоритмом конструирования. Этот алгоритм строит НКА из структурированного представления р.в. за время O(m), где m пропорционально размеру р.в. после подсчёта повторений, которые разворачиваются. (Например, a{5} - это aaaaa.) Алгоритм работает, отображая каждый тип р.в. в мини-НКа, а затем определяя правила для комбинирования этих мини-НКА в один большой НКА.

НКА - центральный тип данных, потому что он используется напрямую, как есть, для реализации движка р.в. Но НКА так же могут быть преобразован в другие типы (такие, как ДКА), которые в свою очередь используются для реализации разных движков р.в. По сути, в данный момент, если вам хочется построить движок р.в. с помощью крейта regex-automata, то вам придётся начать с НКА Томпсона.

Перед тем, как разбираться с НКА более детально, взглянем на простой пример.

Простой пример НКА

Так же как и в случае извлечения литералов, regex-cli может нам быть полезным, позволяя выводить отладочное представление НКА заданного р.в.:

$ regex-cli debug thompson 'a'
        parse time:  9.856µs
    translate time:  3.005µs
  compile nfa time:  18.51µs
            memory:  700
            states:  6
       pattern len:  1
       capture len:  1
        has empty?:  false
          is utf8?:  true
       is reverse?:  false
   line terminator:  "\n"
       lookset any:  ∅
lookset prefix any:  ∅
lookset prefix all:  ∅

thompson::NFA(
>000000: binary-union(2, 1)
 000001: \x00-\xFF => 0
^000002: capture(pid=0, group=0, slot=0) => 3
 000003: a => 4
 000004: capture(pid=0, group=0, slot=1) => 5
 000005: MATCH(0)

transition equivalence classes: ByteClasses(0 => [\x00-`], 1 => [a], 2 => [b-\xFF], 3 => [EOI])
)

Далее я буду сокращать вывод только до самого НКА. Так что объясню, что тут значит остальной вывод:

  • Тайминги парсинга и трансляции - тоже самое, что и в случае извлечения литералов. Напомню, что это время построения значений Ast и Hir.

  • compile nfa time - время построения структуры данных NFA из значения Hir.

  • memory - объём кучи, используемой НКА

  • states - количество состояний в НКА

  • pattern len - количество шаблонов в НКА

  • capture len - количество групп захвата (далее - г.з.), скомпилированных в НКА. Когда г.з. задействованы (по-умолчанию это так), тогда в НКА будет как минимум одна г.з., соответствующая всему совпадению.

  • has empty? - может ли НКА вернуть пустую строку в качестве совпадения или нет.

  • is utf8? - гарантирует ли НКА то, что он никогда не вернёт в качестве совпадения невалидную UTF-8 строку. Это так же включает в себя ограничение на сопоставление пустой строки между code units в UTF-8 codepoint. Например,

Источник: https://habr.com/ru/articles/749730/


Интересные статьи

Интересные статьи

В Unreal Engine 5, Блюпринты являются одним из основных инструментов для создания игровой логики без необходимости писать код на C++. Блюпринты позволяют разработчикам создавать, настраивать и контрол...
Всем привет!Меня зовут Надя, я занимаю должность Data Engineer в компании, которая специализируется на разработке мобильных игр. В этой статье я хочу поделиться информацией об основных инструментах, к...
В последнее время, всё чаще мы слышим новости о том, как китайские вендоры потихоньку начинают переходить на своё железо: тут вам и новости о x86 процессорах Zhaoxin, и Loongsoon (экспорт которого зап...
Привет! Это вторая статья из цикла о разработке приложения на Flutter. В этом "номере" я опишу создание сетевого слоя, работу с локализацией, удобный способ работы с ассетами, локальный поиск и создан...
Изображение: Unsplash Уже несколько дней интернет-общественность активно обсуждает фильм Юрия Дудя про Кремниевую долину. Опрошенные блогером эксперты рассказали об устройстве мировой IТ-с...