Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

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

Обратите внимание на то, что мы могли бы определить выражение 1–2–3 как 1–(2–3), а не (1–2)–3 и вообще избежать этой дискуссии. Довольно часто самые трудные программистские проблемы возникают тогда, когда мы работаем с привычными для людей правилами, которые изобрели задолго до компьютеров.

6.5.2.3. Выражения: третья попытка (удачная)

Итак, что теперь? Еще раз взгляните на грамматику (правильная грамматика приведена в разделе 6.5.2): любое Выражение начинается с Терма, за которым может следовать символ + или –. Следовательно, мы должны найти Терм, проверить, следует ли за ним символ + или –, и делать это, пока символы “плюс” и “минус” не закончатся. Рассмотрим пример.

double expression

{

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

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

while (t.kind=='+' || t.kind=='–') { // ищем + или –

if (t.kind == '+')

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

else

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

t = get_token;

}

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

}

Этот вариант немного сложнее: мы ввели цикл для поиска символов + и –. Кроме того, дважды повторили проверку символов + и –, а также дважды вызвали функцию

get_token
. Поскольку это запутывает логику кода, просто продублируем проверку символов + и –.

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;

  • Читать дальше
  • 1
  • ...
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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