From: adam Date: Sun, 27 May 2007 20:27:38 +0000 (-0400) Subject: allow lifts on any position X-Git-Url: http://git.megacz.com/?p=sbp.git;a=commitdiff_plain;h=584cef55d8811e3215858fde22e708d2a3d1cf70 allow lifts on any position darcs-hash:20070527202738-5007d-d4059b9394ec68669c0ab779c8dcef80d58f78eb.gz --- diff --git a/src/edu/berkeley/sbp/Forest.java b/src/edu/berkeley/sbp/Forest.java index 34982bd..795f3a0 100644 --- a/src/edu/berkeley/sbp/Forest.java +++ b/src/edu/berkeley/sbp/Forest.java @@ -28,22 +28,13 @@ public abstract class Forest implements GraphViz.ToGraphViz { // Package-Private ////////////////////////////////////////////////////////////////////////////// - static Forest create(Input.Region region, NodeType head, Forest[] children, - boolean lift) { - if (region == null) throw new RuntimeException("invoked Forest.create(region=null) -- this should never happen"); - return new One(region, head, children, lift); - } - - static Forest create(Input.Region region, NodeType head, Forest[] children, - boolean lift, boolean liftLeft) { + public static Forest create(Input.Region region, NodeType head, Forest[] children) { + return create(region, head, children, new boolean[children==null ? 0 : children.length]); } + public static Forest create(Input.Region region, NodeType head, Forest[] children, boolean[] lifts) { if (region == null) throw new RuntimeException("invoked Forest.create(region=null) -- this should never happen"); - return new One(region, head, children, lift, liftLeft); + return new One(region, head, children, lifts); } - /** create a new forest */ - public static Forest create(Input.Region region, NodeType head, Forest[] children) { - return Forest.create(region, head, children, false); } - abstract void expand(HashSet> ht, HashSet> ignore, Tree bogus); abstract void gather(HashSet> ignore); abstract void edges(GraphViz.Node n); @@ -59,29 +50,24 @@ public abstract class Forest implements GraphViz.ToGraphViz { private final Forest[] children; /** if true, the last child's children are considered children of this node */ - private final boolean lift; - private final boolean liftLeft; + private final boolean[] lifts; public Input.Region getRegion() { return location; } - private One(Input.Region loc, NodeType head, Forest[] children, boolean lift) { - this(loc, head, children, lift, false); - } - private One(Input.Region loc, NodeType head, Forest[] children, boolean lift, boolean liftLeft) { + private One(Input.Region loc, NodeType head, Forest[] 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 expand1() throws Ambiguous { Tree[] ret = new Tree[children.length]; for(int i=0; i(location, head, ret, lift, liftLeft); + return new Tree(location, head, ret, lifts); } void gather(HashSet> hf) { @@ -95,7 +81,7 @@ public abstract class Forest implements GraphViz.ToGraphViz { private void expand(final int i, Tree[] ta, HashSet> ht, HashSet> ignore, Tree bogus) { if (i==children.length) { - ht.add(new Tree(location, head, ta, lift, liftLeft)); + ht.add(new Tree(location, head, ta, lifts)); } else { HashSet> ht2 = new HashSet>(); children[i].expand(ht2, ignore, bogus); @@ -124,7 +110,7 @@ public abstract class Forest implements GraphViz.ToGraphViz { if (edges) return; edges = true; for(int i=0; i, SequenceOrElement { public static Sequence create(Element e) { return create(new Element[] { e }, 0); } /** create a sequence which drops the result of all but one of its element */ - public static Sequence create(Element[] e, int which) { return new Singleton(e, which); } + public static Sequence create(Element[] e, int which) { + return new Singleton(e, which); } /** create a sequence which always evaluates to a constant result */ - public static Sequence create(Element[] e, Object result) { return new Constant(e, result); } + public static Sequence create(Object result, Element[] e) { + return new RewritingSequence(result, e, trues(e.length)); } + + private static boolean[] trues(int length) { + boolean[] ret = new boolean[length]; + for(int i=0; i, SequenceOrElement { * @param e the elements to match * @param drop only elements of e whose corresponding boolean in drops * is false will be included in the output tree - * @param foster if true, all children of the last child (ie - * grandchildren) are promoted to children of this - * node; this is very useful for matching repetitions + * @param lifts which (if any) child trees to lift **/ - public static Sequence create(Object head, Element[] e, boolean[] drop, boolean foster) { - return foster - ? new Unwrap(e, head, drop) - : new RewritingSequence(head, e, drop); - } - public static Sequence createLeft(Object head, Element[] e, boolean[] drop, boolean foster) { - return foster - ? new UnwrapLeft(e, head, drop) - : new RewritingSequence(head, e, drop); + public static Sequence create(Object head, Element[] e, boolean[] drop) { + return create(head, e, drop, new boolean[e.length]); } + public static Sequence create(Object head, Element[] e, boolean[] drop, boolean[] lifts) { + if (lifts==null) lifts = new boolean[e.length]; + return new RewritingSequence(head, e, drop, lifts); } /** return a new sequence identical to this one, but with a positive conjunct s */ @@ -240,66 +242,31 @@ public abstract class Sequence implements Iterable, SequenceOrElement { } } - static class Unwrap extends Sequence { - private boolean[] drops; - private final Object tag; - public Unwrap(Element[] e, Object tag) { this(e, tag, null); } - public Unwrap(Element[] e, Object tag, boolean[] drops) { super(e); this.drops = drops; this.tag = tag; } - Sequence _clone() { return new Unwrap(elements, tag, drops); } - public Forest postReduce(Input.Region loc, Forest[] args, Position p) { - for(int i=0; i[] args2 = new Forest[count]; - int j = 0; - for(int i=0; i Forest postReduce(Input.Region loc, Forest[] args, Position p) { - for(int i=0; i[] args2 = new Forest[count]; - int j = 0; - for(int i=0; i Forest postReduce(Input.Region loc, Forest[] args, Position p) { - Forest[] args2 = new Forest[count]; + Forest[] args2 = new Forest[lifts.length]; int j = 0; for(int i=0; i, SequenceOrElement { return sb; } Forest epsilonForm(Input.Region loc, Grammar cache) { - return Forest.create(loc, tag, new Forest[0], false); + return Forest.create(loc, tag, new Forest[0], lifts); } } - } diff --git a/src/edu/berkeley/sbp/Tree.java b/src/edu/berkeley/sbp/Tree.java index 1f55a90..5f7f73d 100644 --- a/src/edu/berkeley/sbp/Tree.java +++ b/src/edu/berkeley/sbp/Tree.java @@ -35,32 +35,27 @@ public class Tree /** get the input region that this tree was parsed from */ public Input.Region getRegion() { return location; } - public Tree(Input.Region loc, NodeType head) { this(loc, head, null); } - public Tree(Input.Region loc, NodeType head, Tree[] children) { this(loc, head, children, false); } + public Tree(Input.Region loc, NodeType head) { this(loc, head, new Tree[0]); } + public Tree(Input.Region loc, NodeType head, Tree[] children) { this(loc, head, children, new boolean[children==null?0:children.length]); } // FIXME: fairly inefficient because we keep copying arrays /** package-private constructor, allows setting the "lift" bit */ - Tree(Input.Region loc, NodeType head, Tree[] children, boolean lift) { - this(loc, head, children, lift, false); - } - Tree(Input.Region loc, NodeType head, Tree[] children, boolean lift, boolean liftLeft) { + Tree(Input.Region loc, NodeType head, Tree[] children, boolean[] lifts) { this.location = loc; this.ihead = head; - // FIXME: lift+liftLeft togheter - if (liftLeft && children != null && children.length > 0) { - Tree last = children[0]; - this.children = new Tree[(children.length-1)+last.children.length]; - System.arraycopy(children, 1, this.children, last.children.length, children.length-1); - if (last.children.length > 0) - System.arraycopy(last.children, 0, this.children, 0, last.children.length); - } else if (lift && children != null && children.length > 0) { - Tree last = children[children.length-1]; - this.children = new Tree[(children.length-1)+last.children.length]; - System.arraycopy(children, 0, this.children, 0, children.length-1); - if (last.children.length > 0) - System.arraycopy(last.children, 0, this.children, children.length-1, last.children.length); - } else { - this.children = ArrayUtil.clone(children, Tree.class); + + int count = 0; + for(int i=0; i { public String toString() { return escapified; } }; Element[] refs = new Element[s.length()]; for(int i=0; i { private static Union emptyString = new Union("()"); static { // FIXME: force this to be dropped wherever used! - emptyString.add(Sequence.create(new Element[0], "")); + emptyString.add(Sequence.create("", new Element[0])); } public Topology> unwrap() { return this; } diff --git a/src/edu/berkeley/sbp/meta/GrammarAST.java b/src/edu/berkeley/sbp/meta/GrammarAST.java index 997d0b6..19f12a3 100644 --- a/src/edu/berkeley/sbp/meta/GrammarAST.java +++ b/src/edu/berkeley/sbp/meta/GrammarAST.java @@ -79,26 +79,24 @@ public class GrammarAST { if (head.equals("Word")) return stringifyChildren(t); if (head.equals("Elements")) return seq2((ElementNode[])Reflection.rebuild(walkChildren(t), ElementNode[].class)); if (head.equals("NonTerminalReference")) return new ReferenceNode(stringifyChildren(t.child(0))); - //if (head.equals(")")) return new ReferenceNode(stringifyChildren(t.child(0))); - if (head.equals("{")) return new XTree((Seq)walk(t.child(0))); - if (head.equals("::")) return tag((String)walk(t.child(0)), (Seq)walk(t.child(1))); - if (head.equals("++")) return plusmax((ElementNode)walk(t.child(0))); - if (head.equals("...")) return star(new TildeNode(new AtomNode())); - if (head.equals("+")) return plus((ElementNode)walk(t.child(0))); - if (head.equals("++/")) return plusmaxfollow((ElementNode)walk(t.child(0)), (ElementNode)walk(t.child(1))); - if (head.equals("+/")) return plusfollow((ElementNode)walk(t.child(0)), (ElementNode)walk(t.child(1))); - if (head.equals("**")) return starmax((ElementNode)walk(t.child(0))); - if (head.equals("*")) return star((ElementNode)walk(t.child(0))); - if (head.equals("**/")) return starmaxfollow((ElementNode)walk(t.child(0)), (ElementNode)walk(t.child(1))); - if (head.equals("*/")) return starfollow((ElementNode)walk(t.child(0)), (ElementNode)walk(t.child(1))); - if (head.equals("?")) return question((ElementNode)walk(t.child(0))); - if (head.equals("!")) return new DropNode((ElementNode)walk(t.child(0))); - if (head.equals("^")) return new LiteralNode((String)walk(t.child(0)), true); - if (head.equals("`")) { - ElementNode ret = (ElementNode)walk(t.child(0)); - ret.lifted = true; - return ret; - } + if (head.equals(")")) return new ReferenceNode(stringifyChildren(t.child(0)), true); + if (head.equals("{")) return new BracedNode(walkSeq(t.child(0))); + if (head.equals("::")) return walkSeq(t.child(1)).tag(walkString(t.child(0))); + if (head.equals("...")) return new DropNode(new RepeatNode(new TildeNode(new AtomNode()), null, true, true, false)); + + if (head.equals("++")) return new RepeatNode(walkElement(t.child(0)), null, false, true, true); + if (head.equals("+")) return new RepeatNode(walkElement(t.child(0)), null, false, true, false); + if (head.equals("++/")) return new RepeatNode(walkElement(t.child(0)), walkElement(t.child(1)), false, true, true); + if (head.equals("+/")) return new RepeatNode(walkElement(t.child(0)), walkElement(t.child(1)), false, true, false); + if (head.equals("**")) return new RepeatNode(walkElement(t.child(0)), null, true, true, true); + if (head.equals("*")) return new RepeatNode(walkElement(t.child(0)), null, true, true, false); + if (head.equals("**/")) return new RepeatNode(walkElement(t.child(0)), walkElement(t.child(1)), true, true, true); + if (head.equals("*/")) return new RepeatNode(walkElement(t.child(0)), walkElement(t.child(1)), true, true, false); + if (head.equals("?")) return new RepeatNode(walkElement(t.child(0)), null, true, false, false); + + if (head.equals("!")) return new DropNode(walkElement(t.child(0))); + if (head.equals("^")) return new LiteralNode(walkString(t.child(0)), true); + if (head.equals("`")) return walkElement(t.child(0)).lifted(); if (head.equals("Quoted")) return stringifyChildren(t); if (head.equals("Literal")) return new LiteralNode(walkString(t.child(0))); if (head.equals("->")) return walkSeq(t.child(0)).follow(walkElement(t.child(1))); @@ -198,7 +196,7 @@ public class GrammarAST { public Union build(String rootNonterminal) { Context cx = new Context(this); Union u = null; - for(GrammarBuilder.NonTerminalNode nt : values()) + for(GrammarAST.NonTerminalNode nt : values()) if (nt.name.equals(rootNonterminal)) return (Union)cx.get(nt.name); return null; @@ -347,20 +345,20 @@ public class GrammarAST { els[i] = elements[i].build(cx, cnt, dropall); } if (tag==null && multiNonDrop) - throw new RuntimeException("multiple non-dropped elements in sequence: " + Sequence.create(els, "")); - boolean lift = false; - if (elements.length > 0 && elements[0].lifted) - lift = true; + throw new RuntimeException("multiple non-dropped elements in sequence: " + Sequence.create("", els)); + boolean[] lifts = new boolean[elements.length]; + for(int i=0; i