import se.chalmers.cs.gf.gfcutil.Function; import se.chalmers.cs.gf.linearize.Linearizer; import se.chalmers.cs.gf.linearize.gfvalue.*; import se.chalmers.cs.gf.abssyn.*; public class Node { private Function fun; private Node parent; private Node[] children; public Node(Function fun) { this.fun = fun; this.parent = null; this.children = new Node[fun.getArity()]; } public String getFun() { return fun.getName(); } public String getType() { return fun.getResultCat(); } public int getArity() { return children.length; } public boolean isRoot() { return parent == null; } /** * Checks if the given child slot is free. */ public boolean isFree(int slot) { return children[slot] == null; } public String getText(Linearizer lin) { // FIXME: cache? Tree t = createTree(); String s = createText(lin,t); System.err.println(getFun() + ": " + s); return s; } protected Node setParent(Node newParent) { Node old = parent; parent = newParent; return old; } /** * Checks if a node can be attached as a child of this * one in the given position. */ public boolean canAttach(int pos, Node child) { return child.getType().equals(fun.getArgCat(pos)); } /** * Attaches a child node to this node. This method * also sets the parent node of the given child to * be this node. This method does not check whether * the child is allowed to be attached, use * {@link #canAttach(int,Node) canAttach} for that. * @param pos The child position to attach to. * @return The old child in this position, or null * if there was none. */ public Node attachChild(int pos, Node child) { Node old = children[pos]; children[pos] = child; child.setParent(this); return old; } /** * Removes a child node from this node. Sets the parent * of the child node to null. * @return The removed child. */ public Node removeChild(int pos) { Node old = children[pos]; children[pos] = null; old.setParent(null); return old; } public Node clone() { Node n = new Node(fun); n.parent = parent; for (int i = 0; i < children.length; i++) { if (children[i] != null) { n.children[i] = children[i].clone(); } } return n; } private Tree createTree() { Tree[] cs = new Tree[children.length]; for (int i = 0; i < children.length; i++) { if (children[i] == null) { cs[i] = new MetaVariable(); } else { cs[i] = children[i].createTree(); } } return new Fun(fun.getName(), cs); } private static String createText(Linearizer lin, Tree t) { return valueAsString(lin.linearize(t)); } private static String valueAsString(Value value) { Record r = (Record)value; Value v = null; if (r.hasField("s")) { v = r.get("s"); } else if (r.hasField("s1")) { v = r.get("s1"); } while (v instanceof Table) { v = ((Table)v).firstValue(); } String s = v.toString(); return s; } }