checkpoint
[sbp.git] / src / edu / berkeley / sbp / misc / RegressionTests.java
1 package edu.berkeley.sbp.misc;
2 import java.io.*;
3 import java.util.*;
4 import java.lang.reflect.*;
5 import edu.berkeley.sbp.*;
6 import edu.berkeley.sbp.misc.*;
7 import edu.berkeley.sbp.tib.*;
8 import edu.berkeley.sbp.chr.*;
9 import edu.berkeley.sbp.util.*;
10
11 public class RegressionTests {
12
13     public static boolean yes = false;
14
15     public static void main(String[] s) throws Exception {
16         try {
17             boolean profile = false;
18             if (s[0].equals("-profile")) {
19                 profile = true;
20                 String[] s2 = new String[s.length-1];
21                 System.arraycopy(s, 1, s2, 0, s2.length);
22                 s = s2;
23             }
24
25             //MetaGrammar mg0 = new MetaGrammar();
26             //mg0.walk(MetaGrammar.meta);
27             //System.out.println(mg0);
28             Tree<String> res = new CharParser(MetaGrammar.make()).parse(new FileInputStream(s[0])).expand1();
29             MetaGrammar mg = (MetaGrammar)new MetaGrammar().walk(res);
30             //System.out.println(mg);
31             Union meta = mg.done();
32             SequenceInputStream sis = new SequenceInputStream(new FileInputStream(s[0]), new FileInputStream(s[1]));
33             res = new CharParser(meta).parse(sis).expand1();
34             Union testcasegrammar = ((MetaGrammar)new MetaGrammar("ts").walk(res)).done("ts");
35             if (testcasegrammar==null) return;
36             CharParser parser = new CharParser(testcasegrammar);
37
38             if (profile) {
39                 System.out.println("\nready...");
40                 System.in.read();
41             }
42             System.gc();
43             long now = System.currentTimeMillis();
44             Forest<String> r2 = parser.parse(new FileInputStream(s[2]));
45             System.out.println();
46             System.out.println("elapsed = " + (System.currentTimeMillis()-now) + "ms");
47             if (profile) {
48                 System.out.println("\ndone");
49                 System.in.read();
50                 System.exit(0);
51             }
52             for(TestCase tc : (TestCase[])new TestCaseBuilder().walk(r2.expand1())) tc.execute();
53
54         } catch (Throwable t) {
55             System.err.println("\n\nexception thrown, class == " + t.getClass().getName());
56             System.err.println(t);
57             System.err.println();
58             t.printStackTrace();
59             System.err.println();
60         }
61     }
62
63     public static class TestCase {
64         private final boolean tib;
65         private final boolean jav;
66         public final String input;        
67         public final String[] output;
68         public final Union grammar;
69         public TestCase(String input, String[] output, Union grammar, boolean tib, boolean jav) throws IOException {
70             this.tib = tib;
71             this.jav = jav;
72             this.input = input;
73             this.output = output;
74             this.grammar = grammar;
75         }
76         public String toString() {
77             String ret = "testcase {\n" + "  input \""+input+"\";\n";
78             for(String s : output) ret += "  output \""+s+"\";\n";
79             ret += grammar +"\n}\n";
80             return ret;
81         }
82         public boolean execute() throws Exception {
83             if (jav) {
84                 Forest<String> tree = new CharParser(grammar).parse(new StringReader(input));
85                 FileOutputStream fos = new FileOutputStream("/Users/megacz/Desktop/out.dot");
86                 PrintWriter p = new PrintWriter(new OutputStreamWriter(fos));
87                 GraphViz gv = new GraphViz();
88                 tree.toGraphViz(gv);
89                 gv.dump(p);
90                 p.flush();
91                 p.close();
92                 return true;
93             }
94             Forest<String> res = null;
95             ParseFailed pfe = null;
96             try {
97                 res = tib 
98                     ? /*new CharParser(grammar).parse(new Tib(input))*/ null
99                 : new CharParser(grammar).parse(new StringReader(input));
100             } catch (ParseFailed pf) {
101                 pfe = pf;
102             }
103             //ystem.out.println("res=="+res);
104             Collection<Tree<String>> results = res==null ? new HashSet<Tree<String>>() : res.expand(false);
105             System.out.print("\r");
106             if (results.size() == 0 && output.length > 0) {
107                 System.out.print("\033[31m");
108                 System.out.println("PARSE FAILED");
109                 System.out.print("\033[0m");
110                 if (pfe != null) pfe.printStackTrace();
111             } else {
112                 System.out.print("\r                                                                                                              \r");
113             }
114             HashSet<String> outs = new HashSet<String>();
115             if (output != null) for(String s : output) outs.add(s.trim());
116             boolean bad = false;
117             for (Tree<String> r : results) {
118                 String s = r.toString().trim();
119                 if (outs.contains(s)) { outs.remove(s); continue; }
120                 if (!bad) System.out.println(input);
121                 System.out.print("\033[33m");
122                 System.out.println("     GOT: " + s);
123                 bad = true;
124             }
125             for(String s : outs) {
126                 if (!bad) System.out.println(input);
127                 System.out.print("\033[31m");
128                 System.out.println("EXPECTED: " + s);
129                 bad = true;
130             }
131             if (bad) {
132                 System.out.println("\033[0m");
133                 return true;
134             }             
135             System.out.println("\r\033[32mPASS\033[0m                                                                              ");
136             return false;
137         }
138     }
139
140     public static class TestCaseBuilder extends MetaGrammar {
141         public Object walk(Tree<String> tree) {
142             try {
143                 if ("grammar".equals(tree.head())) { walkChildren(tree); return done("s"); }
144                 else if ("output".equals(tree.head())) return string(tree.children());
145                 else if ("input".equals(tree.head())) return string(tree.children());
146                 else if ("javacase".equals(tree.head()) || "tibcase".equals(tree.head()) || "testcase".equals(tree.head())) {
147                     String input = string(tree.child(0));
148                     String[] output = tree.numChildren()>2 ? ((String[])walk(tree, 1)) : new String[0];
149                     boolean tib = "tibcase".equals(tree.head());
150                     boolean jav = "javacase".equals(tree.head());
151                     MetaGrammar gram = jav ? new JavaGrammar() : tib ? /*new Tib.Grammar()*/null : new MetaGrammar();
152                     Union grammar = (Union)((MetaGrammar)(gram.walk(tree, tree.numChildren()-1))).done("s");
153                     return new TestCase(input, output, grammar, tib, jav);
154                 } else if ("ts".equals(tree.head())) return walk(tree, 0);
155                 else return super.walk(tree);
156             } catch (Exception e) {
157                 throw new Error(e);
158             }
159         }
160     }
161
162     public static class JavaGrammar extends MetaGrammar {
163         public Object convertLabel(String label) { return new ClassMark(label); }
164         public Object convertFieldLabel(String label) { return new FieldMark(label); }
165
166         private static class FieldMark {
167             public final String field;
168             public FieldMark(String field) { this.field = field; }
169             public String toString() { return "."+field; }
170         }
171         private static class ClassMark {
172             public final String clazz;
173             public ClassMark(String clazz) { this.clazz = clazz; }
174             public String toString() { return clazz+"$"; }
175         }
176
177         public static Object build(Tree<Object> t, Class c) throws Exception {
178             System.out.println("** build " + c.getName() + " " + t.toPrettyString());
179             Object h = t.head();
180             if (h instanceof ClassMark) return build2(t, Class.forName(JavaGrammar.class.getName()+"$"+((ClassMark)h).clazz));
181             Object o = null;
182             if (t.numChildren()==0) o = t.head();
183             else if (t.head()==null) return build2(t, c);
184             else if (t.head() instanceof FieldMark) {
185                 return build2(new Tree(null, new Tree[] { t }), c);
186             } else {
187                 throw new Exception("don't know how to cope: " + c.getName() + " <- " + t.toPrettyString());
188             }
189             return Reflection.rebuild(o, c);
190         }
191         private static Object build2(Tree<Object> t, Class c) throws Exception {
192             System.out.println("** build2 " + c.getName() + " " + t.toPrettyString());
193             if (!Reflection.isConcrete(c)) {
194                 Field f = c.getField("subclasses");
195                 if (f==null) throw new Exception("don't know how to cope: " + c.getName() + " <- " + t.toPrettyString());
196                 Class[] subs = (Class[])f.get(null);
197                 OUTER: for(int i=0; i<subs.length; i++) {
198                     for(Tree<Object> t2 : t) {
199                         Object o2 = t2.head();
200                         System.out.println("checking  " + o2 + " in " + subs[i].getName());
201                         if (o2 instanceof FieldMark) {
202                             if (subs[i].getField(((FieldMark)o2).field)==null) continue OUTER;
203                         }
204                     }
205                     c = subs[i];
206                     break;
207                 }
208             }
209             Object o = c.newInstance();
210             for(Tree<Object> t2 : t) {
211                 Object o2 = t2.head();
212                 if (o2 instanceof FieldMark) {
213                     FieldMark f = (FieldMark)o2;
214                     Field field = c.getField(ReflectiveWalker.mangle(f.field));
215                     Object tgt = build(t2.child(0), field.getType());
216                     System.out.println("setting " + f.field +
217                                        " on a " + o.getClass().getName() +
218                                        " to " + (tgt==null?"null":tgt.getClass().getName()));
219                     field.set(o, tgt);
220                 }
221             }
222             System.out.println("returning a " + o.getClass().getName());
223             return o;
224         }
225         public static Object build(Tree<Object> t) throws Exception {
226             Object h = t.head();
227             if (h instanceof ClassMark) {
228                 ClassMark cm = (ClassMark)h;
229                 Class c = Class.forName(JavaGrammar.class.getName() + "$" + ReflectiveWalker.mangle(cm.clazz));
230                 return build2(t, c);
231             }
232             
233             return h==null ? null : h.toString();
234         }
235         
236         public static interface Expr {
237             public static Class[] subclasses = new Class[] { _plus_.class, num.class };
238         }
239         public static class _plus_ implements Expr {
240             public Expr left;
241             public Expr right;
242             public String toString() { return left + "+" + right; }
243         }
244         public static class num implements Expr {
245             public String val;
246             public String toString() { return "["+val+"]"; }
247         }
248
249     }
250
251     private static String pad(int i,String s) { return s.length() >= i ? s : pad(i-1,s)+" "; }
252 }
253