+ 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;
+ }
+
+ public Tree<NodeType> expand1() throws Ambiguous {
+ Tree<NodeType>[] ret = new Tree[children.length];
+ for(int i=0; i<children.length; i++) ret[i] = children[i].expand1();
+ return new Tree<NodeType>(location, head, ret, lifts);
+ }
+
+ void gather(HashSet<Forest<NodeType>> hf) {
+ hf.add(this);
+ for(Forest<NodeType> f : children) f.gather(hf);
+ }
+ void expand(HashSet<Tree<NodeType>> ht, HashSet<Forest<NodeType>> ignore, Tree<NodeType> bogus) {
+ if (ignore.contains(this)) { ht.add(bogus); return; }
+ expand(0, new Tree[children.length], ht, ignore, bogus);
+ }
+ private void expand(final int i, Tree<NodeType>[] ta, HashSet<Tree<NodeType>> ht, HashSet<Forest<NodeType>> ignore,
+ Tree<NodeType> bogus) {
+ if (i==children.length) {
+ ht.add(new Tree<NodeType>(location, head, ta, lifts));
+ } else {
+ HashSet<Tree<NodeType>> ht2 = new HashSet<Tree<NodeType>>();
+ children[i].expand(ht2, ignore, bogus);
+ for(Tree<NodeType> tc : ht2) {
+ ta[i] = tc;
+ expand(i+1, ta, ht, ignore, bogus);
+ ta[i] = null;
+ }
+ }
+ }
+
+ // GraphViz, ToInt //////////////////////////////////////////////////////////////////////////////