Программирование. Принципы и практика использования C++ Исправленное издание, стр. 87
Мы реализуем класс
Token_streamToken_streamexpression()Token_streamdouble expression(){ double left = term(); // считываем и вычисляем Терм Token t = ts.get(); // получаем следующую лексему // из потока лексем while(true) { switch(t.kind) { case '+': left += term(); // вычисляем и добавляем Терм t = ts.get(); break; case '–': left –= term(); // вычисляем и вычитаем Терм t = ts.get(); break; default: ts.putback(t); // помещаем объект t обратно // в поток лексем return left; // финал: символов + и – нет; // возвращаем ответ } }}Кроме того, такие же изменения следует внести в функцию
term()double term(){ double left = primary(); Token t = ts.get(); // получаем следующую лексему // из потока лексем while(true) { switch (t.kind) { case '*': left *= primary(); t = ts.get(); break; case '/': { double d = primary(); if (d == 0) error("деление на нуль"); left /= d; t = ts.get(); break; } default: ts.putback(t); // помещаем объект t обратно в поток лексем return left; } }}Для последней функции программы грамматического анализа
primary()get_token()ts.get()primary()6.7. Испытание второй версии
Итак, мы готовы к испытанию второй версии. Введем число
2322+223=22+2=3Хм... Может быть, наша функция
putback()expression()term()2 3 4 2+3 2*3= 2= 3= 4= 5Да! Это правильные ответы! Но последний ответ (
6Как исправить этот недостаток? Очевидное решение — потребовать немедленно выполнить вывод. Договоримся считать, что каждое выражение завершается точкой с запятой, которая одновременно служит триггером вывода. Кроме того, добавим в программу команду выхода. Для этого подходит символ
qquitmain()while (cin) cout << "=" << expression() << '\n'; // version 1Заменим ее более запутанной, но более полезной инструкцией.
double val = 0;while (cin) { Token t = ts.get(); if (t.kind == 'q') break; // 'q' для выхода if (t.kind == ';') // ';' для команды "печатать немедленно" cout << "=" << val << '\n';