Описание структур данных
Для анализа арифметического выражения был разработан анализатор (распознователь )арифметических выражений на основании рекурсивной функции. Переменные представляються вещественными числами типа dauble и целочисленными типа int . Также был написан алгорит проверки правельности введенной строки.
Руководство пользователя
Запустив приложение мы видем следующее окно
рис. 3
Вначале указанно пояснение какой знак за какую операцию отвечает . Далее нас просят ввести выражение
рис. 4
Вводим пример и нажимаем enter
После нажатия enter мы видим строку, в которой указан ответ
рис. 5
Если при вводе ворожения вы допустили синтаксическую ошибку то программа вам выдаст строку : Некоректное выражение
рис. 6
При вводе q программа закроется
Результаты тестирования
Тестовый пример
1)
В главном меню программы с клавиатуры вводим следующее выражение как показанно на рисунке 4:
(2+2*(9/3))*5=40
Считаем в порядке выполнения действий
9/3=3
3*2=6
6+2=)
8*5=40
Ответ: 40
2)
2.5*4+(8/2+1)=15
Считаем в порядке выполнения действий
2.5*4=10
8/2+1=5
10+5=15
Ответ: 15
3)
Считаем в порядке выполнения действий
6.6/2+645/4=164.55
6.6/2=3.3
645/4=161.25
161.25+3.3=164.55
Ответ: 164.55
4)
Считаем в порядке выполнения действий
6+A= Программа выдаст ответ: Некоректное выражение
Заключение
В данном курсовом проекте была разобрана работа с синтаксическим анализом арифметических выражений и подсчету результата.
Было созданно приложение под Windows. Приложение было отлаженно и протестированно.
Список использованных источников
Бьярн Страуструп. Язык программирования С++.в двух частях. Пер. с англ. Киев:"ДиаСофт",1993.-296 с.,ил.
Г. Шилдт «Самоучитель С++» - СПб.:БХВ-Петербург. 2001. — 670с.
Культин Н. «С/С++ в задачах и примерах» - СПб.:БХВ-Петербург, 2002. — 288 с.
ПРИЛОЖЕНИЕ А
Файл Курсовой проект.cpp
#include <string>
#include <cctype>
#include<iostream>
#include<map>
using namespace std;
int no_of_errors; // note: default initialized to 0
double error(const char* s)
{setlocale(LC_ALL,"Rus");
no_of_errors++;
cerr << "Ошибка: " << s << '\n';
return 1;
}
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;
Token_value get_token()
{
char ch;
do { // skip whitespace except '\en'
if(!cin.get(ch)) return curr_tok = END;
} while (ch!='\n' && isspace(ch));
while (ch=='q') exit(0);
switch (ch) {
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: // NAME, NAME=, or error
if (isalpha(ch)) {
string_value = ch;
while (cin.get(ch) && isalnum(ch))
string_value += ch; // string_value.push_back(ch);
// to work around library bug
cin.putback(ch);
return curr_tok=NAME;
}
error("Некорректное выражение");
return curr_tok=PRINT;
}
}
map<string,double> table;
double expr(bool); // cannot do without
double prim(bool get) // handle primaries
{
if (get) get_token();
switch (curr_tok) {
case NUMBER: // floating-point constant
{ 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: // unary minus
return -prim(true);
case LP:
{ double e = expr(true);
if (curr_tok != RP) return error(") expected");
get_token(); // eat ')'
return e;
}
default:
return error("Некорректное выражение");
}
}
double term(bool get) // multiply and divide
{
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("На ноль делить нельзя");
default:
return left;
}
}
double expr(bool get) // add and subtract
{
double left = term(get);
for (;;) // ``forever''
switch (curr_tok) {
case PLUS:
left += term(true);
break;
case MINUS:
left -= term(true);
break;
default:
return left;
}
}
int main()
{
table["pi"] = 3.1415926535897932385; // insert predefined names
table["e"] = 2.7182818284590452354;
setlocale(LC_ALL,"Rus");
cout<<"Программа вычисления арифметических выражений "<<"\n";
cout<<"Знак + сложение "<<"\n";
cout<<"Знак - вычитание "<<"\n";
cout<<"Знак / деление "<<"\n";
cout<<"Знак * умножение "<<"\n";
cout<<"Знак . используется для записи дробных чисел : "<<"\n";
cout<<"Знак q для выхода из программы : "<<"\n";
cout<<"Введите пример : "<<"\n";
while (cin) {
get_token();
if (curr_tok == END) break;
if (curr_tok == PRINT) continue;
cout<<"Ответ : ";
cout << expr(false) << '\n';
cout<<"Введите пример : "<<"\n";
}
return no_of_errors;
}