diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json new file mode 100644 index 0000000..4e72f3b --- /dev/null +++ b/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": "Нет конфигураций" +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..16a5d48 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,9 @@ +{ + "ExpandedNodes": [ + "", + "\\src", + "\\src\\src" + ], + "SelectedNode": "\\src\\src\\Source.cpp", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/mp2-lab3-arithmetic-expression/v16/.suo b/.vs/mp2-lab3-arithmetic-expression/v16/.suo new file mode 100644 index 0000000..87db31b Binary files /dev/null and b/.vs/mp2-lab3-arithmetic-expression/v16/.suo differ diff --git a/.vs/mp2-lab3-arithmetic-expression/v16/Browse.VC.db b/.vs/mp2-lab3-arithmetic-expression/v16/Browse.VC.db new file mode 100644 index 0000000..6854710 Binary files /dev/null and b/.vs/mp2-lab3-arithmetic-expression/v16/Browse.VC.db differ diff --git a/.vs/mp2-lab3-arithmetic-expression/v16/ipch/AutoPCH/3da2ddb35a83b16b/SOURCE.ipch b/.vs/mp2-lab3-arithmetic-expression/v16/ipch/AutoPCH/3da2ddb35a83b16b/SOURCE.ipch new file mode 100644 index 0000000..e496fb9 Binary files /dev/null and b/.vs/mp2-lab3-arithmetic-expression/v16/ipch/AutoPCH/3da2ddb35a83b16b/SOURCE.ipch differ diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000..4fec281 Binary files /dev/null and b/.vs/slnx.sqlite differ diff --git a/src/.vs/src/v16/.suo b/src/.vs/src/v16/.suo new file mode 100644 index 0000000..78c11d7 Binary files /dev/null and b/src/.vs/src/v16/.suo differ diff --git a/src/.vs/src/v16/Browse.VC.db b/src/.vs/src/v16/Browse.VC.db new file mode 100644 index 0000000..9dc19b1 Binary files /dev/null and b/src/.vs/src/v16/Browse.VC.db differ diff --git a/src/.vs/src/v16/ipch/AutoPCH/8a4f8aa7f85d16b/SOURCE.ipch b/src/.vs/src/v16/ipch/AutoPCH/8a4f8aa7f85d16b/SOURCE.ipch new file mode 100644 index 0000000..c263ae3 Binary files /dev/null and b/src/.vs/src/v16/ipch/AutoPCH/8a4f8aa7f85d16b/SOURCE.ipch differ diff --git a/src/Debug/src.ilk b/src/Debug/src.ilk new file mode 100644 index 0000000..4e115c6 Binary files /dev/null and b/src/Debug/src.ilk differ diff --git a/src/Debug/src.pdb b/src/Debug/src.pdb new file mode 100644 index 0000000..6f82d84 Binary files /dev/null and b/src/Debug/src.pdb differ diff --git a/src/src/Debug/src.exe.recipe b/src/src/Debug/src.exe.recipe new file mode 100644 index 0000000..8d9f827 --- /dev/null +++ b/src/src/Debug/src.exe.recipe @@ -0,0 +1,11 @@ + + + + + C:\Users\ladan\source\repos\mp2-lab3-arithmetic-expression\src\Debug\src.exe + + + + + + \ No newline at end of file diff --git a/src/src/Debug/src.log b/src/src/Debug/src.log new file mode 100644 index 0000000..7724041 --- /dev/null +++ b/src/src/Debug/src.log @@ -0,0 +1,2 @@ + Source.cpp + src.vcxproj -> C:\Users\ladan\source\repos\mp2-lab3-arithmetic-expression\src\Debug\src.exe diff --git a/src/src/Debug/src.tlog/CL.command.1.tlog b/src/src/Debug/src.tlog/CL.command.1.tlog new file mode 100644 index 0000000..f535674 Binary files /dev/null and b/src/src/Debug/src.tlog/CL.command.1.tlog differ diff --git a/src/src/Debug/src.tlog/CL.read.1.tlog b/src/src/Debug/src.tlog/CL.read.1.tlog new file mode 100644 index 0000000..66d5fd7 Binary files /dev/null and b/src/src/Debug/src.tlog/CL.read.1.tlog differ diff --git a/src/src/Debug/src.tlog/CL.write.1.tlog b/src/src/Debug/src.tlog/CL.write.1.tlog new file mode 100644 index 0000000..9060494 Binary files /dev/null and b/src/src/Debug/src.tlog/CL.write.1.tlog differ diff --git a/src/src/Debug/src.tlog/link.command.1.tlog b/src/src/Debug/src.tlog/link.command.1.tlog new file mode 100644 index 0000000..b897f39 Binary files /dev/null and b/src/src/Debug/src.tlog/link.command.1.tlog differ diff --git a/src/src/Debug/src.tlog/link.read.1.tlog b/src/src/Debug/src.tlog/link.read.1.tlog new file mode 100644 index 0000000..8c54268 Binary files /dev/null and b/src/src/Debug/src.tlog/link.read.1.tlog differ diff --git a/src/src/Debug/src.tlog/link.write.1.tlog b/src/src/Debug/src.tlog/link.write.1.tlog new file mode 100644 index 0000000..87bd1c0 Binary files /dev/null and b/src/src/Debug/src.tlog/link.write.1.tlog differ diff --git a/src/src/Debug/src.tlog/src.lastbuildstate b/src/src/Debug/src.tlog/src.lastbuildstate new file mode 100644 index 0000000..f58ef99 --- /dev/null +++ b/src/src/Debug/src.tlog/src.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.28.29333:TargetPlatformVersion=10.0.18362.0: +Debug|Win32|C:\Users\ladan\source\repos\mp2-lab3-arithmetic-expression\src\| diff --git a/src/src/Debug/vc142.idb b/src/src/Debug/vc142.idb new file mode 100644 index 0000000..9fa0768 Binary files /dev/null and b/src/src/Debug/vc142.idb differ diff --git a/src/src/Debug/vc142.pdb b/src/src/Debug/vc142.pdb new file mode 100644 index 0000000..48df621 Binary files /dev/null and b/src/src/Debug/vc142.pdb differ diff --git a/src/src/Source.cpp b/src/src/Source.cpp new file mode 100644 index 0000000..3b96a87 --- /dev/null +++ b/src/src/Source.cpp @@ -0,0 +1,366 @@ +#include +#include +#include +#include +#include +using namespace std; +#define PI 3.14159265358979323846 + +enum class TypeLexeme { + number, + variable, + bin_op, + un_op, + left_scope, + right_scope, + error +}; + +enum class Priority { + number, + plus, + mult, + pow, + un_op, + scope, +}; + +struct Lexeme { + TypeLexeme type; + std::string value; + Priority priority; +}; + +enum class StateLexeme { + start, + number, + variable, + un_op, + bin_op, + left_scope, + right_scope, + end, + error +}; + +Lexeme crToLexeme(const std::string& exp, size_t& index, StateLexeme state) { + std::string val; + if (exp[index] == '*' || exp[index] == '/') + { + val.push_back(exp[index++]); + return Lexeme({ TypeLexeme::bin_op, val, Priority::mult }); + } + else if (exp[index] == '+') + { + val.push_back(exp[index++]); + return Lexeme({ TypeLexeme::bin_op, val, Priority::plus }); + } + else if (exp[index] == '-') + { + if (state == StateLexeme::start || state == StateLexeme::left_scope) + { + return Lexeme({ TypeLexeme::un_op ,val, Priority::un_op }); + } + else if (state == StateLexeme::variable || state == StateLexeme::number || state == StateLexeme::right_scope) + { + return Lexeme{ TypeLexeme::bin_op,val ,Priority::plus}; + } + } + + else if (exp[index] == '^') + { + val.push_back(exp[index++]); + return Lexeme({TypeLexeme::bin_op, val, Priority::pow}); + } + + else if (exp[index] == '(') + { + val.push_back(exp[index++]); + return Lexeme({TypeLexeme::left_scope, val, Priority::scope}); + } + else if (exp[index] == ')') + { + val.push_back(exp[index++]); + return Lexeme({TypeLexeme::right_scope, val, Priority::scope}); + + } + + else if (exp.substr(index, 3) == "sin" || exp.substr(index, 3) == "cos" || exp.substr(index, 3) == "sqrt" || exp.substr(index, 3) == "tg" || exp.substr(index, 3) == "ctg" || exp.substr(index, 3) == "ln" || exp.substr(index, 3) == "arcsin" || exp.substr(index, 3) == "arccos" || exp.substr(index, 3) == "arctg" || exp.substr(index, 3) == "arcctg") + { + val = exp.substr(index, 3); + index += 3; + return Lexeme({ TypeLexeme::un_op, val, Priority::un_op}); + } + + else if (exp[index] >= '0' && exp[index] <= '9') + { + while (exp[index] >= '0' && exp[index] <= '9') + { + val.push_back(exp[index++]); + } + return Lexeme({ TypeLexeme::number, val, Priority::number }); + } + + return Lexeme({ TypeLexeme::error, val, Priority::plus }); +} + +std::vector convertStrToLexeme(const std::string& str) +{ + int counter = 0; + size_t index = 0; + std::vector res; + StateLexeme state = StateLexeme::start; + for (index; index < str.size(); index++) + { + const Lexeme lexeme = crToLexeme(str, index, state); + if (state == StateLexeme::start) + { + if (lexeme.type == TypeLexeme::un_op) + state = StateLexeme::un_op; + else if (lexeme.type == TypeLexeme::variable || lexeme.type == TypeLexeme::number) + state = StateLexeme::variable; + else if (lexeme.type == TypeLexeme::left_scope) + { + state = StateLexeme::left_scope; + counter++; + } + else throw "Error"; + } + else if (state == StateLexeme::un_op) + { + if (lexeme.type == TypeLexeme::variable || lexeme.type == TypeLexeme::number) + { + state = StateLexeme::variable; + } + else if (lexeme.type == TypeLexeme::left_scope) + { + state = StateLexeme::left_scope; + counter++; + } + else if (lexeme.type == TypeLexeme::un_op) + { + state = StateLexeme::un_op; + } + else throw "Error"; + } + + else if (state == StateLexeme::variable) + { + if (lexeme.type == TypeLexeme::bin_op) + { + state = StateLexeme::bin_op; + } + else if (lexeme.type == TypeLexeme::right_scope) + { + state = StateLexeme::right_scope; + counter++; + } + else throw "Error"; + } + + else if (state == StateLexeme::bin_op) + { + if (lexeme.type == TypeLexeme::variable || lexeme.type == TypeLexeme::number) + { + + state = StateLexeme::variable; + } + else if (lexeme.type == TypeLexeme::left_scope) + { + state = StateLexeme::left_scope; + counter++; + } + else if (lexeme.type == TypeLexeme::un_op) + { + state = StateLexeme::un_op; + } + else throw "Error"; + } + + else if (state == StateLexeme::right_scope) + { + if (lexeme.type == TypeLexeme::right_scope) + { + state = StateLexeme::right_scope; + counter--; + } + else if (lexeme.type == TypeLexeme::bin_op) + { + state = StateLexeme::bin_op; + } + else throw "Error"; + } + + else if (state == StateLexeme::left_scope) + { + if (lexeme.type == TypeLexeme::left_scope) + { + state = StateLexeme::left_scope; + counter++; + } + else if (lexeme.type == TypeLexeme::un_op) + { + state = StateLexeme::un_op; + } + else if (lexeme.type == TypeLexeme::variable || lexeme.type == TypeLexeme::number) + { + state = StateLexeme::variable; + } + else if (lexeme.type == TypeLexeme::un_op) + { + state = StateLexeme::un_op; + } + else throw "Error"; + } + else throw "Error"; + res.push_back(lexeme); + } + return res; +} + +std::vector reverse(const std::vector& src) +{ + std::vector out; + std::vector stack; + for (const Lexeme& lex : src) + { + if (lex.type == TypeLexeme::variable || lex.type == TypeLexeme::number) + { + out.push_back(lex); + } + else if (lex.type == TypeLexeme::un_op || lex.type == TypeLexeme::left_scope) + { + stack.push_back(lex); + } + else if (lex.type == TypeLexeme:: right_scope) + { + while (stack.back().type != TypeLexeme::left_scope) + { + out.push_back(stack.back()); + stack.pop_back(); + } + stack.pop_back(); + } + else if (lex.type == TypeLexeme::bin_op) + { + while (!stack.empty() && stack.back().priority > lex.priority) + { + out.push_back(stack.back()); + stack.pop_back(); + } + stack.push_back(lex); + } + } + while (!stack.empty()) + { + out.push_back(stack.back()); + stack.pop_back(); + } + return out; +} + +double calcReverse(const std::vector& reverse) +{ + std::vector stack; + for (const Lexeme& lex: reverse) + { + if (lex.type == TypeLexeme::number) + stack.push_back(lex); + else if (lex.type == TypeLexeme::un_op) + { + double a = stod(stack.back().value); + stack.pop_back(); + if (lex.value == "-") + stack.push_back({ TypeLexeme::number, to_string(-a), Priority::number }); + else if (lex.value == "sin") + stack.push_back({ TypeLexeme::number, to_string(sin(a)), Priority::number }); + else if (lex.value == "cos") + stack.push_back({ TypeLexeme::number, to_string(cos(a)), Priority::number }); + else if (lex.value == "tg") + stack.push_back({ TypeLexeme::number, to_string(tan(a)), Priority::number }); + else if (lex.value == "ctg") + stack.push_back({ TypeLexeme::number, to_string(1 / tan(a)), Priority::number }); + else if (lex.value == "arcsin") + stack.push_back({ TypeLexeme::number, to_string(asin(a)), Priority::number }); + else if (lex.value == "arccos") + stack.push_back({ TypeLexeme::number, to_string(acos(a)), Priority::number }); + else if (lex.value == "arctg") + stack.push_back({ TypeLexeme::number, to_string(atan(a)), Priority::number }); + else if (lex.value == "arcctg") + stack.push_back({ TypeLexeme::number, to_string(PI / 2 - atan(a)), Priority::number }); + else if (lex.value == "sqrt") + stack.push_back({ TypeLexeme::number, to_string(pow(a, 0.5)), Priority::number }); + else if (lex.value == "ln") + stack.push_back({ TypeLexeme::number, to_string(log(a)), Priority::number }); + } + else if (lex.type == TypeLexeme::bin_op) + { + Lexeme a2 = stack.back(); + stack.pop_back(); + Lexeme a1 = stack.back(); + stack.pop_back(); + double b1 = std::stod(a1.value); + double b2 = std::stod(a2.value); + std::string t; + if (lex.value == "+") + { + t = std::to_string(b1 + b2); + } + else if (lex.value == "-") + { + t = std::to_string(b1 - b2); + } + else if (lex.value == "*") + { + t = std::to_string(b1 * b2); + } + else if (lex.value == "/") + { + t = std::to_string(b1 / b2); + } + else if (lex.value == "^") + { + t = std::to_string(pow(b1, b2)); + } + Lexeme t2 = { TypeLexeme::number, t, Priority::number }; + stack.push_back(t2); + } + } + double res = std::stod(stack.back().value); + return res; +} + +bool checkArithmExp(const string& str) { + try { + vector result = convertStrToLexeme(str); + } + catch (const char* str) { + cout << str; + return false; + } + catch (const string str) { + cout << "Incorrect"; + return false; + } + return true; +} + +void calcExp(string& str) { + if (checkArithmExp(str)) + { + vector lexemes = convertStrToLexeme(str); + cout << calcReverse(reverse(lexemes)); + } +} + + +int main() { + string exp; + getline(cin, exp); + + cout << endl; + calcExp(exp); + cout << endl; + + return 0; +}