Введение

Программа UNIX для лексического анализа. Flex (быстрый генератор лексических анализаторов) — это бесплатная программа с открытым исходным кодом, являющаяся альтернативой lex. Это компьютерная программа, генерирующая лексические анализаторы (также известные как "сканеры" или "лексеры"). Она часто используется в качестве реализации lex совместно с генератором парсеров Berkeley Yacc в операционных системах, основанных на BSD (поскольку lex и yacc входят в состав POSIX), или совместно с GNU bison (версией yacc) в портах *BSD и дистрибутивах Linux. В отличие от Bison, flex не входит в проект GNU и не распространяется под лицензией GNU General Public License, хотя руководство пользователя для Flex было создано и опубликовано Фондом свободного программного обеспечения.

Внутренние

Эти программы выполняют разбор символов и токенизацию с использованием детерминированного конечного автомата (DFA). DFA — это теоретическая машина, распознающая регулярные языки. Эти машины являются подмножеством множества машин Тьюринга. DFA эквивалентны машинам Тьюринга, читающим только вправо. Синтаксис основан на использовании регулярных выражений. См. также недетерминированный конечный автомат.

Временная сложность

Лексический анализатор Flex обычно имеет временную сложность, линейную от длины входных данных. То есть, он выполняет постоянное количество операций для каждого входного символа. Эта константа достаточно мала: GCC генерирует 12 инструкций для цикла сопоставления DFA. Важно отметить, что эта константа не зависит от длины токена, длины регулярного выражения и размера DFA. Однако использование макроса REJECT в сканере, способном сопоставлять чрезвычайно длинные токены, может привести к генерации Flex сканера с нелинейной производительностью. Эта возможность является необязательной. В этом случае программист явно указывает Flex "вернуться и попробовать снова" после того, как часть входных данных уже была сопоставлена. Это заставит DFA выполнить возврат к предыдущим состояниям для поиска других принимающих состояний. Макрос REJECT не включен по умолчанию, и из-за его влияния на производительность его использование не рекомендуется в документации Flex.

Возвращение

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

Использование в средах, не относящихся к Unix

Обычно генерируемый сканер содержит ссылки на заголовочный файл unistd.h, который является специфичным для Unix. Чтобы избежать генерации кода, включающего unistd.h, следует использовать опцию `%option nounistd`. Другая проблема – вызов функции isatty (библиотечной функции Unix), который также встречается в генерируемом коде. Опция `%option never-interactive` заставляет flex генерировать код, не использующий isatty.

Использование флекса из других языков

Flex может генерировать код только для языков C и C++. Для использования кода сканера, сгенерированного Flex, в других языках программирования можно использовать инструмент для создания языковых привязок, например SWIG.

Поддержка Unicode

Flex ограничивается сопоставлением 1-байтовых (8-битных) двоичных значений и, следовательно, не поддерживает Unicode. RE/flex и другие альтернативы поддерживают сопоставление с использованием Unicode.

Flex++

flex++ — это аналогичный лексический сканер для C++, который входит в состав пакета flex. Сгенерированный код не зависит ни от каких библиотек времени выполнения или внешних библиотек, за исключением распределителя памяти (malloc или альтернативы, предоставленной пользователем), если только входные данные от него не зависят. Это может быть полезно во встраиваемых и подобных системах, где традиционные операционные системы или библиотеки времени выполнения C могут быть недоступны. Сгенерированный flex++ C++ сканер включает в себя заголовочный файл FlexLexer.h, который определяет интерфейсы двух сгенерированных C++ классов.