[ Содержание ] [ Предыдущая ] [ Следующая ]

Глава 3. Лексический анализ

    Пользователь должен предоставить лексический анализатор для чтения входных данных и передавать токены (со значениями, если надо) парсеру. Лексический анализатор - это функция типа integer, называемая yylex. Функция возвращает целое число, номер токена, представляющий вид прочитанного токена. Если с этим токеном связано значение, оно должен быть присвоено внешней переменной yylval.

     Парсер и лексический анализатор должны договориться о номерах токенов, для того, чтобы между ними была связь. Эти номера могут быть выбраны Yacc-ом или пользователем. В обоих случаях, механизм #define используется, чтобы позволить лексическому анализатору возвращать эти номера в символическом виде. Hапример, предположим, что токен DIGIT был определен в секции объявлений файла спецификаций Yacc-а. Соответсвующая часть лексического анализатора может выглядеть как:

yylex() { extern int yylval; int c; . . . c = getchar(); . . . switch (c) { . . . case '0': case '1': . . . case '9': yylval = c - '0'; return DIGIT; . . . } . . . }

    Hазначение этого - вернуть номер токена DIGIT и значение, равное численному значению цифры. При условии, что код лексического анализатора помещен в секцию программ файла спецификаций Yacc-а, идентификатор DIGIT будет определен как номер токена, связанный с токеном DIGIT.

     Этот механизм обеспечивает ясные, легко изменяемые лексические анализаторы; единственная ловушка - необходимость избегать использования в грамматике любых имен токенов, зарезервированных или значимых в C или парсере, например, использование токенов if или while, почти обязательно вызовет сильные трудности при компиляции лексического анализатора. Имя токена error зарезервировано для обработки ошибок и не должно использоваться наивно (смотрите главу 7).

     Как упоминалось выше, имена токенов могут выбираться Yacc-ом или пользователем. По умолчанию номера выбираются Yacc-ом. Hомера токенов для буквенных символов по умолчанию - это численные значения символа в локальном наборе символов. Остальным именам присваиваются номера токенов, начиная с 257.

     Чтобы присвоить токену (включая литералу) номер, за первым появлением имени токена или литерала в секции объявлений должно немедленно следовать неотрицательное целое число. Это целое берется в качестве номера токена для имени или литерала. Имена и литералы, не определенные с помощью этого механизма, сохраняют свои определения по умолчанию. Важно, чтобы все номера токенов различались.

     По историческим причинам, маркер конца должен иметь номером токена 0 или отрицательное число. Этот номер токена не может быть переопределен пользователем; таким образом, все лексические анализаторы должны быть написаны так, чтобы возвращать 0 или отрицательное число при достижении конца своих входных данных.

     Очень полезное средство для построения лексических анализаторов - программа Lex, разработанная Mike Lesk [8]. Эти лексические анализаторы приспособленны для работы в гармонии с парсерами Yacc-а. Спецификации для этих лексических анализаторов использую регулярные выражения вместо грамматических правил. Lex может легко использоваться для построения достаточно сложных лексических анализаторов, но остаются некоторые языки (такие как FORTRAN), которые не соответсвуют ни одной теоретической схеме, и чью лексические анализаторы должны создаваться вручную.

[ Содержание ] [ Предыдущая ] [ Следующая ]



c 1998-2000 SoloTony (Antonio Solo) solotony@mail.ru