X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2FForest.java;h=0a20228acd563ee908532da57f962af4002d33ee;hb=aa467fd9d82ee4ab751a6ced1e4f48864f494e90;hp=8587dcb0cc680ba9539133eac5c2472dc0e049af;hpb=96a2822a729e563a64173f22dc184bc972a200ef;p=sbp.git diff --git a/src/edu/berkeley/sbp/Forest.java b/src/edu/berkeley/sbp/Forest.java index 8587dcb..0a20228 100644 --- a/src/edu/berkeley/sbp/Forest.java +++ b/src/edu/berkeley/sbp/Forest.java @@ -7,211 +7,141 @@ import java.util.*; import java.lang.reflect.*; /** an efficient representation of a collection of trees (Tomita's shared packed parse forest) */ -public abstract class Forest { +public abstract class Forest extends PrintableTree> implements Iterable> { /** assume that this forest contains exactly one tree and return it; otherwise throw an exception */ - public final Tree expand1() throws Parser.Ambiguous, Parser.Failed { + public final Tree expand1() throws Ambiguous, ParseFailed { Iterator> it = expand(true).iterator(); - if (!it.hasNext()) throw new Parser.Failed(); + if (!it.hasNext()) throw new ParseFailed(); return it.next(); } /** expand this forest into a set of trees */ public abstract HashSet> expand(boolean toss); - abstract boolean valid(); - - static Forest singleton(Token.Location loc, Sequence creator) { return create(loc, null, new Forest[] { }, creator, false, true); } - static Forest singleton(Token.Location loc, Forest body, Sequence creator) { return create(loc, null, new Forest[] { body }, creator, false, true); } - static Forest leaf(Token.Location loc, T tag, Sequence creator) { return create(loc, tag, null, creator, false, false); } - public static Forest create(Token.Location loc, T tag, Forest[] tokens, Sequence creator, boolean unwrap, boolean singleton) { - return new MultiForest(loc, tag, tokens, creator, unwrap, singleton); + static Forest singleton(Input.Location loc) { return create(loc, null, new Forest[] { }, false, true); } + static Forest singleton(Input.Location loc, Forest body) { return create(loc, null, new Forest[] { body }, false, true); } + static Forest leaf(Input.Location loc, T tag) { return create(loc, tag, null, false, false); } + public static Forest create(Input.Location loc, T tag, Forest[] tokens, boolean unwrap, boolean singleton) { + return new MultiForest(loc, tag, tokens, unwrap, singleton); } // Body ////////////////////////////////////////////////////////////////////////////// - protected static class Body { + protected static class Body extends PrintableTree> implements Iterable> { - private final Token.Location location; + private final Input.Location location; private final T tag; private final Forest[] tokens; - private final Sequence creator; private final boolean unwrap; private final boolean singleton; - private Body(Token.Location loc, T tag, Forest[] tokens, Sequence creator, boolean unwrap, boolean singleton) { + private Body(Input.Location loc, T tag, Forest[] tokens, boolean unwrap, boolean singleton) { this.location = loc; this.tag = tag; this.tokens = tokens==null ? emptyForestArray : new Forest[tokens.length]; if (tokens != null) System.arraycopy(tokens, 0, this.tokens, 0, tokens.length); - this.creator = creator; + if (tokens != null) for(int i=0; i> expand(boolean toss, ArrayList> toks, int i, HashSet> h) { if (singleton) { - for(Body b : (IterableForest)tokens[0]) b.expand(toss, toks, i, h); + for(Body b : tokens[0]) b.expand(toss, toks, i, h); } else if (i==tokens.length) { h.add(new Tree(null, tag, toks.toArray(tree_hint))); } else if (unwrap && i==tokens.length-1) { if (tokens[i] != null) - for(Body b : (IterableForest)tokens[i]) + for(Body b : tokens[i]) b.expand(toss, toks, 0, h); } else { - if (tokens[i]!=null) { - HashSet> exp = tokens[i].expand(toss); - if (exp != null) - for(Tree r : exp) { - int old = toks.size(); - toks.add(r); - expand(toss, toks, i+1, h); - while(toks.size() > old) toks.remove(toks.size()-1); - } + boolean hit = false; + for(Tree r : tokens[i].expand(toss)) { + hit = true; + int old = toks.size(); + toks.add(r); + expand(toss, toks, i+1, h); + while(toks.size() > old) toks.remove(toks.size()-1); } + //if (!hit) throw new Error(); } return h; } - void addTo(HashSet h) { - if (!singleton) h.add(this); - else for(Body b : (IterableForest)tokens[0]) b.addTo(h); - } + void addTo(FastSet h) { if (!singleton) h.add(this, true); - else for(Body b : (IterableForest)tokens[0]) b.addTo(h); - } - - private boolean kcache = false; - private boolean keep = false; - public boolean keep() { - if (kcache) return keep; - kcache = true; - for(Forest token : tokens) if (!token.valid()) return keep = false; - return keep = creator==null || (creator.needs.size()==0 && creator.hates.size()==0); + else for(Body b : tokens[0]) b.addTo(h); } - public boolean keep(Iterable> h) { - if (keep()) return true; - for(Forest token : tokens) if (!token.valid()) return false; - int needs = 0; - for(Body b : h) { - if (creator.hates.contains(b.creator) && b.keep(h)) return false; - if (creator.needs.contains(b.creator) && b.keep(h)) needs--; - } - return needs <= -1 * creator.needs.size(); - } - - public String toString() { - StringBuffer ret = new StringBuffer(); - for(int i=0; i 0) { - ret.append(q); - ret.append(" "); - } - } - String tail = ret.toString().trim(); - String head = (tag!=null && !tag.toString().equals("")) ? (tail.length() > 0 ? tag+":" : tag+"") : ""; - if (tail.length() > 0) tail = "{" + tail + "}"; - return head + tail; - } + protected String headToString() { return null; } + protected String headToJava() { return null; } + protected String left() { return "{"; } + protected String right() { return "}"; } + protected boolean ignoreSingleton() { return false; } + public Iterator> iterator() { return new ArrayIterator>(tokens); } } // Ref ////////////////////////////////////////////////////////////////////////////// - static abstract class IterableForest extends Forest implements Iterable> { - public abstract Iterator> iterator(); - } - /** * This class represents a partially complete collection of * forests to be viewed as a forest at some later date; once * viewed, it becomes immutable */ - static class Ref extends IterableForest { + static class Ref extends Forest { private FastSet hp = new FastSet(); private Forest res = null; - public boolean valid = false; public Ref() { } public void merge(Forest p) { if (res != null) throw new Error("already resolved!"); if (p==null) throw new Error(); - if (p!=this) hp.add(p); + if (p!=this) hp.add(p, true); } - public Iterator> iterator() { return ((IterableForest)resolve()).iterator(); } + public Iterator> iterator() { return ((Forest)resolve()).iterator(); } public HashSet> expand(boolean toss) { return resolve().expand(toss); } - public boolean valid() { resolve(); return valid; } - public String toString() { return resolve().toString(); } public Forest resolve() { if (hp==null) return res; - HashSet results = null; FastSet nh = new FastSet(); for(Forest p : hp) - for(Body b : (IterableForest)p) { - if (b.keep() && (b.creator==null || !b.creator.lame)) { valid = true; b.addTo(nh); } - else results = new HashSet(); - } - if (results != null) { - for(Forest p : hp) for(Body b : (IterableForest)p) results.add(b); - for(Body b : results) { - if (b.keep() && (b.creator==null || !b.creator.lame)) continue; - if (!b.keep(results)) continue; - if (b.creator!=null && b.creator.lame) continue; - valid = true; + for(Body b : (Forest)p) b.addTo(nh); - } - } + res = new MultiForest(nh); hp = null; - return res = new MultiForest(nh, valid); + return res; } } // Implementations ////////////////////////////////////////////////////////////////////////////// - private static class MultiForest extends IterableForest { + private static class MultiForest extends Forest { private final FastSet> results; - private boolean valid; - public boolean valid() { return valid; } - private MultiForest(FastSet> results, boolean valid) { this.results = results; this.valid = valid; } - public MultiForest(Token.Location loc, T tag, Forest[] tokens, Sequence creator, boolean unwrap, boolean singleton) { - this.results = new FastSet>(new Body(loc, tag, tokens, creator, unwrap, singleton)); - this.valid = true; + private MultiForest(FastSet> results) { this.results = results; } + public MultiForest(Input.Location loc, T tag, Forest[] tokens, boolean unwrap, boolean singleton) { + this.results = new FastSet>(new Body(loc, tag, tokens, unwrap, singleton)); } public Iterator> iterator() { return results.iterator(); } - public HashSet> expand(boolean toss) { HashSet> ret = new HashSet>(); for(Body b : results) ret.addAll(b.expand(toss, new ArrayList>(), 0, new HashSet>())); - if (toss && ret.size() > 1) throw new Parser.Ambiguous(this); + if (toss && ret.size() > 1) throw new Ambiguous(this); return ret; } - - // Display ////////////////////////////////////////////////////////////////////////////// - - private String toString = null; - public String toString() { - if (toString != null) return toString; - StringBuffer ret = new StringBuffer(); - ret.append(" r : results) { - if (!first) ret.append(' '); - first = false; - ret.append(r); - } - ret.append("?>"); - return toString = ret.toString(); - } } // Statics ////////////////////////////////////////////////////////////////////////////// private static Tree[] tree_hint = new Tree[0]; - private static Body[] body_hint = new Body[0]; private static final Forest[] emptyForestArray = new Forest[0]; + + protected String headToString() { return null; } + protected String headToJava() { return null; } + protected String left() { return ""; } + protected boolean ignoreSingleton() { return true; } }