/// <summary> /// Take each token string from the list of postfixedtokens and build a parse tree /// with each node evaluated when possible. /// </summary> internal void AppendFunction(IToken token) { int numberOfChildLeafs =0; FunctionToken functToken= null; switch (token.Type) { case TokenType.function: functToken = (FunctionToken)token; numberOfChildLeafs = functToken.numberOfChildren; break; case TokenType.infixOperator: numberOfChildLeafs = 2; break; case TokenType.suffixOperator: numberOfChildLeafs = 1; break; } //TODO: In the parser you must keep count of the amount of children and pass that number here //also have restrictions in certain cases string tokenString = token.TokenString; TreeNode child = new TreeNode(); child.type = nodeType.operation; child.name = tokenString; TreeNode[] childLeafNodes = new TreeNode[numberOfChildLeafs]; for (int i = 0; i < numberOfChildLeafs; i++) { if (children.Count() == 0) throw new Exception("Post fixed token notation error."); childLeafNodes[i] = children[0]; children.RemoveAt(0); child.children.Insert(0, childLeafNodes[i]); } if (childLeafNodes.All(i => i.numericalEvaluation)) { child.numericalEvaluation = true; List<Complex> paramaters = childLeafNodes.Select(i => i.val).ToList(); if (token.Type == TokenType.suffixOperator || token.Type == TokenType.infixOperator) child.val = postFixedOperatorEvaluator(paramaters, tokenString); else if (token.Type == TokenType.function) { //TODO: You should be evaluating parse trees not Complex values child.val = functToken.Function.Compute(paramaters); } else throw new Exception("Not operator or function can't evaluate"); } flattenTieredAddOrMult(child); children.Insert(0, child); }
/// <summary> /// For commutative operations its possible to have one operation node with many children /// instead of tiered iterations of the operation. This method is to change from the /// latter to the former.</summary> private void flattenTieredAddOrMult(TreeNode node) { TreeNode adjustedNode = new TreeNode(); switch (node.name) { case "+": for (int i = 0; i < node.children.Count(); i++) { if (node.children[i].name == "+") { adjustedNode = node.children[i]; node.children.RemoveAt(i); foreach (TreeNode t in adjustedNode.children) { node.children.Add(t); } } } break; case "*": List<int> commonFactors = new List<int>(); for(int i=0; i < node.children.Count(); i++){ if (node.children[i].name == "*") { adjustedNode = node.children[i]; node.children.RemoveAt(i); foreach (TreeNode t in adjustedNode.children) { node.children.Add(t); } } } if (this.numericalEvaluation) { //this means that all the children are numbers and we have evaluated //TODO: take out the common factors from val.factors //Make it work by using exponents } break; } }
internal bool AppendVariable(string variableName) { TreeNode child = new TreeNode(); child.type = nodeType.number; switch (variableName) { case "PI": child.val = PI.value; child.name = child.val.ToString(); break; default: ErrorLog.Add(new ErrorMessage("Unknown variable can't be appendend")); return false; } child.numericalEvaluation = true; children.Insert(0, child); //clear the static visualization output string: output = string.Empty; return true; }
internal void AppendNumber(NumberToken token) { Complex tokenVal = token.TokenNumValue; TreeNode child = new TreeNode(); child.type = nodeType.number; child.val = tokenVal; child.name = tokenVal.ToString(); child.numericalEvaluation = true; children.Insert(0, child); //clear the static visualization output string: output = string.Empty; }
internal bool AppendKeyword(string keyword) { TreeNode child = new TreeNode(); child.type = nodeType.number; switch (keyword) { case "ANS": Complex tokenVal = (Complex)OutputLog.returnValues.Last(); child.val = tokenVal; child.name = tokenVal.ToString(); break; default: ErrorLog.Add(new ErrorMessage("Unknown variable can't be appendend")); return false; } child.numericalEvaluation = true; children.Insert(0, child); //clear the static visualization output string: output = string.Empty; return true; }
public TreeNode BuildParseTree() { TreeNode parseTree = new TreeNode(); foreach (IToken token in InAList) { switch (token.Type) { case TokenType.keyword: if (!parseTree.AppendKeyword(token.TokenString)) return null; break; case TokenType.number: parseTree.AppendNumber((NumberToken)token); break; case TokenType.infixOperator: parseTree.AppendFunction(token); break; case TokenType.suffixOperator: parseTree.AppendFunction(token); break; case TokenType.variable: if (!parseTree.AppendVariable(token.TokenString.ToUpper())) { return null; } break; case TokenType.function: parseTree.AppendFunction((FunctionToken)token); break; default: ErrorLog.Add(new ErrorMessage("Fatal parsing error: this token type is unknown cannot be appended to the parse tree")); return null; } } if (parseTree.children.Count() > 0) //The root node is always redundant by construction return parseTree.children.First(); else return null; }