/// <summary> /// Parses <paramref name="expression"/> into new <see cref="Expressions.Expression"/> object and inserts it into internal data structure. /// </summary> /// <param name="expression">Expression in string format</param> /// <param name="negative">Whether expression result should be negative</param> /// <param name="instanceCreator">Parser instance creator for parsing sub-expressions</param> /// <returns></returns> public ExpressionBuilder Expression(string expression, bool negative, ConstructNewParser instanceCreator) { IExpressionParser parser = instanceCreator.Invoke(); Expression expr = parser.Parse(expression, instanceCreator); expr.Negative = negative; components.AddLast(expr); return(this); }
/// <summary> /// Reads function which has no parameters /// </summary> /// <param name="funcName">Function key - such as <code>sin</code></param> /// <param name="negative">Whether function value should be negative</param> /// <param name="instanceCreator">Parser instance creator for parsing sub-expressions</param> protected void ParseNoParameterFunction(string funcName, bool negative, ConstructNewParser instanceCreator) { Function function = Functions.FindFunction(funcName); if (function.InputCount != 0) { throw new InvalidExpressionSyntaxException("Invalid function syntax"); } expressionBuilder.Function(function, "", negative, instanceCreator); }
private IMathComponent[] ConvertToComponents(string[] expressionArray, ConstructNewParser instanceCreator) { IMathComponent[] mathComponents = new IMathComponent[expressionArray.Length]; for (int i = 0; i < expressionArray.Length; i++) { IExpressionParser parser = instanceCreator.Invoke(); Expression expression = parser.Parse(expressionArray[i], instanceCreator); mathComponents[i] = expression; } return(mathComponents); }
public Expression Parse(string expression, ConstructNewParser instanceCreator) { expressionBuilder = new ExpressionBuilder(); int len = expression.Length; StartReading(expression, out int readerIndex, instanceCreator); while (readerIndex < len) { if (ReadingValue) { ParseValue(expression, ref readerIndex, false, instanceCreator); ReadingValue = false; } else { ParseOperator(expression, ref readerIndex); ReadingValue = true; } } return(expressionBuilder.Build()); }
/// <summary> /// Reads first component of <paramref name="expression"/>. Handles negative expressions /// </summary> /// <param name="expression">Expression which is being parsed</param> /// <param name="readerIndex">Position in expression</param> /// <param name="instanceCreator">Parser instance creator for parsing sub-expressions</param> protected virtual void StartReading(string expression, out int readerIndex, ConstructNewParser instanceCreator) { readerIndex = 0; if (expression.Length == 0) { return; } if (expression[readerIndex] == '(') { ++readerIndex; ParseExpression(expression, ref readerIndex, false, instanceCreator); return; } bool negative = false; if (expression[readerIndex] == '-') { negative = true; ++readerIndex; } ParseValue(expression, ref readerIndex, negative, instanceCreator); }
/// <summary> /// Converts Function and it's parameters to math component and inserts it into internal data structure. /// </summary> /// <param name="function">Function type</param> /// <param name="funcExpression">Function parameter expression. Can be empty string if function has no parameters. Parameters must be separated by <see cref="Expressions.Function.FUNCTION_PARAMETER_SEPARATOR"/></param> /// <param name="negative">Whether function result should be negative</param> /// <param name="instanceCreator">Parser instance creator for parsing sub-expressions</param> /// <returns>This builder</returns> public ExpressionBuilder Function(Function function, string funcExpression, bool negative, ConstructNewParser instanceCreator) { string[] parameters; if (funcExpression.Length == 0) { parameters = new string[0]; } else { parameters = funcExpression.Split(Expressions.Function.FUNCTION_PARAMETER_SEPARATOR); } IMathComponent component = new OperationComponent(new FunctionInstance(function, parameters.Length == 0 ? new IMathComponent[0] : ConvertToComponents(parameters, instanceCreator))) { Negative = negative }; components.AddLast(component); return(this); }
/// <summary> /// Converts Function and it's parameters to math component and inserts it into internal data structure. /// Internally calls <see cref="Function(Expressions.Function, string, bool, ConstructNewParser)"/> with <code>false</code> negative parameter /// </summary> /// <param name="function">Function type</param> /// <param name="funcExpression">Function parameter expression. Can be empty string if function has no parameters. /// Parameters must be separated by <see cref="Expressions.Function.FUNCTION_PARAMETER_SEPARATOR"/></param> /// <param name="instanceCreator">Parser instance creator for parsing sub-expressions</param> /// <returns>This builder</returns> public ExpressionBuilder Function(Function function, string funcExpression, ConstructNewParser instanceCreator) { return(Function(function, funcExpression, false, instanceCreator)); }
/// <summary> /// Parses <paramref name="expression"/> into new <see cref="Expressions.Expression"/> object and inserts it into internal data structure. /// Internally calls <see cref="Expression(string, bool, ConstructNewParser)"/> with <code>false</code> negative parameter /// </summary> /// <param name="expression">Expression in string format</param> /// <param name="instanceCreator">Parser instance creator for parsing sub-expressions</param> /// <returns>This builder</returns> public ExpressionBuilder Expression(string expression, ConstructNewParser instanceCreator) { return(Expression(expression, false, instanceCreator)); }
/// <summary> /// Constructs new instance of expression processor /// </summary> /// <param name="instanceCreator"></param> public ExpressionProcessor(ConstructNewParser instanceCreator) { InstanceCreator = instanceCreator; }
/// <summary> /// Reads value from expression. /// </summary> /// <param name="expression">Expression which is being parsed</param> /// <param name="readerIndex">Position in expression</param> /// <param name="negative">Whether parsed value should be negative</param> /// <param name="instanceCreator">Parser instance creator for parsing sub-expressions</param> protected virtual void ParseValue(string expression, ref int readerIndex, bool negative, ConstructNewParser instanceCreator) { // number / function / expression if (readerIndex >= expression.Length) { return; } char firstCharacter = expression[readerIndex]; if (firstCharacter == '(') { ++readerIndex; ParseExpression(expression, ref readerIndex, negative, instanceCreator); } else if (char.IsDigit(firstCharacter)) { ReadNumber(expression, ref readerIndex, negative); } else if (VALID_FUNCTION_CHARACTERS.IsMatch(firstCharacter.ToString())) { ParseFunction(expression, ref readerIndex, negative, instanceCreator); } }
/// <summary> /// Reads sub-expression from <paramref name="expression"/> /// </summary> /// <param name="expression">Expression being parsed</param> /// <param name="readerIndex">Position in expression</param> /// <param name="negative">Whether expression value should be negative</param> /// <param name="instanceCreator">Parser instance creator for parsing sub-expressions</param> protected void ParseExpression(string expression, ref int readerIndex, bool negative, ConstructNewParser instanceCreator) { expressionBuilder.Expression(GetExpression(expression, ref readerIndex), negative, instanceCreator); }
/// <summary> /// Reads function from expression string /// </summary> /// <param name="expression">Expression which is being parsed</param> /// <param name="readerIndex">Position in expression</param> /// <param name="negative">Whether function value should be negative</param> /// <param name="instanceCreator">Parser instance creator for parsing sub-expressions</param> protected void ParseFunction(string expression, ref int readerIndex, bool negative, ConstructNewParser instanceCreator) { StringBuilder functionString = new StringBuilder(); functionString.Append(expression[readerIndex++]); if (readerIndex >= expression.Length) { ParseNoParameterFunction(functionString.ToString(), negative, instanceCreator); return; } while (readerIndex < expression.Length) { char character = expression[readerIndex]; if (VALID_FUNCTION_CHARACTERS.IsMatch(character.ToString())) { functionString.Append(character); ++readerIndex; if (readerIndex >= expression.Length) { ParseNoParameterFunction(functionString.ToString(), negative, instanceCreator); break; } } else if (character == '(') { Function function = Functions.FindFunction(functionString.ToString()); readerIndex++; string parameters = GetExpression(expression, ref readerIndex); expressionBuilder.Function(function, parameters, negative, instanceCreator); break; } else { ParseNoParameterFunction(functionString.ToString(), negative, instanceCreator); break; } } }