Шрифт:
double var = 7.2;
Это работает, но все переменные в данном калькулятора и так хранят значения типа
double
, поэтому явно указывать этот тип совершенно не обязательно. Можно было бы написать проще.
var = 7.2;
Что ж, возможно, но теперь мы не можем отличить определение новой переменной от синтаксической ошибки.
var1 = 7.2; // определение новой переменной с именем var1
var1 = 3.2; // определение новой переменной с именем var2
Ой! Очевидно, что мы имели в виду
var2 = 3.2;
но не сказали об этом явно (за исключением комментария). Это не катастрофа, но будем следовать традициям языков программирования, в частности языка С++, в которых объявления переменных с их инициализацией отличаются от присваивания. Мы можем использовать ключевое слово double
, но для калькулятора нужно что-нибудь покороче, поэтому — следуя другой старой традиции — выбрали ключевое слово let
.
let var = 7.2;
Грамматика принимает следующий вид:
Вычисление:
Инструкция
Печать
Выход
Инструкция вычисления
Инструкция:
Объявление
Выражение
Объявление:
"let" Имя "=" Выражение
Вычисление — это новое правило вывода в грамматике. Оно выражает цикл (в функции
calculate
), который позволяет выполнять несколько вычислений в ходе одного сеанса работы программы. При обработке выражений и объявлений это правило опирается на правило Инструкция. Например, инструкцию можно обработать следующим образом:
double statement
{
Token t = ts.get;
switch (t.kind) {
case let:
return declaration;
default:
ts.putback(t);
return expression;
}
}
Вместо функции
expression
в функции calculate
можем использовать функцию statement
.
void calculate
{
while (cin)
try {
cout << prompt;
Token t = ts.get;
while (t.kind == print) t=ts.get; // игнорируем
"печать"
if (t.kind == quit) return; // выход
ts.putback(t);
cout << result << statement << endl;
}
catch (exception& e) {
cerr << e.what << endl; // выводим сообщение об ошибке
clean_up_mess;
}
}
Теперь необходимо написать функцию
declaration
. Что следует сделать? Нужно убедиться, что после ключевого слова let
следует Имя, а за ним — символ = и Выражение. Именно это утверждает грамматика. Что делать с членом name
? Мы должны добавить в вектор var_table
типа vector<Variable>
объект класса Variable
c заданными строкой name и значением выражения. После этого мы сможем извлекать значения с помощью функции get_value
и изменять их с помощью функции set_value
. Однако сначала надо решить, что случится, если мы определим переменную дважды. Рассмотрим пример.
let v1 = 7;
let v1 = 8;
Мы решили, что повторное определение является ошибкой. Обычно это просто синтаксическая ошибка. Вероятно, мы имели в виду не то, что написали, а следующие инструкции:
let v1 = 7;
let v2 = 8;
Определение объекта класса
Variable
с именем var
и значением val
состоит из двух логических частей.