5.2 Использование переменных |
Предыдущая Содержание Следующая |
Переменная принимает участие в двух операциях: её значение используется в качестве операнда в выражении, или ей присваивается значение выражения. Первая операция представляет собой простое расширение компонента factor() распознавателя, показанного в разделе 3.5.
static void * factor (void) { void * result; ... switch (token) { case VAR: result = symbol; break; ...
VAR представляет собой уникальное значение, которое screen() помещает в token, когда найден подходящий идентификатор. Дополнительная информация о идентификаторе помещается в глобальную переменную symbol. В этом случае символ содержит узел для представления переменной, подобно листу в дереве выражений. screen() либо находит переменную в таблице символов, либо использует для его создания описание Var. Распознавание присвоения несколько сложнее. Наш калькулятор будет удобен в использовании, если мы допустим два вида операторов со следующим синтаксисом:
asgn : sum | VAR = asgn
К сожалению, VAR может также появиться в левой части суммы, то есть не сразу понятно, как нашей техникой рекурсивного спуска распознать встроенный в C стиль присваивания. (* Существует трюк: просто выполнять проверку для суммы. Если при возвращении следующий входной символ это =, сумма должна быть листовым узлом для переменной и можно построить присвоение.) Поскольку вообще-то мы хотим узнать, как иметь дело с ключевыми словами, то соглашаемся со следующей грамматикой:
stmt : sum | LET VAR = sum
Это переводится в следующую функцию:
static void * stmt (void) { void * result;
switch (token) { case LET: if (scan(0) != VAR) error("bad assignment"); result = symbol; if (scan(0) != ’=’) error("expecting ="); scan(0); return new(Assign, result, sum()); default: return sum(); } }
В основной программе вместо sum() вызываем stmt() и наша распознаватель готов обрабатывать переменные. Assign — это новое описание типа для узла, который вычисляет значение суммы и присваивает его переменной.
|
Предыдущая Содержание Следующая |