添加项目文件。

This commit is contained in:
KiriAky
2025-07-01 16:04:35 +08:00
parent 27b960a881
commit 0f8e7d3282
13 changed files with 755 additions and 0 deletions

31
ScientificCalculator.sln Normal file
View File

@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36127.28 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ScientificCalculator", "ScientificCalculator\ScientificCalculator.vcxproj", "{5C991D9D-797E-4C35-8C97-E6F43099CBD6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5C991D9D-797E-4C35-8C97-E6F43099CBD6}.Debug|x64.ActiveCfg = Debug|x64
{5C991D9D-797E-4C35-8C97-E6F43099CBD6}.Debug|x64.Build.0 = Debug|x64
{5C991D9D-797E-4C35-8C97-E6F43099CBD6}.Debug|x86.ActiveCfg = Debug|Win32
{5C991D9D-797E-4C35-8C97-E6F43099CBD6}.Debug|x86.Build.0 = Debug|Win32
{5C991D9D-797E-4C35-8C97-E6F43099CBD6}.Release|x64.ActiveCfg = Release|x64
{5C991D9D-797E-4C35-8C97-E6F43099CBD6}.Release|x64.Build.0 = Release|x64
{5C991D9D-797E-4C35-8C97-E6F43099CBD6}.Release|x86.ActiveCfg = Release|Win32
{5C991D9D-797E-4C35-8C97-E6F43099CBD6}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {227C30D6-2F25-4EA4-B670-3C930B28DA7B}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,44 @@
#include "Calc.h"
#include <iostream>
// <20><>̬<EFBFBD><CCAC>Ա<EFBFBD><D4B1>ʼ<EFBFBD><CABC>
Tokenizer Calc::tokenizer;
InfixToPostfix Calc::converter;
PostfixEval Calc::evaluator;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿڣ<D3BF><DAA3><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD> -> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
double Calc::eval(const string& expression) {
vector<Token> tokens = tokenizer.run(expression);
vector<Token> postfix = converter.run(tokens);
return evaluator.run(postfix);
}
// <20><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD>ӿڣ<D3BF><DAA3><EFBFBD> try-catch <20><>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD> bool <20><>־
bool Calc::safeEval(const string& expr, double& res) {
try {
res = eval(expr);
return true;
}
catch (const exception& e) {
cerr << "[Error] " << e.what() << endl;
return false;
}
}
// <20><><EFBFBD>Խӿڣ<D3BF><DAA3><EFBFBD>ӡ<EFBFBD>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>token <20>б<EFBFBD> <20><> <20><>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD>
void Calc::debug(const string& expr) {
try {
vector<Token> tokens = tokenizer.run(expr);
cout << "[Token List]" << endl;
for (const auto& t : tokens) cout << t.value << " ";
cout << endl;
vector<Token> postfix = converter.run(tokens);
cout << "[Postfix]" << endl;
for (const auto& t : postfix) cout << t.value << " ";
cout << endl;
}
catch (const exception& e) {
cerr << "[Debug Error] " << e.what() << endl;
}
}

View File

@@ -0,0 +1,28 @@
#ifndef CALC_H
#define CALC_H
#include"Tokenizer.h"
#include"InfixToPostfix.h"
#include"PostfixEval.h"
#include<optional>
#include<unordered_map>
using namespace std;
class Calc {
public:
//<2F><><EFBFBD>ӿں<D3BF><DABA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static double eval(const string& expresssion);
//<2F><>ȫ<EFBFBD>ӿڣ<D3BF><DAA3><EFBFBD><EFBFBD><EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>optional
static bool safeEval(const string& expr,double& res);
//<2F><><EFBFBD>Ժ<EFBFBD><D4BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡtoken<65>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>ʽ
static void debug(const string& expr);
private:
static Tokenizer tokenizer;
static InfixToPostfix converter;
static PostfixEval evaluator;
};
#endif

View File

