+
+ abstract void expand(HashSet<Tree<NodeType>> ht, HashSet<Forest<NodeType>> ignore, Tree<NodeType> bogus);
+ abstract void gather(HashSet<Forest<NodeType>> ignore);
+ abstract void edges(GraphViz.StateNode n);
+ boolean ambiguous() { return false; }
+
+ // One //////////////////////////////////////////////////////////////////////////////
+
+ /** A "single" forest with a head and child subforests */
+ private static class One<NodeType> extends Forest<NodeType> {
+
+ private final Input.Region location;
+ private final NodeType head;
+ private final Forest<NodeType>[] children;
+
+ /** if true, the last child's children are considered children of this node */
+ private final boolean[] lifts;
+
+ public Input.Region getRegion() { return location; }
+
+ private One(Input.Region loc, NodeType head, Forest<NodeType>[] children, boolean[] lifts) {
+ this.location = loc;
+ this.head = head;
+ if (head==null) throw new RuntimeException("invoked Forest.create(,null,,,) -- this should never happen");
+ this.children = children==null ? emptyForestArray : new Forest[children.length];
+ if (children != null) System.arraycopy(children, 0, this.children, 0, children.length);
+ if (children != null) for(int i=0; i<children.length; i++) if (children[i]==null) throw new Error(i+"");
+ this.lifts = lifts;