c++优化

This commit is contained in:
Evan
2026-09-15 17:55:13 +08:00
parent 899adbc9d4
commit d83654837a

View File

@@ -2386,202 +2386,162 @@ export class CppCodeExecutor {
return position; return position;
} }
// 字符串表达式 // 整个表达式是字符串字面量时才当字符串;含引号的 API 调用走后面的算术解析
if (expr.includes('"') || expr.includes("'")) { if ((expr.startsWith('"') && expr.endsWith('"')) ||
return expr.replace(/['"]/g, ''); (expr.startsWith("'") && expr.endsWith("'"))) {
return expr.slice(1, -1);
} }
// 使用改进的表达式解析器处理复杂表达式
return this.parseComplexExpression(expr); return this.parseComplexExpression(expr);
} }
// 新增:改进的表达式解析器,支持括号嵌套和运算优先级 // 递归下降:一元 +/- ,然后 * / % 优先于 + -
parseComplexExpression(expr) { parseComplexExpression(expr) {
try { try {
// 移除所有空格 this._exprTokens = this.lexArithmetic(expr);
expr = expr.replace(/\s+/g, ''); this._exprPos = 0;
if (this._exprTokens.length === 0) return 0;
// 处理括号 const result = this.parseAddExpr();
while (expr.includes('(')) { return typeof result === 'number' && !Number.isNaN(result) ? result : 0;
const lastOpenParen = expr.lastIndexOf('(');
const closeParen = expr.indexOf(')', lastOpenParen);
if (closeParen === -1) {
debugLog(`⚠️ 括号不匹配: ${expr}`);
return 0;
}
const innerExpr = expr.substring(lastOpenParen + 1, closeParen);
const innerResult = this.parseComplexExpression(innerExpr);
expr = expr.substring(0, lastOpenParen) + innerResult + expr.substring(closeParen + 1);
}
// 处理一元运算符(负号)
expr = this.handleUnaryOperators(expr);
// 按正确的运算优先级解析:
// 加法和减法是最低优先级,因此在此处最先切分。
// 切分后的每一项将交给 parseAdditionSubtraction在其中处理更高级别的乘除法。
return this.parseAdditionSubtraction(expr);
} catch (error) { } catch (error) {
debugLog(`⚠️ 表达式解析错误: ${expr}, 错误: ${error.message}`); debugLog(`⚠️ 表达式解析错误: ${expr}, 错误: ${error.message}`);
return 0; return 0;
} }
} }
// 处理一元运算符 lexArithmetic(expr) {
handleUnaryOperators(expr) {
// 先处理开头的负号
if (expr.startsWith('-')) {
const restExpr = expr.substring(1);
if (/^\d+/.test(restExpr)) {
// 负数
const match = restExpr.match(/^\d+/);
const number = match[0];
const remaining = restExpr.substring(number.length);
return (-parseInt(number)) + remaining;
} else if (/^[a-zA-Z_]\w*/.test(restExpr)) {
// 负变量
const match = restExpr.match(/^[a-zA-Z_]\w*/);
const varName = match[0];
const remaining = restExpr.substring(varName.length);
if (this.variables.has(varName)) {
return (-this.variables.get(varName)) + remaining;
}
}
}
return expr;
}
// 解析乘法、除法和模运算(高优先级)
parseMultiplicationDivision(expr) {
const tokens = this.tokenizeExpression(expr, ['*', '/', '%']);
let result = this.evaluateToken(tokens[0]);
for (let i = 1; i < tokens.length; i += 2) {
const operator = tokens[i];
const operand = this.evaluateToken(tokens[i + 1]);
if (operator === '*') {
result *= operand;
} else if (operator === '/') {
result = Math.floor(result / operand); // C++整数除法
} else if (operator === '%') {
result = result % operand; // 模运算
}
}
return result;
}
// 解析加法和减法(低优先级)
parseAdditionSubtraction(expr) {
const tokens = this.tokenizeExpressionSmart(expr, ['+', '-']);
let result = this.evaluateToken(tokens[0]);
for (let i = 1; i < tokens.length; i += 2) {
const operator = tokens[i];
const operand = this.evaluateToken(tokens[i + 1]);
if (operator === '+') {
result += operand;
} else if (operator === '-') {
result -= operand;
}
}
return result;
}
// 智能分词器,考虑到负号可能是一元运算符
tokenizeExpressionSmart(expr, operators) {
const tokens = []; const tokens = [];
let current = '';
let i = 0; let i = 0;
const isIdChar = (ch) => /[a-zA-Z0-9_.]/.test(ch);
while (i < expr.length) { while (i < expr.length) {
const char = expr[i]; const ch = expr[i];
if (/\s/.test(ch)) {
if (operators.includes(char)) { i++;
// 检查是否是一元负号 continue;
if (char === '-' && (i === 0 || operators.includes(expr[i-1]) || expr[i-1] === '(')) { }
// 这是一元负号,继续收集 if ('+-*/%()'.includes(ch)) {
current += char; tokens.push({ type: ch });
} else { i++;
// 这是二元运算符 continue;
if (current.trim()) { }
tokens.push(current.trim()); if (/\d/.test(ch)) {
current = ''; let num = '';
} while (i < expr.length && /\d/.test(expr[i])) {
tokens.push(char); num += expr[i++];
} }
} else { tokens.push({ type: 'num', value: parseInt(num, 10) });
current += char; continue;
}
if (/[a-zA-Z_]/.test(ch)) {
let id = '';
while (i < expr.length && isIdChar(expr[i])) {
id += expr[i++];
}
if (expr[i] === '(') {
let depth = 0;
let call = id;
while (i < expr.length) {
const c = expr[i++];
call += c;
if (c === '(') depth++;
else if (c === ')') {
depth--;
if (depth === 0) break;
}
}
tokens.push({ type: 'call', value: call });
} else {
tokens.push({ type: 'id', value: id });
}
continue;
} }
i++; i++;
} }
if (current.trim()) {
tokens.push(current.trim());
}
return tokens; return tokens;
} }
// 将表达式分解为标记 peekExprToken() {
tokenizeExpression(expr, operators) { return this._exprTokens[this._exprPos] || { type: 'eof' };
const tokens = []; }
let current = '';
for (let i = 0; i < expr.length; i++) { consumeExprToken() {
const char = expr[i]; return this._exprTokens[this._exprPos++] || { type: 'eof' };
}
if (operators.includes(char)) { parseAddExpr() {
if (current.trim()) { let left = this.parseMulExpr();
tokens.push(current.trim()); while (this.peekExprToken().type === '+' || this.peekExprToken().type === '-') {
current = ''; const op = this.consumeExprToken().type;
} const right = this.parseMulExpr();
tokens.push(char); left = op === '+' ? left + right : left - right;
}
return left;
}
parseMulExpr() {
let left = this.parseUnaryExpr();
while (['*', '/', '%'].includes(this.peekExprToken().type)) {
const op = this.consumeExprToken().type;
const right = this.parseUnaryExpr();
if (op === '*') {
left *= right;
} else if (op === '/') {
left = right === 0 ? 0 : Math.trunc(left / right);
} else { } else {
current += char; left %= right;
} }
} }
return left;
if (current.trim()) {
tokens.push(current.trim());
}
return tokens;
} }
// 计算单个标记的值 parseUnaryExpr() {
evaluateToken(token) { const type = this.peekExprToken().type;
token = token.trim(); if (type === '-') {
if (!token) return 0; this.consumeExprToken();
return -this.parseUnaryExpr();
// 如果包含乘除法或模运算,交给乘除法解析器处理
if (token.includes('*') || token.includes('/') || token.includes('%')) {
return this.parseMultiplicationDivision(token);
} }
if (type === '+') {
this.consumeExprToken();
return this.parseUnaryExpr();
}
return this.parsePrimaryExpr();
}
// 布尔常量 parsePrimaryExpr() {
const token = this.peekExprToken();
if (token.type === 'num') {
this.consumeExprToken();
return token.value;
}
if (token.type === 'id') {
this.consumeExprToken();
return this.evaluateAtom(token.value);
}
if (token.type === 'call') {
this.consumeExprToken();
return this.evaluateAtom(token.value);
}
if (token.type === '(') {
this.consumeExprToken();
const value = this.parseAddExpr();
if (this.peekExprToken().type === ')') {
this.consumeExprToken();
}
return value;
}
debugLog(`⚠️ 无法解析标记: ${token.type}`);
return 0;
}
evaluateAtom(token) {
if (token === 'true') return 1; if (token === 'true') return 1;
if (token === 'false') return 0; if (token === 'false') return 0;
// 数字
if (/^-?\d+$/.test(token)) {
return parseInt(token);
}
// 变量查找
if (this.variables.has(token)) { if (this.variables.has(token)) {
return this.variables.get(token); return this.variables.get(token);
} }
// 对象属性访问 (如 pos.x, pos.y, pos.z)
if (token.includes('.')) { if (token.includes('.')) {
const [objName, propName] = token.split('.'); const [objName, propName] = token.split('.');
if (this.variables.has(objName)) { if (this.variables.has(objName)) {
@@ -2592,7 +2552,6 @@ export class CppCodeExecutor {
} }
} }
// 游戏API调用
if (token.includes('player_data(')) { if (token.includes('player_data(')) {
const match = token.match(/player_data\s*\(\s*"(.+?)"\s*\)/); const match = token.match(/player_data\s*\(\s*"(.+?)"\s*\)/);
if (match) return window.cppGameAPI.player_data(match[1]); if (match) return window.cppGameAPI.player_data(match[1]);