C++   ::   Хилл Мюррей

Страница: 96 из 357

автора)

Функция prim, обрабатывающая primary, написана в осноном в том же духе, не считая того, что немного реальной рабты в ней все-таки выполняется, и нет нужды в цикле, поскольку мы попадаем на более низкий уровень иерархии вызовов:

double prim() // обрабатывает primary (первичные) (* switch (curr_tok) (* case NUMBER: // константа с плавающей точкой get_token(); return number_value; case NAME: if (get_token() == ASSIGN) (* name* n = insert(name_string); get_token(); n-»value = expr(); return n-»value; *) return look(name-string)-»value; case MINUS: // унарный минус get_token(); return -prim(); case LP: get_token(); double e = expr(); if (curr_tok != RP) return error(«должна быть )»); get_token(); return e; case END: return 1; default:

return error(«должно быть primary»); *) *)

При обнаружении NUMBER (то есть, константы с плавающей точкой), возвращается его значение. Функция ввода get_token() помещает значение в глобальную переменную number_value. Ипользование в программе глобальных переменных часто указывает на то, что структура не совсем прозрачна, что применялась нкоторого рода оптимизация. Здесь дело обстоит именно так. Торетически лексический символ обычно состоит из двух частей: значения, определяющего вид лексемы (в данной программе token _value), и (если необходимо) значения лексемы. У нас имеется только одна простая переменная curr_tok, поэтому для хранения значения последнего считанного NUMBER понадобилась глобальная переменная переменная number_value. Это работает только потму, что калькулятор при вычислениях использует только одно число перед чтением со входа другого.

Так же, как значение последнего встреченного NUMBER хранится в number_value, в name_string в виде символьной строки хранится представление последнего прочитанного NAME. Перед тем, как что-либо сделать с именем, калькулятор должен заглнуть вперед, чтобы посмотреть, осуществляется ли присваивание ему, или оно просто используется. В обоих случаях надо спрвиться в таблице имен. Сама таблица описывается в #3.1.3; здесь надо знать только, что она состоит из элементов вида:

srtuct name (* char* string; char* next; double value; *)

где next используется только функциями, которые поддерживают работу с таблицей:

name* look(char*); name* insert(char*);

Обе возвращают указатель на name, соответствующее парметру – символьной строке; look() выражает не�

|< Пред. 94 95 96 97 98 След. >|

Java книги

Контакты: [email protected]