Рубрики
Без рубрики

Как построить двигатель Regex в Python (часть 2: Lexer)

В предыдущей статье мы говорили о грамматике и что нам нужно для завершения этого проекта. Это снег… Теги с Python, программированием, регелем, лексером.

Как построить двигатель Regex в Python (4 часть серии)

В предыдущей статье мы говорили о грамматике и что нам нужно для завершения этого проекта.

Сейчас время наконец копаться в кодировке.

Чтобы настроить окружающую среду, сначала нужно создать папку для проекта, а Virtualenv мы будем использовать для него.

mkdir pyregex  
cd pyregexpython3 -m venv venv  
source venv/bin/activate

Для этого проекта мы будем использовать пару библиотек Python:

pip3 install numpy  
pip3 install autopep8

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

С другой стороны, мы будем использовать Numpy для создания AST.

Структура папки

Внутри PyRegex мы создаем папку SRC, где мы разместим весь наш код.

Файлы __init__.py, которые вы видите, являются пустыми файлами, необходимыми Python для перемещения по проекту.

Что такое лексера

Lexer (или сканер) – это компонент, который принимает строку в качестве ввода и выводит список (массив или что-то еще) токенов, то есть категория слов, логических токенов, грамматики ».

Краткий пример:

Строка ввода:

Выход на английском языке Lexer:

Токены

Наш лексером придется распознать различные типы токенов (персонаж, скобки, скобки, побег, …).

Для этого нам сначала нужно определить иерархию типов токенов.

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

Для многих токенов я создал первый базовый класс для представления типа, а затем более специализированные для фактического символа, который мы выбираем, представляющим тип. Это не было строго необходимо, но добавляет не так много работы и может помочь вам сохранить код когерента и облегчает перегрузку типов токенов (может быть, однажды я захочу «#» быть побегом тоже по какой-то причине).

Ну наконец то лексера

Сам лексера является довольно простым компонентом.

В файле с именем LEXER.PY мы создаем класс Lexer, который будет реализовывать метод сканирования, который будет принимать строку в качестве ввода и выводит множество распознаваемых токенов.

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

Как вы можете видеть, это довольно просто. Единственными двумя сложными точками являются обработка побега, «^» и вьющиеся скобка.

Побег Чтобы обработать Escape, я создал переменную поддержки escape_found, которая устанавливается на ложь в конце каждого раза.

Когда он на самом деле находится на самом деле, переменная установлена в True и предложение продолжения немедленно после перезапуска цикла, не устанавливая его в False снова. Благодаря этому, в следующем итерации значение переменной будет правдой, что запускает конкретное условие (если escape_found).

Затем выполняется код, специфичный для условия, и, поскольку нет непрерывности, конец кода Loop достигается, и Exciet_Found установлен снова на false.

«^ ‘ Это, безусловно, самое интересное на мой взгляд, потому что реальность такова, что если вы не найдете его как первого персонажа, вы не можете быть уверены, если то, что вы нашли, является отрицанием, как в [^ abc] (I.e. Сопоставьте символ, которая является чем-то, кроме как A, B, или матч начал токен в последующем регезе, как в ^ ABC $ | ^ 012 $ .

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

Левая кудрявая скобка Когда левая кудрявая скобка «{‘соответствует, мы вводим в своего рода« подмахрамб », которая распознает квантификатор {min, Max} (с мин или максимум в итоге).

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

Потому что, если вы сможете устранить некоторые грамматические ошибки в Lexer, что довольно просто, вам не придется проверять одну и ту же ошибку снова в парсере, что уже более сложна, уменьшая (крошечный бит) сложность этого.

Как вы, наверное, отметил, Lexer – очень простой компонент для проектирования и реализации.

Сложные времена придут, как мы разработаем и внедрим парсер и даже сложнее с двигателем (и системой обратной конструкции выше).

Я надеюсь, что вам понравилось прочитать эту статью. Для этой части я думаю, что мы сделали достаточно, не стесняйтесь спрашивать мне вопросы, если для вас что-то не ясно, я буду рад ответить на любые вопросы!

Обложка изображения по 鏡飛 匙 на Бессмысленно

Как построить двигатель Regex в Python (4 часть серии)

Оригинал: “https://dev.to/lorenzofelletti/how-to-build-a-regex-engine-in-python-part-2-the-lexer-2b4n”