}
static <T> Forest<T> singleton(Input.Location loc, Position p) {
- return create(loc, null, new Forest[] { }, false, true, p); }
+ return create(loc, null, new Forest[] { }, new Object[0], false, true, p); }
static <T> Forest<T> singleton(Input.Location loc, Forest<T> body, Position p) {
//return create(loc, null, new Forest[] { body }, false, true, p);
return body;
}
- static <T> Forest<T> leaf(Input.Location loc, T tag, Position p) { return create(loc, tag, null, false, false, p); }
- public static <T> Forest<T> create(Input.Location loc, T tag, Forest<T>[] tokens, boolean unwrap, boolean singleton, Position p) {
- return new MyBody<T>(loc, tag, tokens, unwrap, singleton, p);
+ static <T> Forest<T> leaf(Input.Location loc, T tag, Position p) { return create(loc, tag, null, null, false, false, p); }
+ public static <T> Forest<T> create(Input.Location loc, T tag, Forest<T>[] tokens, Object[] labels, boolean unwrap, boolean singleton, Position p) {
+ return new MyBody<T>(loc, tag, tokens, labels, unwrap, singleton, p);
}
// Body //////////////////////////////////////////////////////////////////////////////
if (i==tokens.length-1 && unwrap) {
tokens[i].edges(n);
} else {
- n.edge(tokens[i]);
+ n.edge(tokens[i], labels==null?null:labels[i]);
}
}
}
private final Input.Location location;
private final T tag;
private final Forest<T>[] tokens;
+ private final Object[] labels;
private final boolean unwrap;
private final boolean singleton;
private final Sequence.Position reduction;
- private MyBody(Input.Location loc, T tag, Forest<T>[] tokens, boolean unwrap, boolean singleton, Position reduction) {
+ private MyBody(Input.Location loc, T tag, Forest<T>[] tokens, Object[] labels, boolean unwrap, boolean singleton, Position reduction) {
this.location = loc;
this.tag = tag;
this.tokens = tokens==null ? emptyForestArray : new Forest[tokens.length];
this.unwrap = unwrap;
this.singleton = singleton;
this.reduction = reduction;
+ this.labels = labels;
}
public void expand(final int i, final TreeMaker<T> h) {
} else {
tokens[i].visit(new TreeMaker<T>(h.toss) {
public void start(T head, Input.Location loc) { }
- public void addTree(Tree<T> t) { toks.add(t); }
+ public void addTree(Tree<T> t, Object label) { toks.add(t); labs.add(label); }
public void finish(T head, Input.Location loc) {
int old = h.toks.size();
- h.addTree(new Tree<T>(loc, head, toks.toArray(tree_hint)));
+ h.addTree(new Tree<T>(loc, head, toks.toArray(tree_hint), labs.toArray(string_hint)), labels==null?null:labels[i]);
expand(i+1, h);
while(h.toks.size() > old) h.toks.remove(h.toks.size()-1);
+ while(h.labs.size() > old) h.labs.remove(h.labs.size()-1);
}
}, null, null);
}
GraphViz.Node n = gv.createNode(this);
n.label = "?";
n.color = "red";
- for(Forest f : hp) n.edge(f);
+ for(Forest f : hp) n.edge(f, null);
return n;
}
private static class TreeMaker2<T> extends TreeMaker<T> {
private TreeConsumer<T> tc;
public TreeMaker2(boolean toss, TreeConsumer<T> tc) { super(toss); this.tc = tc; }
- public void finish(T head, Input.Location loc) { tc.addTree(new Tree<T>(loc, head, toks.toArray(tree_hint)));; }
+ public void finish(T head, Input.Location loc) { tc.addTree(new Tree<T>(loc, head, toks.toArray(tree_hint), labs.toArray(string_hint)));; }
public void start(T head, Input.Location loc) { }
- public void addTree(Tree<T> t) { toks.add(t); }
+ public void addTree(Tree<T> t, Object label) { toks.add(t); labs.add(label); }
}
- private static abstract class TreeMaker<T> implements Invokable<Forest.Body<T>,Boolean,Integer>, TreeConsumer<T> {
+ private static abstract class TreeMaker<T> implements Invokable<Forest.Body<T>,Boolean,Integer>/*, TreeConsumer<T>*/ {
public ArrayList<Tree<T>> toks = new ArrayList<Tree<T>>();
+ public ArrayList<Object> labs = new ArrayList<Object>();
private boolean toss;
protected T head;
public TreeMaker(boolean toss) { this.toss = toss; }
public abstract void start(T head, Input.Location loc);
public abstract void finish(T head, Input.Location loc);
- public abstract void addTree(Tree<T> t);
+ public abstract void addTree(Tree<T> t, Object label);
public void invoke(Forest.Body<T> bod, Boolean o, Integer i) {
if (i==null) {
ArrayList<Tree<T>> toks = this.toks;
this.toks = new ArrayList<Tree<T>>();
+ ArrayList<Object> labs = this.labs;
+ this.labs = new ArrayList<Object>();
bod.expand(0, this);
this.toks = toks;
+ this.labs = labs;
} else {
bod.expand(i, this);
}
// Statics //////////////////////////////////////////////////////////////////////////////
private static Tree[] tree_hint = new Tree[0];
+ private static String[] string_hint = new String[0];
private static final Forest[] emptyForestArray = new Forest[0];
protected String headToString() { return null; }
if (manyOkay) add(new Sequence.Singleton(many1(e, separator)));
else add(new Sequence.Singleton(e));
} else {
- add(new Sequence.RewritingSequence(null, new Element[] { e }));
+ add(new Sequence.RewritingSequence(null, new Element[] { e }, null));
if (separator==null)
add(new Sequence.Unwrap(new Element[] { e, Repeat.this }));
else
* @param e the elements to match
* @param drops only elements of <tt>e</tt> whose corresponding <tt>boolean</tt> in <tt>drops</tt> is <i>false</i> will be included in the output tree
**/
- public static Sequence rewritingSequence(Object tag, Element[] e, boolean[] drops) { return new RewritingSequence(tag, e, drops); }
+ public static Sequence rewritingSequence(Object tag, Element[] e, Object[] labs, boolean[] drops) {
+ return new RewritingSequence(tag, e, labs, drops); }
////////////////////////////////////////////////////////////////////////////////
Sequence _clone() { return new Unwrap(elements, drops); }
public <T> Forest<T> postReduce(Input.Location loc, Forest<T>[] args, Position p) {
for(int i=0; i<args.length; i++) if (args[i]==null) throw new Error();
- if (drops==null) return Forest.create(loc, null, args, true, false, p);
+ if (drops==null) return Forest.create(loc, null, args, new Object[args.length], true, false, p);
int count = 0;
for(int i=0; i<drops.length; i++) if (!drops[i]) count++;
Forest<T>[] args2 = new Forest[count];
int j = 0;
for(int i=0; i<args.length; i++) if (!drops[i]) args2[j++] = args[i];
- return Forest.create(loc, null, args2, true, false, p);
+ return Forest.create(loc, null, args2, new Object[args.length], true, false, p);
}
}
static class RewritingSequence extends Sequence {
/*private*/public final Object tag;
private final boolean[] drops;
+ private final Object[] labs;
private int count = 0;
- Sequence _clone() { return new RewritingSequence(tag, elements, drops); }
- public RewritingSequence(Object tag, Element[] e) { this(tag, e, null); }
- public RewritingSequence(Object tag, Element[] e, boolean[] drops) {
+ Sequence _clone() { return new RewritingSequence(tag, elements, labs, drops); }
+ public RewritingSequence(Object tag, Element[] e, Object[] labs) { this(tag, e, labs, null); }
+ public RewritingSequence(Object tag, Element[] e, Object[] labs, boolean[] drops) {
super(e);
this.tag = tag;
this.drops = drops == null ? new boolean[e.length] : drops;
for(int i=0; i<this.drops.length; i++) if (!this.drops[i]) count++;
+ this.labs = labs;
}
public <T> Forest<T> postReduce(Input.Location loc, Forest<T>[] args, Position p) {
Forest<T>[] args2 = new Forest[count];
int j = 0;
for(int i=0; i<args.length; i++) if (!drops[i]) args2[j++] = args[i];
//System.out.println("reduce \""+tag+"\"");
- return Forest.create(loc, (T)tag, args2, false, false, p);
+ return Forest.create(loc, (T)tag, args2, labs, false, false, p);
}
public StringBuffer toString(StringBuffer sb, boolean spacing) {
int len = sb.length();
final T head;
Tree<T>[] children;
+ Object[] labels;
final Input.Location location;
public T head() { return head; }
public Iterable<Tree<T>> children() { return new ArrayIterator(children); }
public Iterator<Tree<T>> iterator() { return new ArrayIterator(children); }
public Tree<T> child(int i) { return children[i]; }
+ public Object label(int i) { return labels[i]; }
- public Input.Location getLocation() { return location; }
+ public Input.Location getLocation() { return location; }
public Tree(Input.Location loc, T head) { this(loc, head, null); }
- public Tree(Input.Location loc, T head, Tree<T>[] children) {
+ public Tree(Input.Location loc, T head, Tree<T>[] children) { this(loc, head, children, null); }
+ public Tree(Input.Location loc, T head, Tree<T>[] children, Object[] labels) {
this.location = loc;
this.head = head;
+
Tree<T>[] children2 = children==null ? new Tree[0] : new Tree[children.length];
if (children != null) System.arraycopy(children, 0, children2, 0, children.length);
this.children = children2;
+
+ Object[] labels2 = labels==null ? new Object[0] : new Object[labels.length];
+ if (labels != null) System.arraycopy(labels, 0, labels2, 0, labels.length);
+ this.labels = labels2;
}
protected String headToString() { return head==null?null:head.toString(); }
public CharParser(Union u) { super(u, new CharTopology()); }
public Forest<String> shiftToken(Character ct, Location loc) {
- return Forest.create(loc, ct.toString(), null, false, false, null);
+ return Forest.create(loc, ct.toString(), null, null, false, false, null);
}
}
Sequence ret = null;
if (dropAll || lame) ret = Sequence.drop(expansion, lame);
else if (unwrap) ret = new Sequence.Unwrap(expansion, drops);
- else if (tag!=null) ret = Sequence.rewritingSequence(tag, expansion, drops);
+ else if (tag!=null) ret = Sequence.rewritingSequence(tag, expansion, null, drops);
else {
int idx = -1;
for(int i=0; i<expansion.length; i++)
public boolean directed = false;
public String color="black";
public ArrayList<Node> edges = new ArrayList<Node>();
+ public ArrayList<Object> labels = new ArrayList<Object>();
public ArrayList<Node> inbound = new ArrayList<Node>();
- public void edge(ToGraphViz o) {
+ public void edge(ToGraphViz o, Object label) {
Node n = o.toGraphViz(GraphViz.this);
if (n==null) return;
edges.add(n);
+ labels.add(label);
n.inbound.add(this);
}
public String name() {
}
public void edges(PrintWriter pw) {
if (simple()) return;
- for(Node n : edges)
- pw.println(" "+name()+" -> " + n.name() + " [color="+color+"];\n");
+ for(int i=0; i<edges.size(); i++) {
+ Node n = edges.get(i);
+ Object label = labels.get(i);
+ pw.println(" "+name()+" -> " + n.name() + " [color="+color+" " +(label==null?"":("label=\""+label+"\""))+ "];\n");
+ }
}
public int numEdges() { return edges.size(); }
public boolean simple() {
// #include (with renaming?)
// ANTLR uses ! and ^ suffixes
-s = ws grammar:Grammar ws
+s = !ws (grammar::Grammar) !ws
Grammar = NonTerminal +/ ws
NonTerminal = Word ^"=" RHS /ws