public InnerAmbiguous(Forest<?> f) { this.f = f; }
}
- static <T> Forest<T> singleton(Input.Location loc, Position p) {
+ static <T> Forest<T> singleton(Input.Region loc, Position p) {
return create(loc, null, new Forest[] { }, false, true, p); }
- static <T> Forest<T> singleton(Input.Location loc, Forest<T> body, Position 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) {
+ static <T> Forest<T> singleton(Input.Region loc, Forest<T> body, Position p) { return body; }
+ static <T> Forest<T> leaf(Input.Region loc, T tag, Position p) { return create(loc, tag, null, false, false, p); }
+ public static <T> Forest<T> create(Input.Region loc, T tag, Forest<T>[] tokens, boolean unwrap, boolean singleton, Position p) {
return new MyBody<T>(loc, tag, tokens, unwrap, singleton, p);
}
// Body //////////////////////////////////////////////////////////////////////////////
ivbc.invoke(this, b, c);
}
- private final Input.Location location;
+ private final Input.Region location;
private final T tag;
private final Forest<T>[] tokens;
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.Region loc, T tag, Forest<T>[] tokens, boolean unwrap, boolean singleton, Position reduction) {
this.location = loc;
this.tag = tag;
this.tokens = tokens==null ? emptyForestArray : new Forest[tokens.length];
}
private void gather(TaskList tl, HashSet<Tree<T>>[] ht, HashSet<Tree<T>> target, Tree[] trees, int i) {
if (i==ht.length) {
- target.add(new Tree<T>(null, tag, trees));
+ target.add(new Tree<T>(location, tag, trees));
return;
}
for(Tree<T> tree : ht[i]) {
System.arraycopy(trees, 0, trees2, 0, trees.length-1);
for(int j=0; j<tree.numChildren(); j++)
trees2[trees.length-1+j] = tree.child(j);
- target.add(new Tree<T>(null, tag, trees2));
+ target.add(new Tree<T>(location, tag, trees2));
} else {
trees[i] = tree;
gather(tl, ht, target, trees, i+1);
} else {
tokens[i].visit(new TreeBuilder<T>(h.toss) {
- public void start(T head, Input.Location loc) { }
+ public void start(T head, Input.Region loc) { }
public void addTree(Tree<T> t) { toks.add(t); }
- public void finish(T head, Input.Location loc) {
+ public void finish(T head, Input.Region loc) {
int old = h.toks.size();
h.addTree(new Tree<T>(loc, head, toks.toArray(tree_hint)));
expand(i+1, h);
for(Node child : ((Forest.Ref<?>)result).parents) {
if (only != null && child!=only) continue;
holder[pos] = result;
- if (pos==0) child.finish(r, r.rewrite(phase().getLocation()), target);
+ if (pos==0) child.finish(r, r.rewrite(new Input.Region(child.phase().getLocation(), phase().getLocation())), target);
else child.reduce(r, pos-1, target, null);
}
public static class Region<Loc extends Location> /* implements Topology<Location<Tok>> */ {
public final Loc start;
public final Loc end;
+ public String toString() { return start+"-"+end; }
public Region(Loc a, Loc b) {
switch(a.compareTo(b)) {
case -1:
protected Parser(Table<Tok> pt) { this.pt = pt; }
/** implement this method to create the output forest corresponding to a lone shifted input token */
- public abstract Forest<Result> shiftToken(Tok t, Input.Location loc);
+ public abstract Forest<Result> shiftToken(Input.Location oldloc, Tok t, Input.Location newloc);
public boolean helpgc = true;
current.newNode(null, Forest.leaf(null, null, null), pt.start, true);
int count = 1;
for(int idx=0;;idx++) {
+ Input.Location oldloc = loc;
loc = input.getLocation();
current.reduce();
- Forest forest = current.token==null ? null : shiftToken((Tok)current.token, loc);
+ Forest forest = current.token==null ? null : shiftToken(oldloc, (Tok)current.token, loc);
GSS.Phase next = gss.new Phase<Tok>(current, this, current, input.next(), loc, forest);
if (!helpgc) {
FileOutputStream fos = new FileOutputStream("out-"+idx+".dot");
return epsilonForm;
}
- protected abstract <T> Forest<T> postReduce(Input.Location loc, Forest<T>[] args, Position p);
+ protected abstract <T> Forest<T> postReduce(Input.Region loc, Forest<T>[] args, Position p);
// Position //////////////////////////////////////////////////////////////////////////////
// Position /////////////////////////////////////////////////////////////////////////////////
- final <T> Forest<T> rewrite(Input.Location loc) { return rewrite(loc, true); }
- private final <T> Forest<T> rewrite(Input.Location loc, boolean epsilonCheck) {
+ final <T> Forest<T> rewrite(Input.Region loc) { return rewrite(loc, true); }
+ private final <T> Forest<T> rewrite(Input.Region loc, boolean epsilonCheck) {
if (epsilonCheck && this==firstp()) return epsilonForm();
for(int i=0; i<pos; i++) if (holder[i]==null) throw new Error("realbad " + i);
for(int i=pos; i<elements.length; i++) {
private final Object result;
public Constant(Element[] e, Object result) { super(e); this.result = result; }
Sequence _clone() { return new Constant(elements, result); }
- public <T> Forest<T> postReduce(Input.Location loc, Forest<T>[] args, Position p) {
+ public <T> Forest<T> postReduce(Input.Region loc, Forest<T>[] args, Position p) {
return (Forest<T>)Forest.leaf(loc, result, p);
}
static class Drop extends Constant {
private final int idx;
public Singleton(Element e) { this(new Element[] { e }, 0); }
public Singleton(Element[] e, int idx) { super(e); this.idx = idx; }
- public <T> Forest<T> postReduce(Input.Location loc, Forest<T>[] args, Position p) { return (Forest<T>)Forest.singleton(loc, args[idx], p); }
+ public <T> Forest<T> postReduce(Input.Region loc, Forest<T>[] args, Position p) { return (Forest<T>)Forest.singleton(loc, args[idx], p); }
Sequence _clone() { return new Singleton(elements,idx); }
}
public Unwrap(Element[] e, Object tag) { super(e); this.drops = null; this.tag = tag; }
public Unwrap(Element[] e, Object tag, boolean[] drops) { super(e); this.drops = drops; this.tag = tag; }
Sequence _clone() { return new Unwrap(elements, drops); }
- public <T> Forest<T> postReduce(Input.Location loc, Forest<T>[] args, Position p) {
+ public <T> Forest<T> postReduce(Input.Region 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, (T)tag, args, true, false, p);
int count = 0;
this.drops = drops == null ? new boolean[e.length] : drops;
for(int i=0; i<this.drops.length; i++) if (!this.drops[i]) count++;
}
- public <T> Forest<T> postReduce(Input.Location loc, Forest<T>[] args, Position p) {
+ public <T> Forest<T> postReduce(Input.Region 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];
final T head;
Tree<T>[] children;
- final Input.Location location;
+ final Input.Region location;
public T head() { return head; }
public int numChildren() { return children.length; }
public Iterator<Tree<T>> iterator() { return new ArrayIterator(children); }
public Tree<T> child(int i) { return children[i]; }
- public Input.Location getLocation() { return location; }
+ public Input.Region getRegion() { 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.Region loc, T head) { this(loc, head, null); }
+ public Tree(Input.Region loc, T head, Tree<T>[] children) {
this.location = loc;
this.head = head;
protected String headToString() { return head==null?null:head.toString(); }
protected String headToJava() {
+ // FIXME
if (head==null) return null;
if (head instanceof ToJava) {
StringBuffer sb = new StringBuffer();
((ToJava)head).toJava(sb);
return sb.toString();
}
- return head==null?"null":("\""+StringUtil.toJavaString(head.toString())+"\"");
+ return (head==null?"null":("\""+StringUtil.toJavaString(head.toString())+"\""));
}
protected String left() { return "{"; }
protected String right() { return "}"; }
public boolean isTransparent() { return false; }
public boolean isHidden() { return false; }
- public static interface TreeFunctor<T,R> extends Functor<Iterable<Tree<T>>, R> {
+ public static interface TreeFunctor<T,R> extends Functor<Tree<T>, R> {
}
public static class ArrayBuildingTreeFunctor<T> implements TreeFunctor<T,T[]>, ToJava {
public void toJava(StringBuffer sb) { sb.append("new Tree.ArrayBuildingTreeFunctor()"); }
public String toString() { return ""; }
- public T[] invoke(Iterable<Tree<T>> t) {
+ public T[] invoke(Tree<T> t) {
ArrayList ret = new ArrayList();
for(Tree tc : t) {
if (tc.head() != null && tc.head() instanceof Functor)
- ret.add(((Functor<Iterable<Tree>,Object>)tc.head()).invoke(tc.children()));
+ ret.add(((Functor<Iterable<Tree>,Object>)tc.head()).invoke(tc));
else if (tc.numChildren() == 0)
ret.add(tc.head());
else {
public abstract Annotation[][] getArgAnnotations();
public abstract String[] getArgNames();
+ public abstract Class[] getArgTypes();
public static Bindable create(Object o) {
if (o instanceof Class) return new BindableClass((Class)o);
public Object impose(Object[] fields) { return Reflection.impose(_method, fields); }
public Annotation[][] getArgAnnotations() { return _method.getParameterAnnotations(); }
public String[] getArgNames() { return new String[_method.getParameterTypes().length]; }
+ public Class[] getArgTypes() { return _method.getParameterTypes(); }
public void toJava(StringBuffer sb) {
sb.append("Bindable.create(");
sb.append(_method.getDeclaringClass().getName().replace('$','.'));
public Object impose(Object[] fields) { return Reflection.impose(_constructor, fields); }
public Annotation[][] getArgAnnotations() { return _constructor.getParameterAnnotations(); }
public String[] getArgNames() { return new String[_constructor.getParameterTypes().length]; }
+ public Class[] getArgTypes() { return _constructor.getParameterTypes(); }
public void toJava(StringBuffer sb) {
sb.append("Bindable.create(");
sb.append(_constructor.getDeclaringClass().getName().replace('$','.'));
ret[i] = fields[i].getName();
return ret;
}
+ public Class[] getArgTypes() {
+ Field[] fields = _class.getFields();
+ Class[] ret = new Class[fields.length];
+ for(int i=0; i<fields.length; i++)
+ ret[i] = fields[i].getType();
+ return ret;
+ }
public void toJava(StringBuffer sb) {
sb.append("Bindable.create(");
sb.append(_class.getName().replace('$','.'));
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);
+ public Forest<String> shiftToken(Location oldloc, Character ct, Location newloc) {
+ return Forest.create(new Input.Region(oldloc, newloc), ct.toString(), null, false, false, null);
}
}
public static class Target {
public int[] buildSequence(Production p) {
Annotation[][] annotations = _bindable.getArgAnnotations();
+ Class[] types = _bindable.getArgTypes();
String[] names = _bindable.getArgNames();
- String name = _bindable.getSimpleName();
- int len = annotations.length;
- int ofs = 0;
+ String name = _bindable.getSimpleName();
+ int len = annotations.length;
+ int ofs = 0;
bind.arg[] argtags = new bind.arg[len];
for(int i=0; i<names.length; i++)
for(Annotation a : annotations[i+ofs])
if (a instanceof bind.arg)
argtags[i+ofs] = (bind.arg)a;
- return Target.this.buildSequence(p, names, argtags);
+ return Target.this.buildSequence(p, names, argtags, types);
}
private Bindable _bindable;
return false;
}
- public int[] buildSequence(Production p, String[] names, bind.arg[] argtags) {
+ public int[] buildSequence(Production p, String[] names, bind.arg[] argtags, Class[] types) {
int argTagged = 0;
- for(int i=0; i<argtags.length; i++)
+ boolean hasloc = types.length>0 && types[0]==Input.Region.class;
+ for(int i=0; i<argtags.length; i++) {
+ if (i==0 && types[0]==Input.Region.class) continue;
if (argtags[i] != null)
argTagged++;
+ }
+ int numNames = names.length;
+ if (hasloc) numNames--;
// FIXME: can be smarter here
if (argTagged==p.count) {
int[] ret = new int[argtags.length];
int j = 0;
for(int i=0; i<argtags.length; i++) {
+ if (i==0 && types[0]==Input.Region.class) continue;
if (argtags[i]==null) continue;
if (argtags[i].value().equals(""))
ret[i] = j++;
}
}
return ret;
- } else if (names.length==p.count) {
+ } else if (numNames==p.count) {
int[] ret = new int[p.count];
- for(int i=0; i<p.count; i++) ret[i] = i;
+ for(int i=0; i<p.count; i++) ret[i] = i+(hasloc?1:0);
return ret;
} else {
return null;
this._israw = raw;
}
public String toString() { return "reducer-"+_bindable.toString(); }
- public Object invoke(Iterable<Tree<Object>> t) {
+ public Object invoke(Tree<Object> t) {
if (_israw) return _bindable.impose(new Object[] { t });
ArrayList ret = new ArrayList();
for(Tree tc : t) {
if (tc.head() != null && tc.head() instanceof Functor)
- ret.add(((Tree.TreeFunctor<Object,Object>)tc.head()).invoke(tc.children()));
+ ret.add(((Tree.TreeFunctor<Object,Object>)tc.head()).invoke(tc));
else if (tc.numChildren() == 0)
ret.add(tc.head());
else {
Object[] o = (Object[])ret.toArray(new Object[0]);
int max = 0;
for(int i=0; i<map.length; i++) max = Math.max(map[i], max);
+ if (_bindable.getArgTypes().length > 0 &&
+ _bindable.getArgTypes()[0]==Input.Region.class)
+ max++;
Object[] o2 = new Object[max+1];
for(int i=0; i<o.length; i++) o2[map[i]] = o[i];
+ if (_bindable.getArgTypes().length > 0 &&
+ _bindable.getArgTypes()[0]==Input.Region.class)
+ o2[0] = t.getRegion();
return _bindable.impose(o2);
}
}
public static Union make(Tree t, String s) { return make(t, s, new AnnotationGrammarBindingResolver(MetaGrammarBindings.class)); }
public static Union make(Tree t, String s, GrammarBindingResolver rm) {
Tree.TreeFunctor<Object,Object> red = (Tree.TreeFunctor<Object,Object>)t.head();
- MetaGrammarBindings.GrammarNode g = (MetaGrammarBindings.GrammarNode)red.invoke(t.children());
+ MetaGrammarBindings.GrammarNode g = (MetaGrammarBindings.GrammarNode)red.invoke(t);
return g.build(s, rm);
}
public Context(Tree t, GrammarBindingResolver rm) {
this.rm = rm;
Tree.TreeFunctor<Object,Object> red = (Tree.TreeFunctor<Object,Object>)t.head();
- this.grammar = (GrammarNode)red.invoke(t.children());
+ this.grammar = (GrammarNode)red.invoke(t);
}
public Union peek(String name) { return map.get(name); }
public void put(String name, Union u) { map.put(name, u); }
public int getRow() { return row; }
public Location(int col, int row) { this.row = row; this.col = col; }
public int compareTo(Input.Location loc) throws ClassCastException {
- if (!(loc instanceof Cartesian)) throw new ClassCastException();
+ if (!(loc instanceof Cartesian.Location)) throw new ClassCastException(loc.getClass().getName());
Location<Tok> c = (Location<Tok>)loc;
if (row < c.row) return -1;
if (row > c.row) return 1;
// below is ugly voodoo which will go away very soon. ignore it.
Tree.TreeFunctor tf = (Tree.TreeFunctor)tree.head();
- Math.Expr e = (Math.Expr)tf.invoke(tree.children());
+ Math.Expr e = (Math.Expr)tf.invoke(tree);
// above is ugly voodoo which will go away very soon. ignore it.
System.out.println("done!");
System.err.println("expanding...");
Tree t = r2.expand1();
- TestCase[] expanded = (TestCase[])((Functor)t.head()).invoke(t.children());
+ TestCase[] expanded = (TestCase[])((Functor)t.head()).invoke(t);
System.err.println("executing...");
for(TestCase tc : expanded) {
tc.execute();
public boolean toss;
protected T head;
public TreeBuilder(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 start(T head, Input.Region loc);
+ public abstract void finish(T head, Input.Region loc);
public abstract void addTree(Tree<T> t);
public void invoke(Forest.Body<T> bod, Boolean o, Integer i) {
if (i==null) {