🐛 Fix case like y=80%*x painting wrongly
This commit is contained in:
		| @@ -43,23 +43,27 @@ class Parser { | |||||||
|   Expr parseMul() { |   Expr parseMul() { | ||||||
|     var expr = parsePow(); |     var expr = parsePow(); | ||||||
|     skipSpaces(); |     skipSpaces(); | ||||||
|     while (!isEnd && (current == '*' || current == '/')) { |     while (!isEnd && | ||||||
|       var op = current; |         (current == '*' || | ||||||
|       eat(); |             current == '/' || | ||||||
|       var right = parsePow(); |             current == '%' || | ||||||
|       if (op == '*') { |             RegExp(r'[a-zA-Z\d]').hasMatch(current) || | ||||||
|         expr = MulExpr(expr, right); |             current == '(')) { | ||||||
|  |       if (current == '*' || current == '/') { | ||||||
|  |         var op = current; | ||||||
|  |         eat(); | ||||||
|  |         var right = parsePow(); | ||||||
|  |         expr = op == '*' ? MulExpr(expr, right) : DivExpr(expr, right); | ||||||
|  |       } else if (current == '%') { | ||||||
|  |         eat(); | ||||||
|  |         expr = PercentExpr(expr); | ||||||
|       } else { |       } else { | ||||||
|         expr = DivExpr(expr, right); |         // implicit multiplication | ||||||
|  |         var right = parsePow(); | ||||||
|  |         expr = MulExpr(expr, right); | ||||||
|       } |       } | ||||||
|       skipSpaces(); |       skipSpaces(); | ||||||
|     } |     } | ||||||
|     // Handle percentage operator |  | ||||||
|     skipSpaces(); |  | ||||||
|     if (!isEnd && current == '%') { |  | ||||||
|       eat(); |  | ||||||
|       expr = PercentExpr(expr); |  | ||||||
|     } |  | ||||||
|     return expr; |     return expr; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -48,7 +48,30 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | |||||||
|     final input = _controller.text.trim(); |     final input = _controller.text.trim(); | ||||||
|     final normalizedInput = input.replaceAll(' ', ''); |     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)) { |     if (_solverService.isGraphableExpression(normalizedInput)) { | ||||||
|       setState(() { |       setState(() { | ||||||
|         _isFunctionMode = true; |         _isFunctionMode = true; | ||||||
| @@ -57,6 +80,7 @@ class _CalculatorHomePageState extends State<CalculatorHomePage> { | |||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // 普通表达式求解 | ||||||
|     setState(() { |     setState(() { | ||||||
|       _isFunctionMode = false; |       _isFunctionMode = false; | ||||||
|       _isLoading = true; |       _isLoading = true; | ||||||
|   | |||||||
| @@ -54,6 +54,12 @@ class _GraphCardState extends State<GraphCard> { | |||||||
|         (match) => '${match.group(1)}*${match.group(2)}', |         (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 parser = Parser(functionExpr); | ||||||
|       final expr = parser.parse(); |       final expr = parser.parse(); | ||||||
|   | |||||||
| @@ -130,6 +130,10 @@ void main() { | |||||||
|       // 测试无y=前缀的表达式 |       // 测试无y=前缀的表达式 | ||||||
|       final noPrefix = solver.prepareFunctionForGraphing('(x-1)(x+3)'); |       final noPrefix = solver.prepareFunctionForGraphing('(x-1)(x+3)'); | ||||||
|       expect(noPrefix, 'x^2+2x-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