private void button1_Click(object sender, EventArgs e) { var parsedFunc = new ParsedFunction(); parsedFunc.StringToParse = " "; parsedFunc.VariableNames = new List <string> { "x", "y", "z" }; parsedFunc.ParameterNames = new List <string> { "p1", "p2" }; parsedFunc.ParameterValues = new[] { 0.0, 0.0 }; var errorData = new FuncParserErrorData(); parsedFunc.Parse(errorData); if (errorData.ErrorNumber == errNumber.err_OK) { MessageBox.Show(this, "That wasn't supposed to happen"); } else { MessageBox.Show(this, $"Error is on purpose. The error is {errorData.ErrorNumber}"); } }
private void ParseFunctions(string fileContents) { MatchCollection matches = FUNCTION_REGEX.Matches(fileContents); // Report on each match. foreach (Match match in matches) { // group[0] is the whole mathed string // group[1] is filled with "native " (yes with spaces) if the function is a native function bool isNative = match.Groups[1].Length != 0; // group[2] is the return type // there are cases where a return statement function call with 0 parameters is parsed as a function // skip these false positives string returnType = match.Groups[2].Value; if (returnType == "return") { continue; } // group[3] is the function name string name = match.Groups[3].Value; // group[4] contains all the parameters in the form // (type name, type name, type name, ...) string allParameters = match.Groups[4].Value.Trim(); ParsedFunction function = new ParsedFunction(isNative, returnType, name, allParameters); functions.Add(function); } }
public ExplicitFormulaParser(IEnumerable <string> variableNames, IEnumerable <string> parameterNames, ParsedFunction parserFunction) { _parserFunc = parserFunction; _parserFunc.SetVariableNames(variableNames.ToList()); _parserFunc.SetParameterNames(parameterNames.ToList()); _parserFunc.LogicalNumericMixAllowed = true; _parserFunc.LogicOperatorsAllowed = true; _parserFunc.SimplifyParametersAllowed = true; }
public void should_return_correct_value_when_partly_simplified(string stringToParse, double expectedValue) { var partlySimplifiedParsedFunction = new ParsedFunction(); partlySimplifiedParsedFunction.UpdateFrom(sut); partlySimplifiedParsedFunction.StringToParse = stringToParse; partlySimplifiedParsedFunction.SetParametersNotToSimplify(new[] { "p1" }); partlySimplifiedParsedFunction.CalcExpression(_arguments).ShouldBeEqualTo(expectedValue); }
public void should_return_correct_value_when_not_simplified(string stringToParse, double expectedValue) { var notSimplifiedParsedFunction = new ParsedFunction(); notSimplifiedParsedFunction.UpdateFrom(sut); notSimplifiedParsedFunction.SimplifyParametersAllowed = false; notSimplifiedParsedFunction.StringToParse = stringToParse; notSimplifiedParsedFunction.CalcExpression(_arguments).ShouldBeEqualTo(expectedValue); }
// override object.Equals public override bool Equals(object obj) { if (obj == null || GetType() != obj.GetType()) { return(false); } ParsedFunction other = (ParsedFunction)obj; return(this.Name == other.Name); }
static void Test3() { var pf = new ParsedFunction(); var stringsToParse = new[] { "1e-3", "1.25e-4", "-2.2e-2", "1e+3", "1.25e+2", "-2.2e+2" }; foreach (var stringToParse in stringsToParse) { pf.StringToParse = stringToParse; pf.Parse(); var d = pf.CalcExpression(null); Console.WriteLine($"f({stringToParse}) = {d}"); } }
protected override void Context() { _parsedFunction = new ParsedFunction(); _variableNames = new List <string> { _var1, _var2 }; _parameterNames = new List <string> { _par1, _par2 }; _variableValues = new[] { 1.0, 2.0 }; _parameterValues = new[] { 3.0, 4.0 }; sut = new ExplicitFormulaParser(_variableNames, _parameterNames, _parsedFunction); }
static void Test1() { var startTime = DateTime.UtcNow; const int NUMBER_ITERATIONS = 100; const int NUMBER_VARIABLES = 100; var variableNames = new List <string>(); var variableValues = new List <double>(); var stringToParse = ""; for (var variableIdx = 1; variableIdx <= NUMBER_VARIABLES; variableIdx++) { var variable = $"V{variableIdx}"; variableNames.Add(variable); stringToParse += variable + (variableIdx < NUMBER_VARIABLES ? "+" : ""); variableValues.Add(variableIdx); } for (var iterationIdx = 0; iterationIdx < NUMBER_ITERATIONS; iterationIdx++) { var pf = new ParsedFunction(); pf.SetVariableNames(variableNames); pf.StringToParse = stringToParse; //pf.Parse(); var xmlString = pf.GetXMLString(); double value = pf.CalcExpression(variableValues); pf = null; } var endTime = DateTime.UtcNow; TimeSpan timeDiff = endTime - startTime; Console.WriteLine($"Duration = {timeDiff.TotalSeconds} seconds"); // Console.WriteLine($"{value}\n{xmlString}\n"); }
static void Test2() { double p1 = 1, p2 = 2, p3 = 3, x = 3, y = 4; var pf = new ParsedFunction(); var caseSensitive = pf.CaseSensitive; pf.CaseSensitive = !caseSensitive; caseSensitive = pf.CaseSensitive; Console.WriteLine($"CaseSensitive={caseSensitive}"); pf.SetVariableNames(new[] { "x", "y" }); pf.SetParameterNames(new[] { "p1", "p2", "p3" }); pf.SetParameterValues(new[] { p1, p2, p3 }); pf.SetParametersNotToSimplify(new[] { "p3" }); pf.SimplifyParametersAllowed = true; pf.LogicOperatorsAllowed = false; pf.LogicalNumericMixAllowed = false; pf.ComparisonTolerance = 0.1; pf.StringToParse = "2*p1+3*p2+p3+x*y"; var stringToParse = pf.StringToParse; pf.Parse(); Console.WriteLine("Parse: OK"); var value = pf.CalcExpression(new[] { x, y }); Console.WriteLine($"p1={p1} p2={p2} p3={p3} x={x} y={y}\n"); Console.WriteLine($"{stringToParse} = {value}\n"); var xmlString = pf.GetXMLString(); Console.WriteLine($"{xmlString}\n"); pf = null; pf = new ParsedFunction(); pf.SetVariableNames(new[] { "x", "y" }); pf.StringToParse = "x+t"; pf.Parse(); }
public virtual string evaluate(bool wrapStringFunctionResults) { string rtnResult = null; // Get the left operand. string leftResultString = null; double?leftResultDouble = null; if (leftOperand is ExpressionTree) { leftResultString = ((ExpressionTree)leftOperand).evaluate(wrapStringFunctionResults); try { leftResultDouble = Convert.ToDouble(leftResultString); leftResultString = null; } catch (System.FormatException) { leftResultDouble = null; } } else if (leftOperand is ExpressionOperand) { ExpressionOperand leftExpressionOperand = (ExpressionOperand)leftOperand; leftResultString = leftExpressionOperand.Value; leftResultString = evaluator.replaceVariables(leftResultString); if (!evaluator.isExpressionString(leftResultString)) { try { leftResultDouble = Convert.ToDouble(leftResultString); leftResultString = null; } catch (System.FormatException nfe) { throw new EvaluationException("Expression is invalid.", nfe); } if (leftExpressionOperand.UnaryOperator != null) { leftResultDouble = new double?(leftExpressionOperand.UnaryOperator.evaluate(leftResultDouble.Value)); } } else { if (leftExpressionOperand.UnaryOperator != null) { throw new EvaluationException("Invalid operand for " + "unary operator."); } } } else if (leftOperand is ParsedFunction) { ParsedFunction parsedFunction = (ParsedFunction)leftOperand; Function function = parsedFunction.Function; string arguments = parsedFunction.Arguments; arguments = evaluator.replaceVariables(arguments); if (evaluator.ProcessNestedFunctions) { arguments = evaluator.processNestedFunctions(arguments); } try { FunctionResult functionResult = function.execute(evaluator, arguments); leftResultString = functionResult.Result; if (functionResult.Type == FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC) { double?resultDouble = Convert.ToDouble(leftResultString); if (parsedFunction.UnaryOperator != null) { resultDouble = new double?(parsedFunction.UnaryOperator.evaluate(resultDouble.Value)); } // Get the final result. leftResultString = resultDouble.ToString(); } else if (functionResult.Type == FunctionConstants.FUNCTION_RESULT_TYPE_STRING) { // The result must be a string result. if (wrapStringFunctionResults) { leftResultString = evaluator.QuoteCharacter + leftResultString + evaluator.QuoteCharacter; } if (parsedFunction.UnaryOperator != null) { throw new EvaluationException("Invalid operand for " + "unary operator."); } } } catch (FunctionException fe) { throw new EvaluationException(fe.Message, fe); } if (!evaluator.isExpressionString(leftResultString)) { try { leftResultDouble = Convert.ToDouble(leftResultString); leftResultString = null; } catch (System.FormatException nfe) { throw new EvaluationException("Expression is invalid.", nfe); } } } else { if (leftOperand != null) { throw new EvaluationException("Expression is invalid."); } } // Get the right operand. string rightResultString = null; double?rightResultDouble = null; if (rightOperand is ExpressionTree) { rightResultString = ((ExpressionTree)rightOperand).evaluate(wrapStringFunctionResults); try { rightResultDouble = Convert.ToDouble(rightResultString); rightResultString = null; } catch (System.FormatException) { rightResultDouble = null; } } else if (rightOperand is ExpressionOperand) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final ExpressionOperand rightExpressionOperand = (ExpressionOperand) rightOperand; ExpressionOperand rightExpressionOperand = (ExpressionOperand)rightOperand; rightResultString = ((ExpressionOperand)rightOperand).Value; rightResultString = evaluator.replaceVariables(rightResultString); // Check if the operand is a string or not. If it not a string, // then it must be a number. if (!evaluator.isExpressionString(rightResultString)) { try { rightResultDouble = Convert.ToDouble(rightResultString); rightResultString = null; } catch (System.FormatException nfe) { throw new EvaluationException("Expression is invalid.", nfe); } if (rightExpressionOperand.UnaryOperator != null) { rightResultDouble = new double?(rightExpressionOperand.UnaryOperator.evaluate(rightResultDouble.Value)); } } else { if (rightExpressionOperand.UnaryOperator != null) { throw new EvaluationException("Invalid operand for " + "unary operator."); } } } else if (rightOperand is ParsedFunction) { ParsedFunction parsedFunction = (ParsedFunction)rightOperand; Function function = parsedFunction.Function; string arguments = parsedFunction.Arguments; arguments = evaluator.replaceVariables(arguments); if (evaluator.ProcessNestedFunctions) { arguments = evaluator.processNestedFunctions(arguments); } try { FunctionResult functionResult = function.execute(evaluator, arguments); rightResultString = functionResult.Result; if (functionResult.Type == FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC) { double?resultDouble = Convert.ToDouble(rightResultString); // Process a unary operator if one exists. if (parsedFunction.UnaryOperator != null) { resultDouble = new double?(parsedFunction.UnaryOperator.evaluate(resultDouble.Value)); } // Get the final result. rightResultString = resultDouble.ToString(); } else if (functionResult.Type == FunctionConstants.FUNCTION_RESULT_TYPE_STRING) { // The result must be a string result. if (wrapStringFunctionResults) { rightResultString = evaluator.QuoteCharacter + rightResultString + evaluator.QuoteCharacter; } if (parsedFunction.UnaryOperator != null) { throw new EvaluationException("Invalid operand for " + "unary operator."); } } } catch (FunctionException fe) { throw new EvaluationException(fe.Message, fe); } if (!evaluator.isExpressionString(rightResultString)) { try { rightResultDouble = Convert.ToDouble(rightResultString); rightResultString = null; } catch (System.FormatException nfe) { throw new EvaluationException("Expression is invalid.", nfe); } } } else if (rightOperand == null) { // Do nothing. } else { throw new EvaluationException("Expression is invalid."); } // Evaluate the the expression. if (leftResultDouble != null && rightResultDouble != null) { double doubleResult = @operator.evaluate(leftResultDouble.Value, rightResultDouble.Value); if (UnaryOperator != null) { doubleResult = UnaryOperator.evaluate(doubleResult); } rtnResult = (new double?(doubleResult)).ToString(); } else if (!string.ReferenceEquals(leftResultString, null) && !string.ReferenceEquals(rightResultString, null)) { rtnResult = @operator.evaluate(leftResultString, rightResultString); } else if (leftResultDouble != null && rightResultDouble == null) { double doubleResult = -1; if (unaryOperator != null) { doubleResult = unaryOperator.evaluate(leftResultDouble.Value); } else { // Do not allow numeric (left) and // string (right) to be evaluated together. throw new EvaluationException("Expression is invalid."); } rtnResult = (new double?(doubleResult)).ToString(); } else { throw new EvaluationException("Expression is invalid."); } return(rtnResult); }
private string getResult(Stack operatorStack, Stack operandStack, bool wrapStringFunctionResults) { // The result to return. string resultString = null; // Process the rest of the operators left on the stack. while (operatorStack.Count > 0) { processTree(operandStack, operatorStack); } if (operandStack.Count != 1) { throw new EvaluationException("Expression is invalid."); } object finalOperand = operandStack.Pop(); // Check if the final operand is a tree. if (finalOperand is ExpressionTree) { // Get the final result. resultString = ((ExpressionTree)finalOperand).evaluate(wrapStringFunctionResults); } // Check if the final operand is an operand. else if (finalOperand is ExpressionOperand) { ExpressionOperand resultExpressionOperand = (ExpressionOperand)finalOperand; resultString = ((ExpressionOperand)finalOperand).Value; resultString = replaceVariables(resultString); // Check if the operand is a string or not. If it not a string, // then it must be a number. if (!isExpressionString(resultString)) { double?resultDouble = null; try { resultDouble = Convert.ToDouble(resultString); } catch (Exception e) { throw new EvaluationException("Expression is invalid.", e); } // Process a unary operator if one exists. if (resultExpressionOperand.UnaryOperator != null) { resultDouble = new double?(resultExpressionOperand.UnaryOperator.evaluate(resultDouble.Value)); } // Get the final result. resultString = resultDouble.ToString(); } else { if (resultExpressionOperand.UnaryOperator != null) { throw new EvaluationException("Invalid operand for " + "unary operator."); } } } else if (finalOperand is ParsedFunction) { ParsedFunction parsedFunction = (ParsedFunction)finalOperand; Function function = parsedFunction.Function; string arguments = parsedFunction.Arguments; if (processNestedFunctions_Renamed) { arguments = processNestedFunctions(arguments); } arguments = replaceVariables(arguments); // Get the final result. try { FunctionResult functionResult = function.execute(this, arguments); resultString = functionResult.Result; if (functionResult.Type == FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC) { double?resultDouble = Convert.ToDouble(resultString); // Process a unary operator if one exists. if (parsedFunction.UnaryOperator != null) { resultDouble = new double?(parsedFunction.UnaryOperator.evaluate(resultDouble.Value)); } // Get the final result. resultString = resultDouble.ToString(); } else if (functionResult.Type == FunctionConstants.FUNCTION_RESULT_TYPE_STRING) { // The result must be a string result. if (wrapStringFunctionResults) { resultString = quoteCharacter + resultString + quoteCharacter; } if (parsedFunction.UnaryOperator != null) { throw new EvaluationException("Invalid operand for " + "unary operator."); } } } catch (FunctionException fe) { throw new EvaluationException(fe.Message, fe); } } else { throw new EvaluationException("Expression is invalid."); } return(resultString); }
private NextOperator processFunction(string expression, int operatorIndex, Stack operandStack) { int parenthesisCount = 1; NextOperator nextOperator = null; int nextOperatorIndex = operatorIndex; // Loop until we find the function's closing parentheses. while (parenthesisCount > 0) { nextOperator = getNextOperator(expression, nextOperatorIndex + 1, null); if (nextOperator == null) { throw new EvaluationException("Function is not closed."); } else if (nextOperator.Operator is OpenParenthesesOperator) { parenthesisCount++; } else if (nextOperator.Operator is ClosedParenthesesOperator) { parenthesisCount--; } // Get the next operator index. nextOperatorIndex = nextOperator.Index; } string arguments = expression.Substring(operatorIndex + 1, nextOperatorIndex - (operatorIndex + 1)); // Pop the function name from the stack. ExpressionOperand operand = (ExpressionOperand)operandStack.Pop(); Operator unaryOperator = operand.UnaryOperator; string functionName = operand.Value; // Validate that the function name is valid. try { isValidName(functionName); } catch (System.ArgumentException iae) { throw new EvaluationException("Invalid function name of \"" + functionName + "\".", iae); } // Get the function object. //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final net.sourceforge.jeval.function.Function function = (net.sourceforge.jeval.function.Function) functions.get(functionName); Function function = (Function)functions[functionName]; if (function == null) { throw new EvaluationException("A function is not defined (index=" + operatorIndex + ")."); } ParsedFunction parsedFunction = new ParsedFunction(function, arguments, unaryOperator); operandStack.Push(parsedFunction); return(nextOperator); }