Операционная система UNIX. Руководство программиста

     

Секция определений


Секция определений может содержать конструкции разных видов, самыми важными из которых являются описания внешних объектов, операторы #include и сокращения. Напомним, что в принципе данная секция необязательна, однако в большинстве случаев некоторые определения необходимы. Описания внешних объектов имеют те же форму и смысл, что и в языке C. Они означают, что переменные, глобально определенные где-то в другом месте (возможно, в другом исходном файле), будут доступны в сгенерированной lex-программе a.out. Рассмотрим определение из примера, который обсуждается ниже:

extern int tokval;

Целочисленное значение, присвоенное переменной, определенной таким образом, будет доступно в функции, вызывающей лексический анализатор, скажем, в функции разбора. Если, с другой стороны, нужно описать локальную переменную для использования в пределах последовательности действий из одного правила (например, управляющую переменную цикла), ее описание можно поместить в начале самого действия, справа от открывающей скобки, {.

Назначение оператора #include - то же, что и в языке C: включать в программу нужные файлы. Некоторые описания могут требоваться более чем в oодном исходном lex-файле, поэтому предпочтительно поместить их в один файл, включаемый в нужных случаях. Примером может служить использование lex'а совместно с yacc(1), который генерирует функции разбора, вызывающие лексический анализатор. В такой ситуации следует включать файл y.tab.h, поскольку он может содержать операторы #define для имен лексем. Подобно описаниям, операторы #include должны содержаться между скобками %{ и %}:

%{ #include "y.tab.h" extern int tokval; int lineno; %}

В секции определений после разделителя %}, который завершает описания и операторы #include, можно поместить сокращения для регулярных выражений, используемые в секции правил. В левой части строки указывается сокращение, а в правой, отделенной одним или несколькими пробелами, - его описание. Сокращения, используемые в правилах, обязательно должны быть заключены в фигурные скобки.


Примечание

Назначение сокращений - избежать излишних повторов при написании спецификаций и улучшить их читаемость.

В качестве примера вернемся к lex-спецификации, рассмотренной в начале раздела Более сложные элементы lex'а. Использование сокращений упрощает последующие ссылки на цифры, буквы и пробелы. Сокращения особенно полезны, когда они встречаются в правилах несколько раз.

D [0-9] L [a-zA-Z] B [ ] %% -{D}+ printf("отрицательное число"); \+?{D}+ printf("положительное число"); -0\.{D}+ printf("отрицательная дробь"); G{L}* printf("G-слово"); rail{B}+road printf("railroad - одно слово"); crook printf("не положено"); \"\./{B}+ printf(".\""); . . . . . .

Применение последнего правила, несколько более сложного, чем остальные, гарантирует, что в конце предложения точка окажется перед кавычкой. Так, example". будет заменено на example."




Содержание раздела