X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2Fmisc%2FReflectiveGrammar.java;h=146335cef85540d3ace9a13e1c5c0f6ccf9468f4;hb=b366a301b090a285c372f4fd77ab7472440f7d30;hp=ecf186de6d53e3f75e4d4892ab6f7875e20b725b;hpb=45d799349e635f1a99e3974e4504a43d5a7aaf33;p=sbp.git diff --git a/src/edu/berkeley/sbp/misc/ReflectiveGrammar.java b/src/edu/berkeley/sbp/misc/ReflectiveGrammar.java index ecf186d..146335c 100644 --- a/src/edu/berkeley/sbp/misc/ReflectiveGrammar.java +++ b/src/edu/berkeley/sbp/misc/ReflectiveGrammar.java @@ -14,6 +14,10 @@ public class ReflectiveGrammar extends MetaGrammar { public ReflectiveGrammar(Class baseClass) { this.baseClass = baseClass; } public Object convertLabel(String label) { return new ClassMark(label); } + public Object repeatTag() { return arrayMark; } + + private static class ArrayMark { } + private static final ArrayMark arrayMark = new ArrayMark(); private static class ClassMark { public final String clazz; @@ -33,44 +37,67 @@ public class ReflectiveGrammar extends MetaGrammar { public Object build(Tree t) throws Exception { return buildHead(t, null); } public Object buildHead(Tree t, Class c) throws Exception { - System.out.println("buildHead " + (c==null?null:c.getName()) + " " + t); + //System.out.println("buildHead " + (c==null?null:c.getName()) + " " + t); Object h = t.head(); - if (h != null && h instanceof ClassMark) return buildBody(t, Class.forName(baseClass.getName()+"$"+((ClassMark)h).clazz)); + if (h != null && h instanceof ClassMark) { + String clazz = ReflectiveWalker.mangle(((ClassMark)h).clazz); + Class c2 = (c!=null && c.getName().endsWith("$"+clazz)) ? c : Reflection.forNameOrNull(baseClass.getName()+"$"+clazz); + if (c2!=null) return buildBody(t, c2); + for(Method m : baseClass.getMethods()) { + if (!m.getName().equals(clazz)) continue; + Object[] o = new Object[m.getParameterTypes().length]; + for(int i=0; i=t.numChildren() ? null : buildHead(t.child(i), m.getParameterTypes()[i]); + return m.invoke(null, o); + } + throw new RuntimeException("couldn't figure out what to invoke for ClassMark " + clazz); + } else if (h==arrayMark && c==null) { + c = Object[].class; + } + if (c==null) System.out.println(h + " -- " + t.toPrettyString()); if (c.isArray()) { Object[] ret = new Object[t.numChildren()]; for(int i=0; i 0) throw new RuntimeException("can't buildHead() on a tree with children when the head is of type " + h.getClass().getName()); + if (t.numChildren() > 0) + throw new RuntimeException("can't buildHead() on a tree with children when the head is of type " + + h.getClass().getName() + "(c=="+(c==null?"null":c.getName())+")"); return h; } public Object buildBody(Tree t, Class c) throws Exception { System.out.println("buildBody " + (c==null?null:c.getName()) + " " + t); c = resolveClass(t, c); + if (c==null) return buildHead(t, null); Object o = c.newInstance(); Field[] f = c.getFields(); OUTER: for(int i=0; i t, Class c) throws Exception { if (c==null) return null; + if (c==int.class) return c; + if (c==String.class) return c; System.out.println("resolving " + c.getName()); if (Reflection.isConcrete(c)) return c; Class ret = null; @@ -99,6 +128,7 @@ public class ReflectiveGrammar extends MetaGrammar { throw new RuntimeException("couldn't decide between two classes:\n " + subs[i].getName() + "\n " + ret.getName()); ret = subs[i]; } + if (t.head()==null) return null; if (ret==null) throw new RuntimeException("couldn't find a class to match tree: " + t); return ret; }