public void GenTestTree() { Operator root = new Operator("x"); root.LeftChild = new Number("4"); root.RightChild = new Number("1"); tree = root; }
public void Test() { var node1 = new Operator("+"); var node2 = new Operator("*"); var node3 = new Operator("-"); var node4 = new Number("1"); var node5 = new Number("2"); var node6 = new Number("3"); var node7 = new Variable("X"); var node8 = new Operator("*"); var node9 = new Operator("/"); var node10 = new Number("4"); var node11 = new Number("5"); var node12 = new Number("6"); node1.LeftChild = node2; node2.Parent = node1; node1.RightChild = node3; node3.Parent = node1; node2.LeftChild = node6; node6.Parent = node2; node2.RightChild = node5; node5.Parent = node2; node3.LeftChild = node9; node9.Parent = node3; node3.RightChild = node10; node10.Parent = node3; node9.LeftChild = node11; node11.Parent = node9; node9.RightChild = node12; node12.Parent = node9; TreeIterator engine = new TreeIterator(node1); }
/// <summary> /// Generates a abstract syntrax tree from the given ParseTree /// </summary> /// <param name="node">Start node</param> /// <returns>Abstract syntax tree </returns> public ASTNode GenerateAST(ParseNode node) { ASTNode root; // Skip start node if (node.GetEnum() == ParseEnum.Start) { node = node.GetChildren()[0]; } List<ParseNode> bfQueue = GetBreadthFirstQueue(node).FindAll(x => x.GetEnum() == ParseEnum.Operator || x.GetEnum() == ParseEnum.Number || x.GetEnum() == ParseEnum.Variable || x.GetEnum() == ParseEnum.Equals); // If there is only one interesting node no further processing needs to be done. if (bfQueue.Count == 1) { root = ConvertPNtoASTNode(bfQueue[0]); } else { // Handle special condition if (bfQueue.Count == 3 && (bfQueue.Find(x => x.GetEnum() == ParseEnum.Operator || x.GetEnum() == ParseEnum.Equals) != null)) { ParseNode op = bfQueue.Find(x => x.GetEnum() == ParseEnum.Operator || x.GetEnum() == ParseEnum.Equals); bfQueue.Remove(op); if (op.GetEnum() == ParseEnum.Equals) { root = new EqualSign(op.GetValue()); } else { root = new Operator(op.GetValue()); } root.LeftChild = ConvertPNtoASTNode(bfQueue[0]); root.RightChild = ConvertPNtoASTNode(bfQueue[1]); } else { // Normal routine // Handles the left and right tree recursivly ParseNode subTree = node.GetChildren().Find(x => ContainsNode(x, bfQueue[0])); root = ConvertPNtoASTNode(bfQueue[0]); if (node.GetChildren()[0].Equals(subTree)) { subTree.GetChildren().Remove(bfQueue[0]); root.LeftChild = GenerateAST(subTree); root.RightChild = GenerateAST(node.GetChildren()[1]); } else { subTree.GetChildren().Remove(bfQueue[0]); root.RightChild = GenerateAST(subTree); root.LeftChild = GenerateAST(node.GetChildren()[0]); } } } return root; }
/// <summary> /// Converts a ParseNode object into it correspondending AST node. Throws an exception when there is no conversion possible. /// </summary> /// <param name="parseNode">Parsenode to be converted</param> /// <returns>AST node</returns> private ASTNode ConvertPNtoASTNode(ParseNode parseNode) { ASTNode ret; switch (parseNode.GetEnum()) { case ParseEnum.Number: ret = new Number(parseNode.GetValue()); break; case ParseEnum.Operator: ret = new Operator(parseNode.GetValue()); break; case ParseEnum.Variable: ret = new Variable(parseNode.GetValue()); break; case ParseEnum.Equals: ret = new EqualSign(parseNode.GetValue()); break; default: throw new Exception("Could not convert Parsenode"); } return ret; }