Программирование. Принципы и практика использования C++ Исправленное издание, стр. 103
double declaration() // предполагается, что мы можем выделить ключевое слово "let" // обработка: name = выражение // объявляется переменная с именем "name" с начальным значением, // заданным "выражением"{ Token t = ts.get(); if (t.kind != name) error ("в объявлении ожидается переменная name"); string var_name = t.name; Token t2 = ts.get(); if (t2.kind != '=') error("в объявлении пропущен символ =", var_name); double d = expression(); define_name(var_name,d); return d;}Обратите внимание на то, что мы возвращаем значение, хранящееся в новой переменной. Это полезно, когда инициализирующее выражение является нетривиальным. Рассмотрим пример.
let v = d/(t2–t1);Это объявление определяет переменную
vcalculate()statement()Описанный механизм отслеживания переменных часто называют таблицей символов (symbol tables). Его можно радикально упростить с помощью стандартной библиотеки
map7.8.2. Использование имен
Все это очень хорошо, но, к сожалению, не работает. Это не должно было стать для нас сюрпризом. Первый вариант никогда — почти никогда — не работает. В данном случае мы даже не закончили программу — она даже не скомпилируется. У нас нет лексемы
'='caseToken_stream::get()letnameget()const char name = 'a'; // лексема nameconst char let = 'L'; // лексема letconst string declkey = "let"; // ключевое слово letToken Token_stream::get(){ if (full) { full=false; return buffer; } char ch; cin >> ch; switch (ch) { // как и прежде default: if (isalpha(ch)) { cin.putback(ch); string s; cin>>s; if (s == declkey) return Token(let); // ключевое слово let return Token(name,s); } error("Неправильная лексема"); }}В первую очередь обратите внимание на вызов функции
isalpha(ch)chisalpha()std_lib_facilities.hputback()>>К сожалению, этот код не компилируется; класс
TokenToken(name,s)Tokenclass Token {public: char kind; double value; string name; Token(char ch):kind(ch), value(0) { } Token(char ch, double val) :kind(ch), value(val) { } Token(char ch, string n) :kind(ch), name(n) { }};Для представления лексемы
let'L'doublevar#declkeysПопытаемся снова протестировать программу. Если напечатать следующие выражения, то легко убедиться, что программа работает:
let x = 3.4;let y = 2;x + y * 2;Однако следующие выражения показывают, что программа еще не работает так, как надо:
let x = 3.4;