添加项目文件。

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

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 == '^';
}