From 1a04db2d7c3cd5360f178cbccfde7f67cdfa3d4d Mon Sep 17 00:00:00 2001 From: toolgood Date: Tue, 18 Jan 2022 19:22:28 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20EvaluateFormula?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AlgorithmEngineExTest.cs | 3 + csharp/ToolGood.Algorithm2/AlgorithmEngine.cs | 6 +- .../ToolGood.Algorithm2/AlgorithmEngineEx.cs | 86 ++++++++++++++++- .../toolgood/algorithm/AlgorithmEngine.java | 2 +- .../toolgood/algorithm/AlgorithmEngineEx.java | 92 +++++++++++++++++++ .../Test2/AlgorithmEngineExTest.java | 3 + 6 files changed, 187 insertions(+), 5 deletions(-) diff --git a/csharp/ToolGood.Algorithm2.Test/AlgorithmEngineEx/AlgorithmEngineExTest.cs b/csharp/ToolGood.Algorithm2.Test/AlgorithmEngineEx/AlgorithmEngineExTest.cs index 7bf06ef8..85e394b6 100644 --- a/csharp/ToolGood.Algorithm2.Test/AlgorithmEngineEx/AlgorithmEngineExTest.cs +++ b/csharp/ToolGood.Algorithm2.Test/AlgorithmEngineEx/AlgorithmEngineExTest.cs @@ -65,6 +65,9 @@ public void Test() var p4 = priceAlgorithm.TryEvaluate("出错了", 0.0); + + var tt = priceAlgorithm.EvaluateFormula("长-宽-高", '-'); + Assert.AreEqual("9-1.3-1", tt); } [Test] public void Test2() diff --git a/csharp/ToolGood.Algorithm2/AlgorithmEngine.cs b/csharp/ToolGood.Algorithm2/AlgorithmEngine.cs index d73e18c2..1585bf92 100644 --- a/csharp/ToolGood.Algorithm2/AlgorithmEngine.cs +++ b/csharp/ToolGood.Algorithm2/AlgorithmEngine.cs @@ -718,7 +718,7 @@ public String EvaluateFormula(String formula, params char[] splitChars) /// 公式 /// 分隔符 /// - public String EvaluateFormula(String formula, List splitChars) + public virtual String EvaluateFormula(String formula, List splitChars) { if (string.IsNullOrEmpty(formula)) return ""; @@ -732,11 +732,11 @@ public String EvaluateFormula(String formula, List splitChars) } else { // TODO 替换此处 String d = TryEvaluate(s, ""); - stringBuilder.Append(d.ToString()); + stringBuilder.Append(d); } } return stringBuilder.ToString(); - } + } #endregion } diff --git a/csharp/ToolGood.Algorithm2/AlgorithmEngineEx.cs b/csharp/ToolGood.Algorithm2/AlgorithmEngineEx.cs index ce3ff6ab..ccf16bc2 100644 --- a/csharp/ToolGood.Algorithm2/AlgorithmEngineEx.cs +++ b/csharp/ToolGood.Algorithm2/AlgorithmEngineEx.cs @@ -1,4 +1,5 @@ -using System; +using Antlr4.Runtime; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -736,5 +737,88 @@ private Operand Evaluate(ProgContext context) } + #region EvaluateFormula + /// + /// 计算公式 + /// + /// 公式 + /// 分隔符 + /// + public String EvaluateFormula(String formula, params char[] splitChars) + { + if (string.IsNullOrEmpty(formula)) return ""; + return EvaluateFormula(formula, splitChars.ToList()); + } + /// + /// 计算公式 + /// + /// 公式 + /// 分隔符 + /// + public virtual String EvaluateFormula(String formula, List splitChars) + { + if (string.IsNullOrEmpty(formula)) return ""; + + List sp = CharUtil.SplitFormula(formula, splitChars); + + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < sp.Count; i++) { + String s = sp[i]; + if (s.Length == 1 && splitChars.Contains(s[0])) { + stringBuilder.Append(s); + } else { + String d = ""; + try { + Operand operand = EvaluateOnce(s); + d = operand.ToText().TextValue; + } catch (Exception) { } + stringBuilder.Append(d); + } + } + return stringBuilder.ToString(); + } + /// + /// 执行一次 + /// + /// + /// + protected Operand EvaluateOnce(string exp) + { + ProgContext context = Parse(exp); + return Evaluate(context); + } + + private ProgContext Parse(string exp) + { + if (string.IsNullOrWhiteSpace(exp)) { return null; } + try { + var stream = new AntlrCharStream(new AntlrInputStream(exp)); + var lexer = new mathLexer(stream); + var tokens = new CommonTokenStream(lexer); + var parser = new mathParser(tokens); + var antlrErrorListener = new AntlrErrorListener(); + parser.RemoveErrorListeners(); + parser.AddErrorListener(antlrErrorListener); + + var context = parser.prog(); + var end = context.Stop.StopIndex; + if (end + 1 < exp.Length) { + + LastError = "Parameter exp invalid !"; + return null; + } + if (antlrErrorListener.IsError) { + LastError = antlrErrorListener.ErrorMsg; + return null; + } + return context; + } catch (Exception ex) { + LastError = ex.Message; + } + return null; + } + #endregion + + } } diff --git a/java/toolgood.algorithm/src/main/java/toolgood/algorithm/AlgorithmEngine.java b/java/toolgood.algorithm/src/main/java/toolgood/algorithm/AlgorithmEngine.java index 3b991617..7d5f8ce1 100644 --- a/java/toolgood.algorithm/src/main/java/toolgood/algorithm/AlgorithmEngine.java +++ b/java/toolgood.algorithm/src/main/java/toolgood/algorithm/AlgorithmEngine.java @@ -306,7 +306,7 @@ public String EvaluateFormula(String formula, List splitChars) { } else { // TODO 替换此处 String d = TryEvaluate(s, ""); - stringBuilder.append(d.toString()); + stringBuilder.append(d); } } return stringBuilder.toString(); diff --git a/java/toolgood.algorithm/src/main/java/toolgood/algorithm/AlgorithmEngineEx.java b/java/toolgood.algorithm/src/main/java/toolgood/algorithm/AlgorithmEngineEx.java index fc0350a9..5ac576d7 100644 --- a/java/toolgood.algorithm/src/main/java/toolgood/algorithm/AlgorithmEngineEx.java +++ b/java/toolgood.algorithm/src/main/java/toolgood/algorithm/AlgorithmEngineEx.java @@ -7,13 +7,20 @@ import java.util.Map; import java.util.function.Function; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; import org.joda.time.DateTime; +import toolgood.algorithm.internals.AntlrCharStream; +import toolgood.algorithm.internals.AntlrErrorListener; +import toolgood.algorithm.internals.CharUtil; import toolgood.algorithm.internals.ConditionCacheInfo; import toolgood.algorithm.internals.MathVisitor; import toolgood.algorithm.internals.MyFunction; import toolgood.algorithm.litJson.JsonData; import toolgood.algorithm.litJson.JsonMapper; +import toolgood.algorithm.math.mathLexer; +import toolgood.algorithm.math.mathParser; import toolgood.algorithm.math.mathParser2.ProgContext; /** @@ -374,4 +381,89 @@ private Operand Evaluate(ProgContext context) { } } + /** + * 计算公式 + * + * @param formula 公式 + * @param splitChar 分隔符 + * @return + */ + public String EvaluateFormula(String formula, Character splitChar) { + if (formula == null || formula.equals("")) + return ""; + List splitChars = new ArrayList<>(); + splitChars.add(splitChar); + return EvaluateFormula(formula, splitChars); + } + + /** + * 计算公式 + * + * @param formula 公式 + * @param splitChars 分隔符 + * @return + */ + public String EvaluateFormula(String formula, List splitChars) { + if (formula == null || formula.equals("")) + return ""; + List sp = CharUtil.SplitFormula(formula, splitChars); + + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < sp.size(); i++) { + String s = sp.get(i); + if (s.length() == 1 && splitChars.contains(s.charAt(0))) { + stringBuilder.append(s); + } else { + String d = ""; + try { + Operand operand = EvaluateOnce(s); + d = operand.ToText("").TextValue(); + } catch (Exception ex) { } + stringBuilder.append(d); + } + } + return stringBuilder.toString(); + } + + /// + /// 执行一次 + /// + /// + /// + protected Operand EvaluateOnce(String exp) { + ProgContext context = Parse(exp); + return Evaluate(context); + } + + private ProgContext Parse(String exp) { + if (exp == null || exp.equals("")) { + LastError = "Parameter exp invalid !"; + return null; + } + try { + final AntlrCharStream stream = new AntlrCharStream(CharStreams.fromString(exp)); + final mathLexer lexer = new mathLexer(stream); + final CommonTokenStream tokens = new CommonTokenStream(lexer); + final mathParser parser = new mathParser(tokens); + final AntlrErrorListener antlrErrorListener = new AntlrErrorListener(); + parser.removeErrorListeners(); + parser.addErrorListener(antlrErrorListener); + final ProgContext context = parser.prog(); + + final int end = context.stop.getStopIndex(); + if (end + 1 < exp.length()) { + LastError = "Parameter exp invalid !"; + return null; + } + if (antlrErrorListener.IsError) { + LastError = antlrErrorListener.ErrorMsg; + return null; + } + return context; + } catch (Exception ex) { + LastError = ex.getMessage(); + } + return null; + } + } diff --git a/java/toolgood.algorithm/src/test/java/toolgood/algorithm/Test2/AlgorithmEngineExTest.java b/java/toolgood.algorithm/src/test/java/toolgood/algorithm/Test2/AlgorithmEngineExTest.java index eb8dcdd9..7b234ab7 100644 --- a/java/toolgood.algorithm/src/test/java/toolgood/algorithm/Test2/AlgorithmEngineExTest.java +++ b/java/toolgood.algorithm/src/test/java/toolgood/algorithm/Test2/AlgorithmEngineExTest.java @@ -105,6 +105,9 @@ public void Test2() { Double p4 = priceAlgorithm.TryEvaluate("出错了", 0.0); + String tt = priceAlgorithm.EvaluateFormula("长-宽-高", '-'); + assertEquals("9-1.3-1", tt); + } @Test