@@ -0,0 +1,74 @@
#include "InfixToPostfix.h"
#include <stdexcept>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><E6B2A8><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>ʽת<CABD><D7AA>Ϊ<EFBFBD><CEAA>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>ʽ
vector<Token> InfixToPostfix::run(const vector<Token>& infix) {
vector<Token> output;// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ
stack<Token> opStack;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>ʽ
for (const Token& token : infix) {
if (token.is_num() || token.is_var())
//<2F><><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
output.push_back(token);
else if (token.is_fun())
//<2F><><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD>ߣ<EFBFBD>
opStack.push(token);
else if (token.is_ope()) {
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD>߻<EFBFBD><DFBB><EFBFBD>ͬ<EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while (!opStack.empty() && opStack.top().is_ope() &&
(precedence(opStack.top()) > precedence(token) ||
(precedence(opStack.top()) == precedence(token) && associativity(token) == Associativity::Left))) {
output.push_back(opStack.top());
opStack.pop();
}
//<2F><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ
opStack.push(token);
}
else if (token.is_LP())
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD>ջ
opStack.push(token);
else if (token.is_RP())
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
pop_ULP(opStack, output);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>󣬵<EFBFBD><F3A3ACB5><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while (!opStack.empty()) {
if (opStack.top().is_LP() || opStack.top().is_RP())
throw runtime_error("<EFBFBD><EFBFBD><EFBFBD>Ų<EFBFBD>ƥ<EFBFBD><EFBFBD>");//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ų<EFBFBD>ƥ<EFBFBD><C6A5>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
output.push_back(opStack.top());
opStack.pop();
}
return output;//<2F><><EFBFBD>غ<EFBFBD>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>Խ<EFBFBD><D4BD>
int InfixToPostfix::precedence(const Token& token) const {
return token.precedence;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><D4A3><EFBFBD>/<2F><>
Associativity InfixToPostfix::associativity(const Token& token) const {
return token.associativity;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪<EFBFBD><D6AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void InfixToPostfix::pop_ULP(stack<Token>& opStack, vector<Token>& output) {
//<2F><><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while (!opStack.empty() && !opStack.top().is_LP()) {
output.push_back(opStack.top());
opStack.pop();
}
//<2F><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׳<EFBFBD><D7B3>
if (opStack.empty())
throw runtime_error("<EFBFBD><EFBFBD><EFBFBD>Ų<EFBFBD>ƥ<EFBFBD>䣺ȱʧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
opStack.pop(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮ǰ<D6AE>Ǻ<EFBFBD><C7BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!opStack.empty() && opStack.top().is_fun()) {
output.push_back(opStack.top());
opStack.pop();
}
}

View File

@@ -0,0 +1,27 @@
#ifndef INFIX_TO_POSTFIX_H
#define INFIX_TO_POSTFIX_H
#include"Token.h"
#include<vector>
#include<stack>
using namespace std;
class InfixToPostfix {
public:
//<2F><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>ʽת<CABD><D7AA>Ϊ<EFBFBD><CEAA>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>ʽ
vector<Token> run(const vector<Token>& infix);
private:
//<2F><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
int precedence(const Token& token) const;
//<2F>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD>ԣ<EFBFBD><D4A3><EFBFBD>/<2F>ң<EFBFBD>
Associativity associativity(const Token& token) const;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ջ<EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void pop_ULP(stack<Token>& opStack, vector<Token>& output);
};
#endif

View File

@@ -0,0 +1,97 @@
#include"PostfixEval.h"
#include<algorithm>
#include<cctype>
double PostfixEval::run(const std::vector<Token>& postfix, const unordered_map<string, double>& vars) {
stack<double> stk;
for (const auto& token : postfix) {
if (token.is_num())
//<2F><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊdouble<6C><65>ջ
stk.push(stod(token.value));
else if (token.is_var()) {
//<2F><><EFBFBD>ұ<EFBFBD><D2B1><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD>
auto it = vars.find(token.value);
// ֧<><D6A7><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD> PAI <20><> e
if (it == vars.end()) {
if (token.value == "PAI")
stk.push(2.0 * std::asin(1.0)); // <20><> = 2 * arcsin(1)
else if (token.value == "e")
stk.push(std::exp(1.0)); // e = exp(1)
else
throw runtime_error("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><EFBFBD><EFBFBD>" + token.value);
}
else stk.push(it->second);
}
else if (token.is_ope()) {
//ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>ж<EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD>
if (stk.size() < 2) throw runtime_error("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
double b = stk.top();
stk.pop();
double a = stk.top();
stk.pop();
double res = apply_BO(token.value, a, b);
stk.push(res);
}
else if (token.is_fun()) {
//ȡ<><C8A1>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>һԪ<D2BB><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱥ<EFBFBD><C8BA><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
if (stk.empty()) throw runtime_error("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
double x = stk.top();
stk.pop();
double res = apply_UF(token.value, x);
stk.push(res);
}
else
throw runtime_error("δ֪Token<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
if (stk.size() != 1)
throw runtime_error("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD>󣬼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD>Ψһ");
return stk.top();
}
//<2F><><EFBFBD>ж<EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
double PostfixEval::apply_BO(const string& op, double a, double b) {
if (op == "+") return a + b;
if (op == "-") return a - b;
if (op == "*") return a * b;
if (op == "/") {
if (b == 0) throw runtime_error("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ0");
return a / b;
}
if (op == "^") return pow(a, b);
if (op == "%") {
if (b == 0) throw runtime_error("ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>");
return std::fmod(a, b);
}
throw runtime_error("δ֪<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" + op);
}
//<2F><><EFBFBD><EFBFBD>һԪ<D2BB><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱥ<EFBFBD><C8BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
double PostfixEval::apply_UF(const string& func, double x) {
string f = func;
transform(f.begin(), f.end(), f.begin(), ::tolower);
if (f == "sin") return sin(x);
if (f == "cos") return cos(x);
if (f == "tan") return tan(x);
if (f == "sqrt") {
if (x < 0)
throw runtime_error("sqrt<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>");
return sqrt(x);
}
if (f == "log") {
if (x <= 0)
throw runtime_error("log<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0");
return log(x);
}
if (f == "exp") return exp(x);
if (f == "abs") return fabs(x);
if (f == "asin") return asin(x);
if (f == "acos") return acos(x);
if (f == "atan") return atan(x);
throw runtime_error("δ֪<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" + func);
}

View File

@@ -0,0 +1,25 @@
#ifndef POSTFIXEVAL_H
#define POSYFIXEVAL_H
#include "Token.h"
#include <vector>
#include <stack>
#include <cmath>
#include <stdexcept>
#include<unordered_map>
using namespace std;
class PostfixEval {
public:
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ժ<EFBFBD>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
double run(const std::vector<Token>& postfix, const unordered_map<string, double>& vars = {});
private:
//Ӧ<><D3A6><EFBFBD>ڶ<EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+<2B><>-<2D><>*<2A><>/<2F><>^
double apply_BO(const string& op, double a, double b);
//Ӧ<><D3A6><EFBFBD><EFBFBD>ҽԺ<D2BD><D4BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱥ<EFBFBD><C8BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sin, cos, log
double apply_UF(const string& func, double x);
};
#endif

View File

@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{5c991d9d-797e-4c35-8c97-e6f43099cbd6}</ProjectGuid>
<RootNamespace>ScientificCalculator</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Calc.h" />
<ClInclude Include="InfixToPostfix.h" />
<ClInclude Include="PostfixEval.h" />
<ClInclude Include="Token.h" />
<ClInclude Include="Tokenizer.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Calc.cpp" />
<ClCompile Include="InfixToPostfix.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="PostfixEval.cpp" />
<ClCompile Include="Tokenizer.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Tokenizer.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="InfixToPostfix.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="PostfixEval.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="Calc.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Token.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="Tokenizer.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="InfixToPostfix.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="PostfixEval.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="Calc.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,52 @@
#ifndef TOKEN_H
#define TOKEN_H
#include<string>
using namespace std;
//<2F>Ǻ<EFBFBD><C7BA><EFBFBD><EFBFBD><EFBFBD>
enum class TokenType {
Number,
Operator,
LeftParen,
RightParen,
Function,
Variable
};
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
enum class Associativity {
Left,
Right,
None
};
//Token<65><EFBFBD><E1B9B9>
struct Token {
TokenType type;//<2F>Ǻ<EFBFBD><C7BA><EFBFBD><EFBFBD><EFBFBD>
string value; //ʵ<><CAB5><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
int precedence = -1; //<2F><><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͺ<EFBFBD><CDBA><EFBFBD><EFBFBD><EFBFBD>Ч
Associativity associativity = Associativity::None; //<2F><><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><D4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͺ<EFBFBD><CDBA><EFBFBD><EFBFBD><EFBFBD>Ч
//<2F><><EFBFBD><EFBFBD><ECBAAF>
Token(TokenType t, const string& v,
int p = -1, Associativity assoc = Associativity::None)
:type(t), value(v), precedence(p), associativity(assoc) {}
//<2F><><EFBFBD><EFBFBD><EFBFBD>жϷ<D0B6><CFB7><EFBFBD>
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD> "3.14", "42"<22><>
bool is_num() const { return type == TokenType::Number; }
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "+", "-", "*", "/"<22><>
bool is_ope() const { return type == TokenType::Operator; }
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA>ѧ<EFBFBD><D1A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "sin", "cos", "log"<22><>
bool is_fun() const { return type == TokenType::Function; }
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "("<22><><EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD><DAB1><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>
bool is_LP() const { return type == TokenType::LeftParen; }
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ")"<22><><EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD><DAB1><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool is_RP() const { return type == TokenType::RightParen; }
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "x", "y"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ֧<D5B9>ַ<EFBFBD><D6B7>Ŵ<EFBFBD><C5B4><EFBFBD><EFBFBD><EFBFBD>
bool is_var()const { return type == TokenType::Variable; }
};
#endif

View File

@@ -0,0 +1,115 @@
#include"Tokenizer.h"
#include<cctype>
#include<stdexcept>
using namespace std;
vector<Token> Tokenizer::run(const string& expr) {
expression = expr;
pos = 0;
vector<Token> tokens;
// <20><>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ʽ
while (pos < expression.length()) {
skipWhitespace();// <20><><EFBFBD><EFBFBD><EFBFBD>հ<EFBFBD><D5B0>ַ<EFBFBD>
if (pos >= expression.length()) break;
char current = expression[pos];
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD>һԪ<D2BB><D4AA><EFBFBD>ſ<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (is_dig(current) || (current == '-' && is_UMC(tokens)))
tokens.push_back(readNumber());
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
else if (is_let(current))
tokens.push_back(readIdentifier());
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
else
tokens.push_back(readOperatorOrParen());
}
return tokens;
}
void Tokenizer::skipWhitespace() {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>пո<D0BF><D5B8><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD>ȿհ<C8BF><D5B0>ַ<EFBFBD>
while (pos < expression.length() && isspace(expression[pos]))
++pos;
}
Token Tokenizer::readNumber() {
size_t start = pos;
bool hasDecimal = false;// <20><><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ֹ<EFBFBD>
if (expression[pos] == '-')
++pos; // <20><><EFBFBD><EFBFBD>һԪ<D2BB><D4AA><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while (pos < expression.length() && (is_dig(expression[pos]) || expression[pos] == '.')) {
if (expression[pos] == '.') {
if (hasDecimal)
throw runtime_error("<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>ʽ<EFBFBD><EFBFBD>Ч<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");// С<><D0A1><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>
hasDecimal = true;
}
++pos;
}
string numberStr = expression.substr(start, pos - start);
return Token(TokenType::Number, numberStr);// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Token
}
Token Tokenizer::readIdentifier() {
size_t start = pos;
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while (pos < expression.length() && is_let(expression[pos]))
++pos;
string name = expression.substr(start, pos - start);
//ʶ<><CAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
skipWhitespace();
if (pos < expression.length() && expression[pos] == '(')
return Token(TokenType::Function, name);
else
return Token(TokenType::Variable, name);
}
Token Tokenizer::readOperatorOrParen() {
char c = expression[pos++]; // <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
// <20>ж<EFBFBD><D0B6>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ Token
switch (c) {
case '+': return Token(TokenType::Operator, "+", 1, Associativity::Left);
case '-': return Token(TokenType::Operator, "-", 1, Associativity::Left);
case '*': return Token(TokenType::Operator, "*", 2, Associativity::Left);
case '/': return Token(TokenType::Operator, "/", 2, Associativity::Left);
case '^': return Token(TokenType::Operator, "^", 3, Associativity::Right);
case '(': return Token(TokenType::LeftParen, "(");
case ')': return Token(TokenType::RightParen, ")");
default:
throw runtime_error(string("δ֪<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ") + c); // δ֪<CEB4>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
}
}
bool Tokenizer::is_UMC(const vector<Token>& tokens) {
// <20><><EFBFBD><EFBFBD><EFBFBD>DZ<EFBFBD><C7B1><EFBFBD>ʽ<EFBFBD><CABD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>ǰһ<C7B0><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>ΪһԪ
if (tokens.empty()) return true;
Token last = tokens.back();
return last.is_ope() || last.is_LP();
}
bool Tokenizer::is_dig(char c) const {
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>
return std::isdigit(static_cast<unsigned char>(c));
}
bool Tokenizer::is_let(char c) const {
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD>ΪӢ<CEAA><D3A2><EFBFBD><EFBFBD>ĸ
return std::isalpha(static_cast<unsigned char>(c));
}
bool Tokenizer::is_OpeCh(char c) const {
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD>Ϊ<EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>
return c == '+' || c == '-' || c == '*' || c == '/' || c == '^';
}

View File

@@ -0,0 +1,40 @@
#ifndef TOKENIZER_H
#define TOKENIZER_H
#include<string>
#include<vector>
#include"Token.h"
using namespace std;
class Tokenizer {
public:
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>ΪToken<65><6E><EFBFBD><EFBFBD>
vector<Token> run(const string& expr);
private:
string expression; //<2F><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD>ʽ
size_t pos = 0; //<2F><>ǰָ<C7B0><D6B8>λ<EFBFBD><CEBB>
//<2F><><EFBFBD>ߺ<EFBFBD><DFBA><EFBFBD>:<3A><><EFBFBD><EFBFBD><EFBFBD>ո<EFBFBD><D5B8>ַ<EFBFBD>
void skipWhitespace();
//<2F><>ȡһ<C8A1><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD><D6A3><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><E3A1A2><EFBFBD>ܵ<EFBFBD>һԪ<D2BB><D4AA><EFBFBD>ţ<EFBFBD>
Token readNumber();
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><>sin<69><6E>cos<6F><73>log<6F><67>)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>x<EFBFBD><78>y<EFBFBD><79>
Token readIdentifier();
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Token readOperatorOrParen();
//<2F>жϵ<D0B6>ǰλ<C7B0><CEBB><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>һԪ<D2BB><D4AA><EFBFBD>ŵ<EFBFBD><C5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool is_UMC(const vector<Token>& tokens);
//<2F>ַ<EFBFBD><D6B7>жϸ<D0B6><CFB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool is_dig(char c)const;
bool is_let(char c)const;
bool is_OpeCh(char c)const;
};
#endif

View File

@@ -0,0 +1,29 @@
#include <iostream>
#include<string>
#include "Calc.h"
using namespace std;
int main() {
string input;
cout << "<EFBFBD><EFBFBD>ѧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD> q <20>˳<EFBFBD>)<29><>\n";
while (true) {
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ > ";
getline(cin, input);
if (input == "q" || input == "quit")
break;
double result;
if (Calc::safeEval(input, result)) {
cout << "= " << result << endl;
}
else {
cout << "[<5B><><EFBFBD><EFBFBD>] <20><><EFBFBD><EFBFBD>ʽ<EFBFBD>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD>\n";
}
}
cout << "<EFBFBD><EFBFBD>лʹ<EFBFBD>ã<EFBFBD><EFBFBD>ټ<EFBFBD><EFBFBD><EFBFBD>" << endl;
return 0;
}