🐛 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