1    package org.xwt.util;
2    
3    import java.util.*;
4    import java.io.*;
5    import org.xwt.js.*;
6    
7    public abstract class Grammar extends JS {
8    
9        public JS action = null;
10       public Grammar() { }
11   
12       // means we call()ed a Grammar that hasn't been bound to a scope yet
13       public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
14           throw new Error("this should never happen");
15       }
16   
17       private static Object NULL = new Object();
18       
19       public abstract int match(String s, int start, Hash v, JSScope scope) throws JSExn;
20       public int matchAndWrite(final String s, final int start, Hash v, JSScope scope, String key) throws JSExn {
21           final Hash v2 = new Hash();
22           final int ret = match(s, start, v2, scope);
23           Object result = ret == -1 ? NULL : action == null ?
24               s.substring(start, ret) :
25               JS.cloneWithNewParentScope(action, new JSScope(scope) {
26                       public Object get(Object key) throws JSExn {
27                           Object val = v2.get(key);
28                           if (val == NULL) return null;
29                           if (val != null) return val;
30                           if (key.equals("whole")) return s.substring(start, ret);
31                           return super.get(key);
32                       }
33                   }).call(null, null, null, null, 0);
34           if (key != null) {
35               Object old = v.get(key);
36               if (old == null || old == NULL) { }
37               else if (old instanceof JSArray) { if (result != NULL) { ((JSArray)old).addElement(result); result = old; } }
38               else if (result != NULL) { JSArray j = new JSArray(); j.addElement(old); j.addElement(result); result = j; }
39               v.put(key, result);
40           }
41           return ret;
42       }
43   
44       public static class Alternative extends Grammar {
45           private GrammarGrammarr1        public Alternative(Grammar r1, Grammar r2) { this.r1 = r1; this.r2 = r2; }
46           public int match(String s, int start, Hash v, JSScope r) throws JSExn {
47               int s1 = r1.match(s, start, v, r);
48               if (s1 != -1) return s1;
49               int s2 = r2.match(s, start, v, r);
50               if (s2 != -1) return s2;
51               return -1;
52           }
53       }
54   
55       public static class Juxtaposition extends Grammar {
56           private Grammar r1, r2;
57           public Juxtaposition(Grammar r1, Grammar r2) { this.r1 = r1; this.r2 = r2; }
58           public int match(String s, int start, Hash v, JSScope r) throws JSExn {
59               int s1 = r1.match(s, start, v, r);
60               if (s1 == -1) return -1;
61               int s2 = r2.match(s, s1, v, r);
62               if (s2 == -1) return -1;
63               return s2;
64           }
65       }
66   
67       public static class Repetition extends Grammar {
68           private Grammar r1;
69           private int min, max;
70           public Repetition(Grammar r1, int min, int max) { this.r1 = r1; this.min = min; this.max = max; }
71           public int match(String s, int start, Hash v, JSScope r) throws JSExn {
72               int i;
73               for(i=0; i<max; i++) {
74                   start = r1.match(s, start, v, r);
75                   if (start == -1) return -1;
76               }
77               if (i < min) return -1;
78               return start;
79           }
80       }
81   
82       public static class Literal extends Grammar {
83           String str;
84           public Literal(String str) { this.str = str; }
85           public int match(String s, int start, Hash v, JSScope r) {
86               if (!s.regionMatches(start, str, 0, str.length())) return -1;
87               return start + str.length();
88           }
89       }
90   
91       public static class Range extends Grammar {
92           char min, max;
93           public Range(char min, char max) { this.min = min; this.max = max; }
94           public int match(String s, int start, Hash v, JSScope r) throws JSExn {
95               if (!(s.charAt(start) >= min && s.charAt(start) <= max)) return -1;
96               return start + 1;
97           }
98       }
99   
100      public static class Reference extends Grammar {
101          String key;
102          public Reference(String key) { this.key = key; }
103          public int match(String s, int start, Hash v, JSScope scope) throws JSExn {
104              return ((Grammar)scope.get(key)).matchAndWrite(s, start, v, scope, key);
105          }
106      }
107  }
108  ?????????????????????????????r2????????????????Alternative????????????????????????????Grammar????????????????????????????????????????Grammar????????????????????????????????????????????????????????????????r1??????????????????????????????????????????????????????????????????????????????r2????????????????int????????????????????match????????????????????????????????????int???????????????????????????????????????????????Hash???????????????????????????????????????????????????????JSScope?????????????????????????????????????????????????????????????????????????JSExn?????????????int??????????????????????r1?????????????????????????match???????????????????????????????s??????????????????????????????????start?????????????????????????????????????????v????????????????????????????????????????????r?????????????????s1??????????????????????????????????s1?????????????int??????????????????????r2?????????????????????????match???????????????????????????????s??????????????????????????????????start?????????????????????????????????????????v????????????????????????????????????????????r?????????????????s2??????????????????????????????????s2?????????????????????????Juxtaposition???????????????????????????????????????????????Grammar?????????????????Grammar?????????????????Grammar?????????????????????????r1?????????????????????????????r2????????????????Juxtaposition??????????????????????????????Grammar??????????????????????????????????????????Grammar??????????????????????????????????????????????????????????????????r1????????????????????????????????????????????????????????????????????????????????r2????????????????int????????????????????match????????????????????????????????????int???????????????????????????????????????????????Hash???????????????????????????????????????????????????????JSScope?????????????????????????????????????????????????????????????????????????JSExn?????????????int??????????????????????r1?????????????????????????match???????????????????????????????s??????????????????????????????????start?????????????????????????????????????????v????????????????????????????????????????????r?????????????????s1?????????????int??????????????????????r2?????????????????????????match???????????????????????????????s??????????????????????????????????s1??????????????????????????????????????v?????????????????????????????????????????r?????????????????s2????????????????????s2?????????????????????????Repetition????????????????????????????????????????????Grammar?????????????????Grammar?????????????????????????r1?????????????????int?????????????????int?????????????????????min??????????????????????????max????????????????Repetition???????????????????????????Grammar???????????????????????????????????????int????????????????????????????????????????????????int?????????????????????????????????????????????????????????????????????r1????????????????????????????????????????????????????????????????????????????????????min????????????????????????????????????????????????????????????????????????????????????????????????????max????????????????int????????????????????match????????????????????????????????????int???????????????????????????????????????????????Hash???????????????????????????????????????????????????????JSScope?????????????????????????????????????????????????????????????????????????JSExn?????????????int?????????????????i??????????????????????i????????????????????????max?????????????????????????????i?????????????????start?????????????????????????r1????????????????????????????match??????????????????????????????????s?????????????????????????????????????start????????????????????????????????????????????v???????????????????????????????????????????????r?????????????????????start?????????????????i?????????????????????min????????????????????start?????????????????????????Literal?????????????????????????????????????????Grammar????????????????str????????????????Literal?????????????????????????????????????????????????str????????????????int????????????????????match????????????????????????????????????int???????????????????????????????????????????????Hash???????????????????????????????????????????????????????JSScope??????????????????s??????????????????????????????????start?????????????????????????????????????????str?????????????????????????????????????????????????str????????????????????start????????????????????????????str?????????????????????????Range???????????????????????????????????????Grammar?????????char?????????char??????????????min???????????????????max????????????????Range??????????????????????char????????????????????????????????char???????????????????????????????????????????????????????min???????????????????????????????????????????????????????????????????????max????????????????int????????????????????match????????????????????????????????????int???????????????????????????????????????????????Hash???????????????????????????????????????????????????????JSScope?????????????????????????????????????????????????????????????????????????JSExn???????????????????s????????????????????????????start??????????????????????????????????????min?????????????????????????????????????????????s??????????????????????????????????????????????????????start????????????????????????????????????????????????????????????????max????????????????????start?????????????????????????Reference???????????????????????????????????????????Grammar????????????????key????????????????Reference???????????????????????????????????????????????????key????????????????int????????????????????match????????????????????????????????????int???????????????????????????????????????????????Hash???????????????????????????????????????????????????????JSScope?????????????????????????????????????????????????????????????????????????????JSExn??????????????????????????????scope????????????????????????????????????get????????????????????????????????????????key????????????????????????????????????????????????????????????s???????????????????????????????????????????????????????????????start??????????????????????????????????????????????????????????????????????v?????????????????????????????????????????????????????????????????????????scope????????????????????????????????????????????????????????????????????????????????key