Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > РЕКУРСИЯ C++


Автор: duducai007 12.12.2012, 22:41
Помогите дополнить программу C++ решаюшее примеры ввида (1+2*3)*(4+5)+6*(7+8)+9) используя метод рекурсивного спуска. Операции(лексемы): _Num-число, _Plus-Сложение, _Mul-Умножение, _Open-открыв. скобка, _Close-закрыв. скобка, _End-конец выражения.Проблема в том, что программа выдает ошибку при вычитании, делении, возведении в степень, унарных минусах, дробных числах.
Надо как нибудь дополнить(У меня  не получается(().

А вот и сама программа:

//Грамматика:
//<Выражение> ::= <слагаемое> {+ <слагаемое>}
//<Слагаемое> ::= <множитель> {* <множитель>}
//<Множитель> ::= <число> | (<выражение>)
#include <iostream>
using namespace std;
typedef char TLexem;
const char _Num = '1',
           _Plus = '+',  
           _Mul = '*',
           _Open = '(',
           _Close = ')',
           _End = '\n';
bool is_error = 0; // флаг ошибки
//получение след. лексемы: _Num, _Plus, _Mul, _Open, _Close или _End
void nextlexem(TLexem& curlex, int& vl);
//вычисление выражения
int expr(TLexem& curlex, int& vl);
//вычисление слагаемого
int item(TLexem& curlex, int& vl);
//вычисление множителя
int mult(TLexem& curlex, int& vl);
//обработка ошибок
void error(TLexem& curlex, int& vl);
int main()
{
    TLexem curlex;
    int vl;
    int v;
    setlocale(LC_ALL, "Russian");
    nextlexem(curlex, vl);
    if(curlex == _End)
        cout << "Введена пустая строка." << endl;
    else
    {   
        v = expr(curlex, vl);
        if(!is_error)
            cout << "Результат = " << v <<endl;
    }
    system("pause");
    return 0;
}
void nextlexem(TLexem& curlex, int& vl)     
{
    char sim;
    sim = cin.get();
    if(isdigit(sim))
    {
        cin.putback(sim);
        cin >> vl;
        curlex = _Num;
    }
    else
        switch(sim)
        {
            case '+':
                curlex = _Plus;
                break;
            case '*':
                curlex = _Mul;
                break;
            case '(':
                curlex = _Open;
                break;
            case ')':
                curlex = _Close;
                break;
            case ' ':                   
                nextlexem(curlex, vl);
                break;
            case '\n':
                curlex = _End;
            default:
                curlex = sim;//записываю сам символ для послед. обработки ошибок
        }
}
int expr(TLexem& curlex, int& vl)
{
    int a;
    a = item(curlex, vl);
    while(curlex == _Plus)
    {
        nextlexem(curlex, vl);
        a+=item(curlex, vl);
    }
    return a;
}
int item(TLexem& curlex, int& vl)
{
    int a;
    a = mult(curlex, vl);
    while(curlex == _Mul)
    {
        nextlexem(curlex, vl);
        a*=mult(curlex, vl);
    }
    return a;
}
int mult(TLexem& curlex, int& vl)
{
    int r = 1;//произвольное значение
    switch(curlex)
    {
        case _Num:
            r = vl;
            nextlexem(curlex, vl);
            break;
        case _Open:
            r = expr(curlex, vl);
            if(curlex == _Close)
            {
                nextlexem(curlex, vl);
                break;
            }
        default:
            error(curlex, vl);
    }
    if(curlex!= _Plus && curlex!= _Mul && curlex!= _End)//следующая лексема после множителя не '*' , не '+' и не '\n'
        error(curlex, vl);
    return r;
}
void error(TLexem& sim, int& vl)
{
    if(sim == _Open || sim == _Close)
        cout << "Ошибка: неверная расстановка скобок." << endl;
    else
        cout << "Ошибка: введён символ '" << sim << "' не являющийся частью выражения, или значение которого в данной позиции не определено." << endl;
    is_error = 1;
    while(sim!= _End)
        nextlexem(sim, vl);
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)