Чтение онлайн

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

double expression

{

double left = term; // считываем и вычисляем Терм

Token t = get_token; // получаем следующую лексему

while(true) {

switch(t.kind) {

case '+':

left += term; // вычисляем Терм и добавляем его

t = get_token;

break;

case '–':

left –= term; // вычисляем Терм и вычитаем его

t = get_token;

break;

default:

return left; //
финал: символов + и – нет;

// возвращаем ответ

}

}

}

Обратите внимание на то, что — за исключением цикла — этот вариант напоминает первый (см. раздел 6.5.2.1). Мы просто удалили вызов функции

expression
в функции
expression
и заменили его циклом. Другими словами, перевели Выражение в грамматическом правиле в цикл поиска Терма, за которым следует символ + или .

6.5.3. Термы

Грамматическое правило для Терма очень похоже на правило для Выражения.

Терм:

Первичное выражение

Терм '*' Первичное выражение

Терм '/' Первичное выражение

Терм '%' Первичное выражение

Следовательно, программный код также должен быть похож на код для Выражения. Вот как выглядит его первый вариант:

double term

{

double left = primary;

Token t = get_token;

while(true) {

switch (t.kind) {

case '*':

left *= primary;

t = get_token;

break;

case '/':

left /= primary;

t = get_token;

break;

case '%':

left %= primary;

t = get_token;

break;

default:

return left;

}

}

}

К сожалению, этот код не компилируется: операция вычисления остатка (
%
) для чисел с плавающей точкой не определена. Компилятор вежливо предупредит нас об этом. Когда мы утвердительно ответили на вопрос 5 из раздела 6.3.5 — “Следует ли позволить ввод чисел с плавающей точкой?”, — мы не думали о таких последствиях и просто поддались искушению добавить в программу дополнительные возможности. Вот так всегда! Что же делать? Можно во время выполнения программы проверить, являются ли оба операнда операции
%
целыми числами, и сообщить об ошибке, если это не так. А можно просто исключить операцию
%
из возможностей нашего калькулятора. Эту функцию всегда можно добавить позднее (см. раздел 7.5). Исключив операцию
%
, получим вполне работоспособную функцию: термы правильно распознаются
и вычисляются. Однако опытный программист заметит нежелательную деталь, которая делает функцию
term
неприемлемой. Что произойдет, если ввести выражение
2/0
? На нуль делить нельзя. Если попытаться это сделать, то аппаратное обеспечение компьютера обнаружит это и прекратит выполнение программы, выдав сообщение об ошибке. Неопытный программист обязательно столкнется с этой проблемой. По этой причине лучше провести проверку и выдать подходящее сообщение.

double term

{

double left = primary;

Token t = get_token;

while(true) {

switch (t.kind) {

case '*':

left *= primary;

t = get_token;

break;

case '/':

{ double d = primary;

if (d == 0) error("деление на нуль");

left /= d;

t = get_token;

break;

}

default:

return left;

}

}

}

Почему мы поместили обработку операции

/
внутри блока? На этом настоял компилятор. Если мы хотим определить и инициализировать переменные в операторе
switch
, то должны поместить ее в блоке.

6.5.4. Первичные выражения

Грамматическое правило для первичных выражений также простое.

Первичное выражение:

Число

'('Выражение')'

Программный код, реализующий это правило, немного сложен, поэтому он открывает больше возможностей для синтаксических ошибок.

double primary

{

Token t = get_token;

switch (t.kind) {

case '(': // обработка варианта '('выражение')'

{ double d = expression;

t = get_token;

if (t.kind != ')') error("')' expected");

return d;

}

case '8': // используем '8' для представления числа

return t.value; // возвращаем значение числа

default:

error("ожидается первичное выражение");

}

}

По сравнению с функциями

expression
и
term
в этом программном коде нет ничего нового. В нем используются те же самые языковые конструкции и методы, и объекты класса
Token
обрабатываются точно так же.

6.6. Испытание первой версии

Для того чтобы выполнить эти функции калькулятора, необходимо реализовать функции

get_token
и
main
. Функция
main
тривиальна: мы просто вызываем функцию
expression
и выводим результат на печать.

Поделиться:
Популярные книги

Возвышение Меркурия. Книга 17

Кронос Александр
17. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 17

Сильнейший ученик. Том 2

Ткачев Андрей Юрьевич
2. Пробуждение крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сильнейший ученик. Том 2

Теневой путь. Шаг в тень

Мазуров Дмитрий
1. Теневой путь
Фантастика:
фэнтези
6.71
рейтинг книги
Теневой путь. Шаг в тень

Ну, здравствуй, перестройка!

Иванов Дмитрий
4. Девяностые
Фантастика:
попаданцы
альтернативная история
6.83
рейтинг книги
Ну, здравствуй, перестройка!

Вечный. Книга III

Рокотов Алексей
3. Вечный
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга III

Безымянный раб

Зыков Виталий Валерьевич
1. Дорога домой
Фантастика:
фэнтези
9.31
рейтинг книги
Безымянный раб

Измена. Возвращение любви!

Леманн Анастасия
3. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Возвращение любви!

Кодекс Охотника. Книга XXIII

Винокуров Юрий
23. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXIII

Идеальный мир для Лекаря 14

Сапфир Олег
14. Лекарь
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 14

Лорд Системы 14

Токсик Саша
14. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 14

Последний Паладин. Том 2

Саваровский Роман
2. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 2

Последний реанорец. Том III

Павлов Вел
2. Высшая Речь
Фантастика:
фэнтези
попаданцы
5.25
рейтинг книги
Последний реанорец. Том III

Темный Лекарь 5

Токсик Саша
5. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 5

Газлайтер. Том 6

Володин Григорий
6. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 6