public static double Simulate(List <string> pass3, double[] args) { var list = InfixToAstParser.ShuntingYardAlgorithm(string.Join("", pass3)); string patternToFindLetters = @"[a-z]+$"; List <string> tokens = new List <string>(); foreach (var element in list) { if (element == "sin" || element == "cos" || element == "ctn" || element == "tan" || element == "log" || element == "ex") { tokens.Add(element.ToString()); continue; } if (Regex.IsMatch(element.ToString(), patternToFindLetters)) { double value = args[InfixToAstParser.ExpressionArgs.IndexOf(element.ToString())]; tokens.Add(value.ToString()); } else { tokens.Add(element.ToString()); continue; } } Stack <double> resultStack = new Stack <double>(); foreach (var token in tokens) { double leftOperand; double rightOperand; if (InfixToAstParser.IsNumber(token.ToString())) { resultStack.Push(double.Parse(token.ToString())); } switch (token) { case "+": resultStack.Push(resultStack.Pop() + resultStack.Pop()); break; case "-": rightOperand = resultStack.Pop(); resultStack.Push(resultStack.Pop() - rightOperand); break; case "*": resultStack.Push(resultStack.Pop() * resultStack.Pop()); break; case "/": rightOperand = resultStack.Pop(); leftOperand = resultStack.Pop(); resultStack.Push(leftOperand / rightOperand); break; case "^": rightOperand = resultStack.Pop(); leftOperand = resultStack.Pop(); resultStack.Push(Math.Pow(leftOperand, rightOperand)); break; case "sin": double numberToSin = resultStack.Pop(); resultStack.Push(Math.Sin(numberToSin)); break; case "cos": double numberToCos = resultStack.Pop(); resultStack.Push(Math.Cos(numberToCos)); break; case "ctn": double numberToCtn = resultStack.Pop(); resultStack.Push(1 / Math.Tan(numberToCtn)); break; case "tan": double numberToTan = resultStack.Pop(); resultStack.Push(Math.Tan(numberToTan)); break; case "log": double numberToLog = resultStack.Pop(); resultStack.Push(Math.Log(numberToLog)); break; case "ex": double numberToEx = resultStack.Pop(); resultStack.Push(Math.Exp(numberToEx)); break; } } var result = resultStack.Pop(); return(result); }
public List <string> ThirdPass(AbstractSyntaxTree tree) { Simulator.Postfix.Clear(); Simulator.NodesToPolishNotation(tree); return(InfixToAstParser.PostfixToInfix(Simulator.Postfix).Select(x => Convert.ToString(x)).ToList()); }
public AbstractSyntaxTree SecondPass(AbstractSyntaxTree tree) { Simulator.Postfix.Clear(); Simulator.NodesToPolishNotation(tree); var tokens = InfixToAstParser.ShuntingYardAlgorithm(InfixToAstParser.PostfixToInfix(Simulator.Postfix)); List <string> result = new List <string>(); foreach (var token in tokens) { if (Regex.IsMatch(token, @"cos|sin|tan|ctn|log|ex")) { string operand = result[result.Count - 1]; if (!Regex.IsMatch(operand.ToString(), @"[0-9]+$") || operand == "cos" || operand == "sin" || operand == "tan" || operand == "ctn" || operand == "log" || operand == "ex") { result.Add(token); continue; } result.RemoveAt(result.Count - 1); switch (token) { case "sin": result.Add(Convert.ToString(Math.Sin(Convert.ToDouble(operand)))); break; case "cos": result.Add(Convert.ToString(Math.Cos(Convert.ToDouble(operand)))); break; case "ctn": result.Add(Convert.ToString(1 / Math.Tan(Convert.ToDouble(operand)))); break; case "tan": result.Add(Convert.ToString(Math.Tan(Convert.ToDouble(operand)))); break; case "log": result.Add(Convert.ToString(Math.Log(Convert.ToDouble(operand)))); break; case "ex": result.Add(Convert.ToString(Math.Exp(Convert.ToDouble(operand)))); break; } } const string pattern = @"[a-z]+|[0-9]+$"; if (Regex.IsMatch(token.ToString(), pattern)) { result.Add(token.ToString()); continue; } string rightOperand = result[result.Count - 1]; string leftOperand = result[result.Count - 2]; if (!Regex.IsMatch(rightOperand.ToString(), @"[0-9]+$") || !Regex.IsMatch(leftOperand.ToString(), @"[0-9]+$")) { result.Add(token); continue; } result.RemoveAt(result.Count - 1); result.RemoveAt(result.Count - 1); switch (token) { case "+": result.Add(Convert.ToString(Convert.ToDouble(leftOperand) + Convert.ToDouble(rightOperand))); break; case "-": result.Add(Convert.ToString(Convert.ToDouble(leftOperand) - Convert.ToDouble(rightOperand))); break; case "*": result.Add(Convert.ToString(Convert.ToDouble(leftOperand) * Convert.ToDouble(rightOperand))); break; case "/": result.Add(Convert.ToString(Convert.ToDouble(leftOperand) / Convert.ToDouble(rightOperand))); break; case "^": result.Add(Convert.ToString(Math.Pow(Convert.ToDouble(leftOperand), Convert.ToDouble(rightOperand)))); break; } } return(InfixToAstParser.Parse(InfixToAstParser.PostfixToInfix(result))); }
public AbstractSyntaxTree FirstPass(string expression) { return(InfixToAstParser.BuildTree(expression)); }