🐛 Fix case like y=80%*x painting wrongly
This commit is contained in:
@@ -43,22 +43,26 @@ class Parser {
|
||||
Expr parseMul() {
|
||||
var expr = parsePow();
|
||||
skipSpaces();
|
||||
while (!isEnd && (current == '*' || current == '/')) {
|
||||
while (!isEnd &&
|
||||
(current == '*' ||
|
||||
current == '/' ||
|
||||
current == '%' ||
|
||||
RegExp(r'[a-zA-Z\d]').hasMatch(current) ||
|
||||
current == '(')) {
|
||||
if (current == '*' || current == '/') {
|
||||
var op = current;
|
||||
eat();
|
||||
var right = parsePow();
|
||||
if (op == '*') {
|
||||
expr = MulExpr(expr, right);
|
||||
} else {
|
||||
expr = DivExpr(expr, right);
|
||||
}
|
||||
skipSpaces();
|
||||
}
|
||||
// Handle percentage operator
|
||||
skipSpaces();
|
||||
if (!isEnd && current == '%') {
|
||||
expr = op == '*' ? MulExpr(expr, right) : DivExpr(expr, right);
|
||||
} else if (current == '%') {
|
||||
eat();
|
||||
expr = PercentExpr(expr);
|
||||
} else {
|
||||
// implicit multiplication
|
||||
var right = parsePow();
|
||||
expr = MulExpr(expr, right);
|
||||
}
|
||||
skipSpaces();
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
@@ -48,7 +48,30 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> {
|
||||
final input = _controller.text.trim();
|
||||
final normalizedInput = input.replaceAll(' ', '');
|
||||
|
||||
// 使用solver检查是否为可绘制的函数表达式
|
||||
// 如果当前已经是函数模式,保持函数模式
|
||||
if (_isFunctionMode) {
|
||||
// 重新检查表达式是否仍然可绘制(以防用户修改了表达式)
|
||||
if (_solverService.isGraphableExpression(normalizedInput)) {
|
||||
// 保持在函数模式,不做任何改变
|
||||
return;
|
||||
} else {
|
||||
// 表达式不再可绘制,切换回普通模式
|
||||
setState(() {
|
||||
_isFunctionMode = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否为函数表达式(优先使用简单y=检测)
|
||||
if (normalizedInput.toLowerCase().startsWith('y=')) {
|
||||
setState(() {
|
||||
_isFunctionMode = true;
|
||||
_result = null;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 备用检查:使用solver进行更复杂的表达式检测
|
||||
if (_solverService.isGraphableExpression(normalizedInput)) {
|
||||
setState(() {
|
||||
_isFunctionMode = true;
|
||||
@@ -57,6 +80,7 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> {
|
||||
return;
|
||||
}
|
||||
|
||||
// 普通表达式求解
|
||||
setState(() {
|
||||
_isFunctionMode = false;
|
||||
_isLoading = true;
|
||||
|
@@ -54,6 +54,12 @@ class _GraphCardState extends State<GraphCard> {
|
||||
(match) => '${match.group(1)}*${match.group(2)}',
|
||||
);
|
||||
|
||||
// 在 % 和变量或数字之间插入乘号 (如 80%x -> 80%*x)
|
||||
functionExpr = functionExpr.replaceAllMapped(
|
||||
RegExp(r'%([a-zA-Z\d])'),
|
||||
(match) => '%*${match.group(1)}',
|
||||
);
|
||||
|
||||
// 解析表达式
|
||||
final parser = Parser(functionExpr);
|
||||
final expr = parser.parse();
|
||||
|
@@ -130,6 +130,10 @@ void main() {
|
||||
// 测试无y=前缀的表达式
|
||||
final noPrefix = solver.prepareFunctionForGraphing('(x-1)(x+3)');
|
||||
expect(noPrefix, 'x^2+2x-3');
|
||||
|
||||
// 测试百分比表达式
|
||||
final percentExpr = solver.prepareFunctionForGraphing('y=80%x');
|
||||
expect(percentExpr, '80%x');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user