Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.10.2013, 10:07   #1
grumpy.user
Новичок
Джуниор
 
Регистрация: 28.10.2013
Сообщений: 1
По умолчанию Калькулятор в книге Страуструпа

В книге Страуструпа одним из первых листингов идёт этот калькулятор. Я не пойму как осуществляется ввод информации? Всё введенное выражение хранится в буфере? Я понимаю, что делает каждая функция в отдельности, но как они вместе могут составить работающий калькулятор - нет. Например, как он распознает, что за действие будет за введённым числом и много чего.. Прошу помочь, спасибо.
Код:
#include <iostream>
#include <string>
#include <map>
#include <cctype>
using namespace std;

enum Token_value            //òàáëèöà ñèìâîëîâ
{
    NAME, NUMBER, END,
    PLUS='+', MINUS='-', MUL='*', DIV='/',
    PRINT=';', ASSIGN='=', LP='(', RP=')'
};
Token_value curr_tok=PRINT;
double number_value;
string string_value;
int no_of_errors;
map<string, double> table;

double term (bool);         //óìíîæåíèå è äåëåíèå
double expr(bool);          //ñëîæåíèå è âû÷èòàíèå
double prim(bool);          //îáðàáàòûâàåò ïåðâè÷íûå ýëåìåíòû
Token_value get_token();    //ëåêñè÷åñêèé àíàëèçàòîð, ââîä
double error (const string&);

int main()
{
    table["pi"]=3.1415926535;
    table["e"]=2.718281828459;
    while(cin)
    {
        get_token();
        if(curr_tok==END) break;
        if (curr_tok==PRINT) continue;
        cout<<expr(false)<< '\n';
    }
    
    return no_of_errors;
}

double expr(bool get)
{
    double left=term(get);
    for ( ; ; )
        switch (curr_tok)
        {
            case PLUS:
                left+=term(true);
                break;
            case MINUS:
                left-=term(true);
                break;
            default:
                return left;
        }
}
double term(bool get)
{
    double left = prim(get);
    for ( ; ; )
        switch (curr_tok)
        {
            case MUL:
                left *= prim(true);
                break;
            case DIV:
                if (double d = prim(true))
                {
                    left /= d;
                    break;
                }
                return error ("divide by 0");
            default:
                return left;
        }
}
double prim(bool get)
{
    if(get) get_token();
    switch(curr_tok)
    {
        case NUMBER:
        {
            double v = number_value;
            get_token();
            return v;
        }
        case NAME:
        {
            double& v = table[string_value];
            if(get_token() == ASSIGN) v = expr(true);
            return v;
        }
        case MINUS:
            return -prim(true);
        case LP:
        {
            double e = expr(true);
            if(curr_tok != RP) return error("')' expected");
            get_token();
            return e;
        }
        default:
            return error("primary expected");
        }
}
Token_value get_token()
{
    char ch = 0;
    do
    {
        if(!cin.get(ch)) return curr_tok=END;
    } while(ch!='\n' && isspace(ch));
    switch(ch)
    {
        case 0:
            return curr_tok=END;
        case ';':
        case '\n':
            return curr_tok=PRINT;
        case '*':
        case '/':
        case '+':
        case '-':
        case '(':
        case ')':
        case '=':
            return curr_tok=Token_value(ch);
        case '0': case '1': case '2': case '3': case '4':
        case '5':case '6': case '7': case '8': case '9': case '.':
            cin.putback(ch);
            cin>>number_value;
            return curr_tok=NUMBER;
        default:
            if(isalpha(ch))
            {
                string_value=ch;
                while(cin.get(ch) && isalnum(ch)) string_value.push_back(ch);
                cin.putback(ch);
                return curr_tok=NAME;
            }
            error ("bad token");
            return curr_tok=PRINT;
    }
}
double error(const string& s)
{
    no_of_errors++;
    cerr<<"error: " << s << "\n";
    return 1;
}
grumpy.user вне форума Ответить с цитированием
Старый 28.10.2013, 15:58   #2
kineziz
Форумчанин
 
Регистрация: 22.12.2011
Сообщений: 378
По умолчанию

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


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
VC++ 2012 не хочет отрабатывать код из Страуструпа Rin Visual C++ 5 22.09.2013 12:23
Задача из Страуструпа 11.14.20. I_I_I Общие вопросы C/C++ 9 24.07.2013 18:08
калькулятор страуструпа.Добавление структур KirillKirill Помощь студентам 1 29.10.2012 14:14
Страуструпа или Лафоре EvWinApi Общие вопросы C/C++ 1 27.03.2012 08:41
Калькулятор Страуструпа Эйнж Общие вопросы C/C++ 1 01.04.2009 00:44