Программирование. Принципы и практика использования C++ Исправленное издание, стр. 95
вызывает ошибку Ожидается первичное выражение. Где следует искать эту ошибку? Конечно, в функции
main()double val = 0;while (cin) { cout << "> "; Token t = ts.get(); if (t.kind == 'q') break; if (t.kind == ';') cout << "= " << val << '\n'; else ts.putback(t); val = expression();}Если обнаруживаем точку с запятой, то вызываем функцию
expression()qterm()primary()main()int main()try{ while (cin) { cout << "> "; Token t = ts.get(); while (t.kind == ';') t=ts.get(); // считываем ';' if (t.kind == 'q') { keep_window_open(); return 0; } ts.putback(t); cout << "= " << expression() << endl; } keep_window_open(); return 0;}catch (exception& e) { cerr << e.what() << endl; keep_window_open("~~"); return 1;}catch (...) { cerr << "exception \n"; keep_window_open("~~"); return 2;}Это повышает надежность обработки ошибок. Таким образом, теперь можно искать новые пути улучшения калькулятора.
7.4. Отрицательные числа
Проверив калькулятор, легко убедиться, что он не слишком элегантно обрабатывает отрицательные числа. Например, выражение
–1/2является ошибочным.
Для того чтобы калькулятор работал корректно, мы должны были бы написать
(0–1)/2Однако это неприемлемо.
В данном случае необходимо внести исправления в грамматику, чтобы предусмотреть унарный минус. На первый взгляд легче всего внести исправления в пункт Первичное выражение. Сейчас он выглядит так:
Первичное выражение: Число "("Выражение")"Нам требуется, чтобы этот пункт выглядел примерно таким образом:
Первичное выражение: Число "("Выражение")" "–" Первичное выражение "+" Первичное выражениеМы добавили унарный плюс, поскольку он есть в языке С++. Если есть унарный минус, то легче реализовать унарный плюс, чем объяснить его бесполезность. Код, реализующий Первичное выражение, принимает следующий вид:
double primary(){ Token t = ts.get(); switch (t.kind) { case '(': // обработка пункта '(' выражение ')' { double d = expression(); t = ts.get(); if (t.kind != ')') error("')' expected"); return d; } case '8': // символ '8' используется для представления числа return t.value; // возвращаем число case '–': return – primary();