|
Программирование >> Формирование пользовательского контейнера
390 /лада© или идентификатором, if(token type == TEMP) { tok = look up(token); преобразует во внутреннюю форму if(tok) token type = KEYWORD; ключевое слово else token type = IDENTIFIER; Проверяет неидентифицированный символ в файле, if(token type == UNDEFTT) throw InterpExc(SYNTAX); return token type; Функция get token() начинается с пропуска всех пробелов, табуляций, пустых строк, возвратов каретки и переводов строки. Поскольку ни одна лексема не содержит пробелов (за исключением строки в кавычках и символьной константы), их следует игнорировать. Функция get token () также пропускает комментарии. Затем читается очередная лексема из программы. Обратите внимание на то, как обрабатывается каждый тип лексемы. Например, если очередной символ в программе - цифра, читается число; если следующий символ - буква, извлекается идентификатор или ключевое слово, и т. д. Строковое представление лексемы помещается в переменную token. Прочитанный тип лексемы (в соответствии с именем, указанным в перечислимом типе tok types) передается переменной token type. и если лексема - ключевое слово, ее внутреннее представление (в соответствии с наименованием, приведенным в перечислимом типе token ireps) присваивается переменной tok с помощью функции iook up() (необходимость представления ключевых слов во внутреннем формате будет объяснена позже). Как видите, функция get token() преобразует двухсимвольные знаки операций языка С++, такие как <= или ++, в соответствующие значения перечислимого типа. Хотя в этом нет технической необходимости, подобный шаг упрощает реализацию интерпретатора. Вывод синтаксических ошибок Если анализатор обнаруживает синтаксическую ошибку, он генерирует исключение типа InterpExc, задающее значение перечислимого типа, соответствующее типу найденной ошибки (другие части интерпретатора Mini С++ также используют класс mterpExc для сообщений об ошибках). Обработчик исключения mterpExc включбн в функцию main () - часть основного файла интерпретатора minicpp.cpp, который будет описан позже. Этот обработчик для сооб1 1ения об ошибке вызывает функцию sntx err (), приведенную далее. Отображает сообщение об ошибке, void sntx: err(error jnsg error) { char *p, *tenp; int linecount = 0; static char *e[]= { Syntax error , No expression present , Not a variable , Duplicate variable name , Duplicate function name . Semicolon expected , Unbalanced braces , Function undefined , Type specifier eэфected , Return without call , Parentheses expected , , While expected , Closing quote expected , Division by zero , eэфected (control statements must use blocks) , Colon expected Выводит ошибку и номер строки, cout \n е[errorJ; p = p buf; while(p != prog) { находит номер строки с ошибкой Р++; if(*Р == -Nr) { linecount++; cout in line linecount endl; temp = p; While (р > p buf && *р != \n) р~; Отображает ошибочную строку, while(р <= temp) cout *р++; cout endl; Обратите внимание, функция sntx err () отображает строку, описывающую ошибку и номер строки кода, в которой обнаружена ошибка (он может указывать на строку, следующую за той, в которой ошибка действительно имела место). Функция также выводит на экран содержимое строки с ошибкой. Вычисление выражения Порохшающие правила в интерпретаторе Mini С++ реализованы с помощью функций, имена которых начинаются со строки eval exp, и функции atomo. Для того чтобы лучшб понять, как анализатор вычисляет выражения, обработаем следующее выражение (предположим, что переменная prog указывает на начало этого выражения): 10 - 3 * 2. Когда функция evai exp () (точка входа в анализатор) вызывается, она получает первую лексему. Если эта лексема Нулевой длины или пустая (null), генерируется исключение, указывающее на отсутствие выражения. Но в данном случае лексема содержит число 10. Следовательно, она не пустая, и вызывается функция evai expO(), которая ищет операцию присваивания. Поскольку такой операции нет, вызывается функция evai expi(), вызывающая в свою очередь функцию eval exp2 (). Далее eval exp2 () вызывает функцию eval exp3 (), а та - функцию eval exp4 (). Функция eval exp4 () обрабатывает унарные + и -, а также префиксные формы инкремента ++ и декремента -. Затем она вызывает функцию evai exp5(). В этой точке функция evai exp5() также рекурсивно вызывает функцию evai expO() (если выражение заключено в круглые скобки) или функцию atom о для получения значения. Поскольку лексема не содержит открывающую круглую скобку, выполняется функция atom о и переменной value присваивается значение 10. Затем извлекается следующая лексема, и начинаются возвраты из функций вверх по цепочке. Текущая лексема - знак операции - (минус), и возвраты из функций продолжаются до функции eval exp2 (). То, что происходит далее, очень важно. Поскольку лексема содержит -, он сохраняется в переменной ор. После этого анализатор получает следующую
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |