internal string ConvertToReversePolishNotation(string expression) { int pos = 0; // Current position of lexical analysis StringBuilder outputString = new StringBuilder(); Stack <MathMetaBase> stack = new Stack <MathMetaBase>(); // While there is unhandled char in expression while (pos < expression.Length) { IMathMeta token = LexicalAnalysisInFixNotation(expression, ref pos); outputString = SyntaxAnalysisInfixNotation(token, outputString, stack); } // Pop all elements from stack to output string while (stack.Count > 0) { // There should be only operators if (stack.Peek().IsOperator()) { outputString.Append(stack.Pop()); } else { throw new FormatException("Format exception," + " there is function without parenthesis"); } } return(outputString.ToString()); }
public static NumberResult AsNumber(this IMathMeta meta) { if (meta.IsNumber()) { return(meta as NumberResult); } throw new ArgumentException("meta is not a number!"); }
public static double GetNumber(this IMathMeta meta) { if (meta.IsNumber()) { return((NumberResult)meta); } throw new ArgumentException("unexpected \"number-->object\" cast." + " Numbers should parsed as " + typeof(NumberResult).FullName + " type!"); }
public StringBuilder SyntaxAnalysisInfixNotation(IMathMeta token, StringBuilder outputString, Stack <MathMetaBase> block) { if (token.IsNumber()) { outputString.Append(token.ToString()); } else if (token.IsFunction() || token.GetType().IsAssignableFrom(typeof(LeftParenthesis)) ) { block.Push(token as MathMetaBase); } else if (token.GetType().IsAssignableFrom(typeof(RightParenthesis))) { string elem; while ((elem = block.Pop().ToString()) != new LeftParenthesis().ToString()) { outputString.Append(elem); } if (block.Count > 0 && block.Peek().IsFunction()) { outputString.Append(block.Pop()); } } else { while (block.Count > 0 && (token as MathMetaBase) < block.Peek()) { outputString.Append(block.Pop().ToString()); } block.Push(token as MathMetaBase); } return(outputString); }
private Stack <double> SyntaxAnalysisRPN(Stack <double> stack, IMathMeta token) { // if it's operand then just push it to stack if (token.IsNumber()) { stack.Push(token.GetNumber()); } else { double rst = 0; Stack <double> arguments = new Stack <double>(); for (int i = 0; i < token.NumberOfArguments; i++) { arguments.Push(stack.Pop()); } token.Operate(ref rst, arguments.ToArray()); stack.Push(rst); } return(stack); }
public static bool IsOperator(this IMathMeta meta) { return(meta.Is(typeof(IMathOperator))); }
public static bool IsFunction(this IMathMeta meta) { return(meta.Is(typeof(IMathFunction))); }
public static bool Is(this IMathMeta meta, Type @interface) { return(@interface.IsAssignableFrom(meta.GetType())); }
public static double GetValue(this IMathMeta meta) { var value = meta.AsNumber(); return(value.Value); }
public static bool IsNumber(this IMathMeta meta) { return(typeof(NumberResult).IsAssignableFrom(meta.GetType())); }