16 / 16 / 1
Регистрация: 13.10.2012
Сообщений: 454
|
|
1 | |
Калькулятор в книге Страуструпа28.07.2013, 14:48. Показов 5090. Ответов 29
Метки нет (Все метки)
Я знал, что это довольно тяжелая книга, поэтому начал читать ее после другой о С++, но пример "элементарного" калькулятора поставил меня в тупик с первых же строк. В этой теме я буду задавать вопросы относительно него по частям. Вот с самого начала: это всё вообще что? Даже не псевдокод, почему END в начале? Что за выражения? Что за термы? Первичное? Выражения? Прочитал весь пример, и так вопросов куча.
(стр. 70) Грамматика языка калькулятора определяется следующими правилами: программа: END // END - это конец ввода список-выраженийEND список-выражений: выражение PRINT // PRINT - это'\n' или';' выражение PRINT список-выражений выражение: выражение+ терм выражение - терм терм терм: терм/ первичное терм* первичное первичное первичное: NUMBER // число с плавающей запятой в С++ NAME // имя в языке С++ за исключением'_' NAME = выражение - первичное ( выражение)
0
|
28.07.2013, 14:48 | |
Ответы с готовыми решениями:
29
Калькулятор в книге Страуструпа Непонятный код в книге Страуструпа Задача по книге Страуструпа после главы 3.9 Для того чтобы выучить С++ по книге Бьёрна Страуструпа |
16 / 16 / 1
Регистрация: 13.10.2012
Сообщений: 454
|
||||||
29.07.2013, 13:58 [ТС] | 22 | |||||
Dani, в expr () после вызова get_token() функция term () возвращает уже следующий после left терм?
0
|
29.07.2013, 14:03 | 23 |
tramp_1-3, ты напутал. Вызов get_token должен быть сразу после for(;;). Т.е. что делает ф-ция (expression (term() ей аналогична практически):
1) Каждое выражение начинается со слагаемого. Считываем его при помощи ф-ции term; 2) Считываем токен в цикле for(;;) 3) Если то токен + или - , то, по правилам математики, дальше должно идти еще одно слагаемое. Вызываем ф-цию term(), чтобы найти следующее слагаемое. 4) Если этот токен не + и не -, это значит, что мы достигли конца выражения. У тебя же токен считывается и выкидывается. По-моему, ты смотришь нерабочую версию калькулятора (в главе 6, там по-моему только третья функция expression правильная)
1
|
16 / 16 / 1
Регистрация: 13.10.2012
Сообщений: 454
|
|
29.07.2013, 14:11 [ТС] | 24 |
Попробую возразить: get_token () пишет в глобальную curr_tok, так что вроде ничего не выкидывается. Возможно, у нас издания разные..
0
|
29.07.2013, 14:18 | 25 |
tramp_1-3, да, издания разные. Но смысл тот же, просто в моем издании он описывал поток лексем, со всем наворотами, а тут - все хитрее и непонятнее. Смысл в том, что то, как я написал - в default надо возвращать токен обратно в поток, а тут - токены все хитро используются, потому ничего возвращать не нужно, т.к. в curr_tok уже будет нужная лексема. Об этом не думай пока, сконцентрируйся на вызовах. Потом поймешь.
В моем издании еще было не for(;;), a while(true)
1
|
16 / 16 / 1
Регистрация: 13.10.2012
Сообщений: 454
|
||||||
29.07.2013, 14:28 [ТС] | 26 | |||||
Dani, константа с плавающей точкой - просто число, которое ввел в программу пользователь?
NAME - имя чего? В чем вообще смысл блока case NAME: ?
0
|
29.07.2013, 15:16 | 27 |
да, это так.
Это точно должно быть описано в книге. Скорее всего, это константа для обозначения имени. Т.е. для каждой лексемы есть свой тип и свое обозначение. NAME - для обозначения имен переменных.
1
|
16 / 16 / 1
Регистрация: 13.10.2012
Сообщений: 454
|
|||||||||||
29.07.2013, 15:48 [ТС] | 28 | ||||||||||
В вашей реализации такого нет? Везде это просто "имя", это что, переменные в калькуляторе вводить можно?
"Если последнее значениеNUMBER хранится в глобальной переменнойnumber_value, то строковое представление последнего значенияNAME хранится вname_string. Перед тем, как что-либо делать с именем, калькулятор должен заглянуть вперед, чтобы выяснить, будет ли ему присваиваться значение, или же будет только использоваться существующее его значение. В обоих случаях надо обратиться к таблице имен. Эта таблица рассматривается в$$3.1.3; а здесь достаточно только знать, что она состоит из записей, имеющих вид:
74 Членnext используется только служебными функциями, работающими с таблицей:
Функцияlook() "ругается", если имя не было занесено в таблицу. Это означает, что в калькуляторе можно использовать имя без предварительного описания, но в первый раз оно может появиться только в левой части присваивания."
0
|
16 / 16 / 1
Регистрация: 13.10.2012
Сообщений: 454
|
||||||
30.07.2013, 13:43 [ТС] | 30 | |||||
Dani, настало время функции ввода (а т.к. в плюсах ввод буферизуется, это делает её самой сложной)
Ввод всего всего выражения целиком (например,2 + 4 * 8 происходит в if(!cin.get(ch)) return curr_tok = END;? Если да, то ведь в плюсах буферизованное выражения после прочтения (while (ch!='\n' && isspace(ch))) выкидывается и нигде не хранится, тогда как происходит дальнейшее обращение к ch?
0
|
30.07.2013, 13:43 | |
30.07.2013, 13:43 | |
Помогаю со студенческими работами здесь
30
Какой компилятор выбрать для лучшего изучения С++ по книге Берна Страуструпа?п калькулятор страуструпа калькулятор Страуструпа Калькулятор Страуструпа (C++) Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |