/// <summary> /// Make a tree from a list of nodes. The first element in the /// array is the root. If the root is null, then the tree is /// a simple list not a tree. Handles null children nodes correctly. /// For example, build(a, b, null, c) yields tree (a b c). build(null,a,b) /// yields tree (nil a b). /// </summary> /// <param name="nodes">List of Nodes.</param> /// <returns>AST Node tree.</returns> public virtual AST make(params AST[] nodes) { if (nodes == null || nodes.Length == 0) { return(null); } AST root = nodes[0]; AST tail = null; if (root != null) { root.setFirstChild(null); // don't leave any old pointers set } // link in children; for (int i = 1; i < nodes.Length; i++) { if (nodes[i] == null) { continue; } // ignore null nodes if (root == null) { // Set the root and set it up for a flat list root = (tail = nodes[i]); } else if (tail == null) { root.setFirstChild(nodes[i]); tail = root.getFirstChild(); } else { tail.setNextSibling(nodes[i]); tail = tail.getNextSibling(); } // Chase tail to last sibling while (tail.getNextSibling() != null) { tail = tail.getNextSibling(); } } return(root); }
public void visit(AST node) { // Flatten this level of the tree if it has no children bool flatten = /*true*/ false; AST node2; for (node2 = node; node2 != null; node2 = node2.getNextSibling()) { if (node2.getFirstChild() != null) { flatten = false; break; } } for (node2 = node; node2 != null; node2 = node2.getNextSibling()) { if (!flatten || node2 == node) { tabs(); } if (node2.getText() == null) { Console.Out.Write("nil"); } else { Console.Out.Write(node2.getText()); } Console.Out.Write(" [" + node2.Type + "] "); if (flatten) { Console.Out.Write(" "); } else { Console.Out.WriteLine(""); } if (node2.getFirstChild() != null) { level++; visit(node2.getFirstChild()); level--; } } if (flatten) { Console.Out.WriteLine(""); } }
/// <summary> /// Duplicate AST Node tree rooted at specified AST node and all of it's siblings. /// </summary> /// <param name="t">Root of AST Node tree.</param> /// <returns>Root node of new AST Node tree (or null if <c>t</c> is null).</returns> public virtual AST dupList(AST t) { AST result = dupTree(t); // if t == null, then result==null AST nt = result; while (t != null) { // for each sibling of the root t = t.getNextSibling(); nt.setNextSibling(dupTree(t)); // dup each subtree, building new tree nt = nt.getNextSibling(); } return(result); }
/*Print out a child-sibling tree in LISP notation */ public virtual string ToStringList() { AST t = this; string ts = ""; if (t.getFirstChild() != null) { ts += " ("; } ts += " " + this.ToString(); if (t.getFirstChild() != null) { ts += ((BaseAST)t.getFirstChild()).ToStringList(); } if (t.getFirstChild() != null) { ts += " )"; } if (t.getNextSibling() != null) { ts += ((BaseAST)t.getNextSibling()).ToStringList(); } return(ts); }
public virtual void xmlSerialize(TextWriter outWriter) { // print out this node and all siblings for (AST node = this; node != null; node = node.getNextSibling()) { if (node.getFirstChild() == null) { // print guts (class name, attributes) ((BaseAST)node).xmlSerializeNode(outWriter); } else { ((BaseAST)node).xmlSerializeRootOpen(outWriter); // print children ((BaseAST)node.getFirstChild()).xmlSerialize(outWriter); // print end tag ((BaseAST)node).xmlSerializeRootClose(outWriter); } } }
/*Is 'sub' a subtree of this list? * The siblings of the root are NOT ignored. */ public virtual bool EqualsListPartial(AST sub) { AST sibling; // the empty tree is always a subset of any tree. if (sub == null) { return(true); } // Otherwise, start walking sibling lists. First mismatch, return false. for (sibling = this; sibling != null && sub != null; sibling = sibling.getNextSibling(), sub = sub.getNextSibling()) { // as a quick optimization, check roots first. if (!sibling.Equals(sub)) { return(false); } // if roots match, do partial list match test on children. if (sibling.getFirstChild() != null) { if (!sibling.getFirstChild().EqualsListPartial(sub.getFirstChild())) { return(false); } } } if (sibling == null && sub != null) { // nothing left to match in this tree, but subtree has more return(false); } // either both are null or sibling has more, but subtree doesn't return(true); }
/*Is t an exact structural and equals() match of this tree. The * 'this' reference is considered the start of a sibling list. */ public virtual bool EqualsList(AST t) { AST sibling; // the empty tree is not a match of any non-null tree. if (t == null) { return(false); } // Otherwise, start walking sibling lists. First mismatch, return false. for (sibling = this; sibling != null && t != null; sibling = sibling.getNextSibling(), t = t.getNextSibling()) { // as a quick optimization, check roots first. if (!sibling.Equals(t)) { return(false); } // if roots match, do full list match test on children. if (sibling.getFirstChild() != null) { if (!sibling.getFirstChild().EqualsList(t.getFirstChild())) { return(false); } } else if (t.getFirstChild() != null) { return(false); } } if (sibling == null && t == null) { return(true); } // one sibling list has more than the other return(false); }