d157de92949b3bfefddedc3b3c2ad2a6333346ee
[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.meta.*;
8 import edu.berkeley.sbp.bind.*;
9 import edu.berkeley.sbp.tib.*;
10 import edu.berkeley.sbp.chr.*;
11 import edu.berkeley.sbp.util.*;
12 import static edu.berkeley.sbp.meta.MetaGrammar.*;
13
14 public class RegressionTests {
15
16     public static boolean yes = false;
17     public static boolean graph = false;
18
19     public static void main(String[] s) throws Exception {
20         try {
21             boolean profile = false;
22             if (s[0].equals("-graph")) {
23                 graph = true;
24                 String[] s2 = new String[s.length-1];
25                 System.arraycopy(s, 1, s2, 0, s2.length);
26                 s = s2;
27             }
28             if (s[0].equals("-profile")) {
29                 profile = true;
30                 String[] s2 = new String[s.length-1];
31                 System.arraycopy(s, 1, s2, 0, s2.length);
32                 s = s2;
33             }
34
35             System.err.println("parsing " + s[0]);
36             Tree<String> res = new CharParser(MetaGrammar.make()).parse(new FileInputStream(s[0])).expand1();
37             Union meta = MetaGrammar.make(res, "s");
38
39             System.err.println("parsing " + s[1]);
40             SequenceInputStream sis = new SequenceInputStream(new FileInputStream(s[0]), new FileInputStream(s[1]));
41             res = new CharParser(meta).parse(sis).expand1();
42
43             Union testcasegrammar = MetaGrammar.make(res, "ts", new TestCaseMaker());
44             if (testcasegrammar==null) return;
45             CharParser parser = new CharParser(testcasegrammar);
46
47             if (profile) {
48                 System.out.println("\nready...");
49                 System.in.read();
50             }
51             System.gc();
52             long now = System.currentTimeMillis();
53             System.err.println("parsing " + s[2]);
54             Forest<String> r2 = parser.parse(new FileInputStream(s[2]));
55             System.out.println();
56             System.out.println("elapsed = " + (System.currentTimeMillis()-now) + "ms");
57             if (profile) {
58                 System.out.println("\ndone");
59                 System.in.read();
60                 System.exit(0);
61             }
62             System.err.println("expanding...");
63
64             Tree t = r2.expand1();
65             TestCase[] expanded = (TestCase[])((Functor)t.head()).invoke(t.children());
66             System.err.println("executing...");
67             for(TestCase tc : expanded) {
68                 tc.execute();
69                 /*
70                 String st = "a";
71                 for(int i=0; i<12; i++) {
72                     //System.out.println("length " + st.length());
73                     tc.input = st;
74                     long nowy = System.currentTimeMillis();
75                     GSS.shifts = 0;
76                     GSS.reductions = 0;
77                     tc.execute();
78                     System.out.println("length " + st.length() + " => " + ((System.currentTimeMillis()-nowy)/1000.0) + " " + GSS.shifts + " " + GSS.reductions);
79                     st = st+st;
80                 }
81                 */
82             }
83
84         } catch (Throwable t) {
85             System.err.println("\n\nexception thrown, class == " + t.getClass().getName());
86             System.err.println(t);
87             System.err.println();
88             t.printStackTrace();
89             System.err.println();
90         }
91     }
92
93     public static class TestCaseMaker extends AnnotationGrammarBindingResolver {
94         public TestCaseMaker() {
95             super(TestCaseMakerHelper.class, new Class[] {
96                      MetaGrammarBindings.Grammar.class,
97                      MetaGrammarBindings.NonTerminal.class,
98                      MetaGrammarBindings.AnonUn.class,
99                      MetaGrammarBindings.Range.class,
100                      MetaGrammarBindings.El.class,
101                      MetaGrammarBindings.Seq.class,
102                      MetaGrammarBindings.NonTerminalReference.class,
103                      MetaGrammarBindings.StringLiteral.class,
104                      MetaGrammarBindings.XTree.class,
105                      MetaGrammarBindings.CharClass.class
106             });
107         }
108         public static class TestCaseMakerHelper extends MetaGrammarBindings {
109             public static @bind.as("grammaro") @bind.raw Object grammaro(Iterable<Tree> t) {
110                 System.out.println("working on " + t);
111                 return MetaGrammar.make(t.iterator().next(), "s", new GrammarBindingResolver());
112             }
113             //public static @bind.as("tca")           Object tca(Object[] o) throws IOException {
114             //return new TestCase((String)o[0], (String[])o[1], (Union)o[2], false, false); }
115             public static @bind.as("tca")           Object tca(String input, String[] output, Union u) throws IOException {
116                 return new TestCase(input, output, u, false, false); }
117             public static @bind.as("tcb")           Object tca(String input, Union u) throws IOException {
118                 return new TestCase(input, new String[0], u, false, false); }
119             public static @bind.as("ts") TestCase[] go(TestCase[] cases) { return cases; }
120             public static @bind.as("o") Object o(Object[] s) { return s; }
121         }
122     }
123
124     public static class TestCase {
125         private final boolean tib;
126         private final boolean jav;
127         public /*final*/ String input;        
128         public final String[] output;
129         public final Union grammar;
130
131         public TestCase(String input, String[] output, Union grammar, boolean tib, boolean jav) throws IOException {
132             this.tib = tib;
133             this.jav = jav;
134             this.input = input;
135             this.output = output==null ? new String[0] : output;
136             this.grammar = grammar;
137         }
138         public String toString() {
139             String ret = "testcase {\n" + "  input \""+input+"\";\n";
140             for(String s : output) ret += "  output \""+s+"\";\n";
141             ret += grammar +"\n}\n";
142             return ret;
143         }
144         public boolean execute() throws Exception {
145             Forest<String> res = null;
146             ParseFailed pfe = null;
147             CharParser parser = new CharParser(grammar);
148             //parser.helpgc = false;
149             try {
150                 res = tib 
151                     ? /*new CharParser(grammar).parse(new Tib(input))*/ null
152                 : parser.parse(new StringReader(input));
153             } catch (ParseFailed pf) {
154                 pfe = pf;
155             }
156             //ystem.out.println("res=="+res);
157
158             if (graph) {
159                 FileOutputStream fos = new FileOutputStream("out.dot");
160                 PrintWriter p = new PrintWriter(new OutputStreamWriter(fos));
161                 GraphViz gv = new GraphViz();
162                 res.toGraphViz(gv);
163                 gv.dump(p);
164                 p.flush();
165                 p.close();
166                 System.out.println(parser);
167             }
168             Collection<Tree<String>> results = res==null ? new HashSet<Tree<String>>() : res.expand(false);
169             System.out.print("\r");
170             if (results == null || (results.size() == 0 && (output!=null && output.length > 0))) {
171                 System.out.print("\033[31m");
172                 System.out.println("PARSE FAILED");
173                 System.out.print("\033[0m");
174                 if (pfe != null) pfe.printStackTrace();
175             } else {
176                 System.out.print("\r                                                                                                              \r");
177             }
178             HashSet<String> outs = new HashSet<String>();
179             if (output != null) for(String s : output) outs.add(s.trim());
180             boolean bad = false;
181             for (Tree<String> r : results) {
182                 String s = r.toString().trim();
183                 if (outs.contains(s)) { outs.remove(s); continue; }
184                 if (!bad) System.out.println(input);
185                 System.out.print("\033[33m");
186                 System.out.println("     GOT: " + s);
187                 bad = true;
188             }
189             for(String s : outs) {
190                 if (!bad) System.out.println(input);
191                 System.out.print("\033[31m");
192                 System.out.println("EXPECTED: " + s);
193                 bad = true;
194             }
195             if (bad) {
196                 System.out.println("\033[0m");
197                 return true;
198             }             
199             System.out.println("\r\033[32mPASS\033[0m                                                                              ");
200
201             return false;
202         }
203     }
204
205     public static class TestCaseBuilder extends StringWalker {
206         public Object walk(Tree<String> tree) {
207             try {
208                 if ("grammaro".equals(tree.head())) return MetaGrammar.make(tree, "s");
209                 else if ("output".equals(tree.head())) return string(tree.children());
210                 else if ("input".equals(tree.head())) return string(tree.children());
211                 else if ("testcase".equals(tree.head())) {
212                     String input = string(tree.child(0));
213                     String[] output = tree.numChildren()>2 ? ((String[])walk(tree, 1)) : new String[0];
214                     Union grammar = MetaGrammar.make(tree.child(tree.numChildren()-1), "s");
215                     TestCase tc = new TestCase(input, output, grammar, false, false);
216                     return tc;
217                 } else if ("ts".equals(tree.head())) return walk(tree, 0);
218                 else if (tree.head() == null) {
219                     Object[] ret = new Object[tree.numChildren()];
220                     for(int i=0; i<ret.length; i++)
221                         ret[i] = walk(tree.child(i));
222                     return Reflection.lub(ret);
223                 }
224                 return super.walk(tree);
225             } catch (Exception e) {
226                 throw new Error(e);
227             }
228         }
229     }
230     private static String pad(int i,String s) { return s.length() >= i ? s : pad(i-1,s)+" "; }
231     public static String string(Tree<String> tree) {
232         String ret = "";
233         if (tree.head()!=null) ret += tree.head();
234         ret += string(tree.children());
235         return ret;
236     }
237     public static String string(Iterable<Tree<String>> children) {
238         String ret = "";
239         for(Tree<String> t : children) ret += string(t);
240         return ret;
241     }
242 }