public void Init() { _testTree = new ParseNode(ParseEnum.Start); _testTree.AddChild(new ParseNode(ParseEnum.Expression)); _testTree.GetChildren()[0].AddChild(new ParseNode(ParseEnum.Term)); _testTree.GetChildren()[0].AddChild(new ParseNode(ParseEnum.ExpressionAccent)); ParseNode node = _testTree.GetChildren()[0].GetChildren()[0]; node.AddChild(new ParseNode(ParseEnum.Factor)); node.AddChild(new ParseNode(ParseEnum.TermAccent)); node.GetChildren()[0].AddChild(new ParseNode(ParseEnum.Number, "3")); node.GetChildren()[1].AddChild(new ParseNode(ParseEnum.Empty)); node = _testTree.GetChildren()[0].GetChildren()[1]; node.AddChild(new ParseNode(ParseEnum.Operator, "+")); node.AddChild(new ParseNode(ParseEnum.Term)); node.AddChild(new ParseNode(ParseEnum.ExpressionAccent)); ParseNode termNode = node.GetChildren()[1]; termNode.AddChild(new ParseNode(ParseEnum.Factor)); termNode.AddChild(new ParseNode(ParseEnum.TermAccent)); termNode.GetChildren()[0].AddChild(new ParseNode(ParseEnum.Number, "4")); termNode.GetChildren()[1].AddChild(new ParseNode(ParseEnum.Empty)); node.GetChildren()[2].AddChild(new ParseNode(ParseEnum.Empty)); }
/// <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; }
private bool ContainsNode(ParseNode startNode, ParseNode nodeToFind) { if (startNode.Equals(nodeToFind)) { return true; } return startNode.GetChildren().Exists(x => ContainsNode(x, nodeToFind)); }