Определения, предназначенные для LEX, помещаются перед первым %%
.
Любая строка этой секции, не содержащаяся между
%START имя1 имя2 ...
Если начальные условия определены, то эта строка должна быть первой
в LEX-программе.
Непосредственно определения задаются в форме:
имя трансляция
В качестве разделителя используется один или более пробелов или табуляций.
Имя (name) - это, как обычно, любая последовательность букв и цифр,
начинающаяся с буквы. Трансляция (translation) - это регулярное выражение
(или его часть), которое будет подставлено всюду, где указано
имя. Пример:
БУКВА [A-ZА-Яa-zа-я_]
ЦИФРА [0-9]
ИДЕНТИФИКАТОР {БУКВА}({БУКВА}|{ЦИФРА})*
%%
{ИДЕНТИФИКАТОР} printf("\n%s",yytext);
. . .
LEX построит ЛА, который будет находить и выводить все идентификаторы
Си-программы из входного файла. В этом примере
ИДЕНТИФИКАТОР
заменит БУКВА(БУКВА
|ЦИФРА)
, затем на
A-ZА-Яa-zа-я(A-ZА-Яa-zа-я
|0-9)
.
yytext
- это внешний массив символов программы lex.yy.c
, которую строит
LEX; yytext
формируется в процессе чтения входного файла и содержит
текст, для которого установлено соответствие какому-либо выражению.
Этот массив доступен пользовательским разделам LEX-программы. Функция
printf
выводит каждый идентификатор на новой строке.
Фрагменты пользовательских подпрограмм вводятся двумя способами:
отступ фрагмент;
или
%{
фрагмент
%}
Включение пользовательского фрагмента необходимо, например, для ввода
макроопределений Си, которые должны начинаться в первой колонке строки.
Все строки фрагмента пользовательской подпрограммы, размещенные в
разделе определений, будут внешними для любой функции lex.yy.c
.
Таблица наборов символов задается в виде:
%T
целое_число строка_символов
. . .
целое_число строка_символов
%T
Сгенерированная программа lex.yy.c
осуществляет ввод/вывод символов
посредством библиотечных функций LEX с именами input
,
output, unput
.
Таким образом, LEX помещает в массив yytext
символы в представлении,
используемом в этих библиотечных функциях. Для внутреннего использования
символ представляется целым числом, значение которого образовано набором
битов, представляющих символ в конкретной ЭВМ. Пользователю представляется
возможность менять представление символов (целых констант) с помощью
таблицы наборов символов. Если таблица символов присутствует в разделе
определений, то любой символ, появляющийся либо во входном потоке,
либо в правилах, должен быть определен в таблице символов. Символам
нельзя назначать число 0 и число, большее числа, выделенного для внутреннего
представления символов конкретной ЭВМ. Пример:
%T
1 Aa
2 Bb
3 Cc
.
.
.
26 Zz
27 \n
28 +
29 -
30 0
31 1
.
.
.
39 9
%T
Здесь символы верхнего и нижнего регистров переводятся в числа 1 -
26, символ новой строки - в число 27, + и - переводятся в числа 28
и 29, а цифры - в числа 30 - 39.
Указатель хост-языка имеет вид:
%C
для языка Си. Для других языков программирования, например Фортрана,
указатель выглядит соответственно. Если указатель хост-языка отсутствует,
то по умолчанию принимается Си.
Изменения размеров внутренних массивов задаются в форме:
%x число
Число - новый размер массива, x - одна из букв: p - позиции (positions),
n - состояния (states), e - узлы дерева разбора (parse tree nodes),
a - упакованные переходы (transitions), k - упакованные классы символов
(packet character classes), o - массив выходных элементов (output
array). LEX имеет внутренние таблицы, размеры которых ограничены.
При построении программы лексического анализа может произойти переполнение
любой из этих таблиц, о чем LEX сообщит при построении ЛА. Представляется
возможность изменить размеры этих таблиц (сокращая размеры одних и
увеличивая размеры других) таким образом, чтобы они не переполнялись.
Естественно, эти изменения возможны лишь в пределах той памяти, которая
выделяется под процесс. Ниже перечислены размеры таблиц, которые устанавливаются
по умолчанию: p - 1500 позиций, n - 300 состояний, e - 600 узлов,
a - 1500 упакованных переходов, k - 1000 упакованных классов символов,
o - 1500 выходных элементов. Для того чтобы определить, каковы размеры
таблиц и насколько они заняты, можно использовать флаг -v
при вызове
команды lex
. Число перед / показывает сколько элементов массива занято,
а число за / показывает установленный размер массива.
Комментарии в разделе определений задаются в форме хост-языка и должны начинаться не с первой колонки строки.