Lex — это компьютерная программа , которая генерирует лексические анализаторы («сканеры» или «лексеры»). [1] [2] Она обычно используется с генератором парсеров yacc и является стандартным генератором лексических анализаторов во многих Unix и Unix-подобных системах. Эквивалентный инструмент указан как часть стандарта POSIX . [3]
Lex считывает входной поток, указывающий лексический анализатор, и пишет исходный код , реализующий лексический анализатор на языке программирования C.
Помимо C, некоторые старые версии Lex могли генерировать лексер в Ratfor . [4]
Lex был первоначально написан Майком Леском и Эриком Шмидтом [5] и описан в 1975 году. [6] [7] В последующие годы Lex стал стандартным генератором лексических анализаторов на многих Unix и Unix-подобных системах. В 1983 году Lex был одним из нескольких инструментов UNIX, доступных для операционной системы UNOS компании Charles River Data Systems по лицензии Bell Laboratories . [8] Хотя изначально Lex распространялся как проприетарное программное обеспечение, некоторые версии Lex теперь имеют открытый исходный код . Версии Lex с открытым исходным кодом, основанные на оригинальном проприетарном коде, теперь распространяются с операционными системами с открытым исходным кодом, такими как OpenSolaris и Plan 9 от Bell Labs . Одна популярная версия Lex с открытым исходным кодом, называемая flex , или «быстрый лексический анализатор», не является производной от проприетарного кодирования.
Структура файла Lex намеренно похожа на структуру файла yacc: файлы делятся на три раздела, разделенные строками, содержащими только два знака процента, как показано ниже:
Ниже приведен пример файла Lex для гибкой версии Lex. Он распознает строки чисел (положительные целые числа) во входных данных и просто выводит их.
/*** Раздел определений ***/% { /* Код C, который необходимо скопировать дословно */ #include <stdio.h> % } %% /*** Раздел правил ***/ /* [0-9]+ соответствует строке из одной или нескольких цифр */ [ 0-9 ] + { /* yytext — это строка, содержащая совпадающий текст. */ printf ( "Увидел целое число: %s \n " , yytext ); } . | \ n { /* Игнорировать все остальные символы. */ } %% /*** Раздел кода C ***/int main ( void ) { /* Вызвать лексер, затем выйти. */ yylex (); return 0 ; }
Если этот ввод задан в flex
, он будет преобразован в файл C, . Это может быть скомпилировано в исполняемый файл, который сопоставляет и выводит строки целых чисел. Например, учитывая ввод: lex.yy.c
abc123z.!&*2gj6
программа выведет на печать:
Увидел целое число: 123Увидел целое число: 2Увидел целое число: 6
Lex, как и другие лексические анализаторы, ограничивает правила теми, которые можно описать регулярными выражениями . Благодаря этому Lex может быть реализован конечным автоматом, как показано в иерархии языков Хомского . Для распознавания более сложных языков Lex часто используется с генераторами синтаксических анализаторов, такими как Yacc или Bison . Генераторы синтаксических анализаторов используют формальную грамматику для разбора входного потока.
Обычно предпочтительнее, чтобы парсер, например, сгенерированный Yacc, принимал поток токенов («токен-поток») в качестве входных данных, а не обрабатывал поток символов («символ-поток») напрямую. Lex часто используется для создания такого токена-потока.
Синтаксический анализ без сканера подразумевает прямой анализ входного потока символов без отдельного лексического анализатора.
make — это утилита, которая может использоваться для поддержки программ, включающих Lex. Make предполагает, что файл с расширением .l
является исходным файлом Lex. Внутренний макрос make LFLAGS
может использоваться для указания параметров Lex, которые будут автоматически вызываться программой make. [9]