# flex

Быстрый генератор лексических анализаторов, который создаёт программы на языке C для распознавания лексических шаблонов в тексте. Он используется совместно с генераторами парсеров (такими как Bison) для создания полных компиляторов, интерпретаторов и других инструментов обработки текста. Flex преобразует пользовательские шаблоны лексем в эффективный детерминированный конечный автомат (DFA).

## Особенности

- высокая производительность лексического анализа за счет оптимизированных таблиц переходов;
- гибкая система шаблонов с поддержкой регулярных выражений;
- интеграция с генераторами парсеров (Bison/Yacc);
- поддержка работы с потоками ввода/вывода и буферизацией;
- возможность создания реентерабельных (потокобезопасных) лексических анализаторов;
- портируемость между различными платформами и операционными системами.

## Основные компоненты

Flex состоит из нескольких ключевых компонентов, которые позволяют определять лексические правила и генерировать эффективные лексические анализаторы (подробнее ознакомиться с документацией можно [здесь](https://westes.github.io/flex/manual/)).

### Регулярные выражения и шаблоны

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

Основные элементы шаблонов:

- Литеральные символы и строки для точного совпадения;
- Классы символов (`[a-z]`, `[^0-9]`);
- Управляющие последовательности (`\n`, `\t`, `\x20`);
- Квантификаторы (`*`, `+`, `?`, `{n,m}`);
- Группировка и альтернативы `(abc|def)`;
- Начало и конец строки (`^`, `$`);
- Контекстно-зависимые правила (использование состояний).

### Управление состояниями

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

Функции управления состояниями:

- Объявление состояний: `%x STATE_NAME` (эксклюзивное) или `%s STATE_NAME` (включительное);
- Активация состояния: `BEGIN(STATE_NAME)`;
- Возврат к предыдущему состоянию: `BEGIN(INITIAL)`;
- Условное выполнение правил в зависимости от состояния.

### Взаимодействие с парсерами

Flex предназначен для совместного использования с генераторами парсеров, такими как Bison. Он предоставляет механизмы для передачи токенов и их значений парсеру.

Ключевые аспекты интеграции:

- Объявление токенов с помощью `%token` в Bison и их использование в Flex;
- Глобальная переменная `yylval` для передачи значения токена;
- Функция `yylex()` как точка входа лексического анализатора;
- Макрос `YYSTYPE` для определения типа значений токенов;
- Возвращение кода токена из действий Flex.

### Встроенные функции и переменные

Flex предоставляет набор встроенных функций и переменных для управления процессом лексического анализа и взаимодействия с окружением.

Основные встроенные элементы:

- `yytext` — указатель на совпавшую строку;
- `yyleng` — длина совпавшей строки;
- `yyin` — входной поток (FILE*);
- `yyout` — выходной поток (FILE*);
- `yylex()` — основная функция лексического анализа;
- `yyrestart(FILE*)` — сброс анализатора на новый поток;
- `yymore()` — добавление следующего совпадения к текущему `yytext`;
- `yyless(n)` — возврат части совпавшей строки во входной поток;
- `ECHO` и `REJECT` — специальные действия.

### Генерация и использование анализаторов

Процесс создания и использования лексического анализатора включает несколько этапов: написание спецификации, генерация кода, компиляция и интеграция с основной программой.

Рабочий процесс:

1. Создание файла спецификации `.l` с правилами и действиями;
2. Генерация C-кода: `flex input.l` → `lex.yy.c`;
3. Компиляция сгенерированного кода вместе с программой;
4. Вызов `yylex()` для начала лексического анализа;
5. Обработка возвращаемых токенов и значений.

### Расширенные возможности

Flex предоставляет дополнительные возможности для создания более сложных и эффективных лексических анализаторов.

Расширенные функции:

- Создание реентерабельных лексических анализаторов с помощью `%option reentrant`;
- Настройка размера буферов и таблиц для оптимизации памяти;
- Использование собственных функций ввода/вывода;
- Генерация отладочной информации с `%option debug`;
- Поддержка юникода через широкие символы (`%option 8bit`, `%option wchar`);
- Классы символов с пользовательскими именами.
