Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

254
LINES

< > BotCompany Repo | #1003021 // unstructure with back references

JavaX fragment (include)

1  
static class DynamicObject {
2  
  S className;
3  
  new Map<S, O> fieldValues;
4  
}
5  
6  
static Object unstructure(String text) {
7  
  ret unstructure(text, false);
8  
}
9  
10  
static Object unstructure(String text, boolean allDynamic) {
11  
  ret unstructure(text, allDynamic, new HashMap<Integer, O>());
12  
}
13  
14  
static Object unstructure(String text, final boolean allDynamic,
15  
  final HashMap<Integer, O> seen) {
16  
  final L<S> tok = javaTok(text);
17  
  final boolean debug = true;
18  
  
19  
  class X {
20  
    int i = 1;
21  
22  
    Object parse() {
23  
      // the non-backreference things
24  
      
25  
      String t = tok.get(i);
26  
      
27  
      if (debug)
28  
        print("parse: " + quote(t));
29  
        
30  
      if (t.startsWith("\"")) {
31  
        String s = unquote(tok.get(i));
32  
        i += 2;
33  
        return s;
34  
      }
35  
      if (t.equals("bigint"))
36  
        return parseBigInt();
37  
      if (t.equals("d"))
38  
        return parseDouble();
39  
      if (t.equals("false")) {
40  
        i += 2; return false;
41  
      }
42  
      if (t.equals("true")) {
43  
        i += 2; return true;
44  
      }
45  
      if (t.equals("-")) {
46  
        t = tok.get(i+2);
47  
        i += 4;
48  
        t = dropSuffix("L", t);
49  
        long l = -Long.parseLong(t);
50  
        ret l == (int) l ? (int) l : l;
51  
      }
52  
      if (isInteger(t) || isLongConstant(t)) {
53  
        i += 2;
54  
        t = dropSuffix("L", t);
55  
        long l = Long.parseLong(t);
56  
        ret l == (int) l ? (int) l : l;
57  
      }
58  
      
59  
      if (t.startsWith("r") && isInteger(t.substring(1))) {
60  
        i += 2;
61  
        int ref = Integer.parseInt(t.substring(1));
62  
        O o = seen.get(ref);
63  
        if (o == null)
64  
          print("Warning: unsatisfied back reference " + ref);
65  
        ret o;
66  
      }
67  
      
68  
      O o = parse_inner();
69  
      seen.put(seen.size()+1, o);
70  
      ret o;
71  
    }
72  
    
73  
    // everything that can be backreferenced
74  
    O parse_inner() {
75  
      String t = tok.get(i);
76  
      
77  
      if (debug)
78  
        print("parse_inner: " + quote(t));
79  
        
80  
      if (t.equals("hashset"))
81  
        return parseHashSet();
82  
      if (t.equals("treeset"))
83  
        return parseTreeSet();
84  
      if (t.equals("hashmap"))
85  
        return parseHashMap();
86  
      if (t.equals("{"))
87  
        return parseMap();
88  
      if (t.equals("["))
89  
        return parseList();
90  
      if (t.equals("array"))
91  
        return parseArray();
92  
      if (t.equals("class"))
93  
        return parseClass();
94  
      if (t.equals("l"))
95  
        return parseLisp();
96  
      if (t.equals("null")) {
97  
        i += 2; return null;
98  
      }
99  
      if (isJavaIdentifier(t)) {
100  
        Class c = allDynamic ? null : findClass(t);
101  
        DynamicObject dO = null;
102  
        O o = null;
103  
        if (c != null)
104  
          o = nuObject(c);
105  
        else {
106  
          dO = new DynamicObject;
107  
          dO.className = t;
108  
        }
109  
        i += 2;
110  
        if (i < tok.size() && tok.get(i).equals("(")) {
111  
          consume("(");
112  
          while (!tok.get(i).equals(")")) {
113  
            // It's like parsing a map.
114  
            //Object key = parse();
115  
            //if (tok.get(i).equals(")"))
116  
            //  key = onlyField();
117  
            String key = unquote(tok.get(i));
118  
            i += 2;
119  
            consume("=");
120  
            Object value = parse();
121  
            if (o != null)
122  
              setOpt(o, key, value);
123  
            else
124  
              dO.fieldValues.put(key, value);
125  
            if (tok.get(i).equals(",")) i += 2;
126  
          }
127  
          consume(")");
128  
        }
129  
        return o != null ? o : dO;
130  
      }
131  
      throw new RuntimeException("Unknown token " + (i+1) + ": " + t);
132  
    }
133  
    
134  
    Object parseSet(Set set) {
135  
      set.addAll((L) parseList());
136  
      return set;
137  
    }
138  
    
139  
    Object parseLisp() {
140  
      consume("l");
141  
      consume("(");
142  
      List list = new ArrayList;
143  
      while (!tok.get(i).equals(")")) {
144  
        list.add(parse());
145  
        if (tok.get(i).equals(",")) i += 2;
146  
      }
147  
      consume(")");
148  
      return newObject("main$Lisp", (S) list.get(0), subList(list, 1));
149  
    }
150  
    
151  
    Object parseList() {
152  
      consume("[");
153  
      List list = new ArrayList;
154  
      while (!tok.get(i).equals("]")) {
155  
        list.add(parse());
156  
        if (tok.get(i).equals(",")) i += 2;
157  
      }
158  
      consume("]");
159  
      return list;
160  
    }
161  
    
162  
    Object parseArray() {
163  
      consume("array");
164  
      consume("{");
165  
      List list = new ArrayList;
166  
      while (!tok.get(i).equals("}")) {
167  
        list.add(parse());
168  
        if (tok.get(i).equals(",")) i += 2;
169  
      }
170  
      consume("}");
171  
      return list.toArray();
172  
    }
173  
    
174  
    Object parseClass() {
175  
      consume("class");
176  
      consume("(");
177  
      S name = tok.get(i);
178  
      i += 2;
179  
      consume(")");
180  
      Class c = allDynamic ? null : findClass(name);
181  
      if (c != null) ret c;
182  
      new DynamicObject dO;
183  
      dO.className = "java.lang.Class";
184  
      dO.fieldValues.put("name", name);
185  
      ret dO;
186  
    }
187  
    
188  
    Object parseBigInt() {
189  
      consume("bigint");
190  
      consume("(");
191  
      S val = tok.get(i);
192  
      i += 2;
193  
      if (eq(val, "-")) {
194  
        val = "-" + tok.get(i);
195  
        i += 2;
196  
      }
197  
      consume(")");
198  
      ret new BigInteger(val);
199  
    }
200  
    
201  
    Object parseDouble() {
202  
      consume("d");
203  
      consume("(");
204  
      S val = unquote(tok.get(i));
205  
      i += 2;
206  
      consume(")");
207  
      ret Double.parseDouble(val);
208  
    }
209  
    
210  
    Object parseHashMap() {
211  
      consume("hashmap");
212  
      return parseMap(new HashMap);
213  
    }
214  
    
215  
    Object parseHashSet() {
216  
      consume("hashset");
217  
      return parseSet(new HashSet);
218  
    }
219  
    
220  
    Object parseTreeSet() {
221  
      consume("treeset");
222  
      return parseSet(new TreeSet);
223  
    }
224  
    
225  
    Object parseMap() {
226  
      return parseMap(new TreeMap);
227  
    }
228  
    
229  
    Object parseMap(Map map) {
230  
      consume("{");
231  
      while (!tok.get(i).equals("}")) {
232  
        //O key = unstructure(tok.get(i));
233  
        O key = parse();
234  
        consume("=");
235  
        Object value = parse();
236  
        map.put(key, value);
237  
        if (tok.get(i).equals(",")) i += 2;
238  
      }
239  
      consume("}");
240  
      return map;
241  
    }
242  
    
243  
    void consume(String s) {
244  
      if (!tok.get(i).equals(s)) {
245  
        S prevToken = i-2 >= 0 ? tok.get(i-2) : "";
246  
        S nextTokens = join(tok.subList(i, Math.min(i+4, tok.size())));
247  
        fail(quote(s) + " expected: " + prevToken + " " + nextTokens + " (" + i + "/" + tok.size() + ")");
248  
      }
249  
      i += 2;
250  
    }
251  
  }
252  
  
253  
  return new X().parse();
254  
}

Author comment

Began life as a copy of #1001355

download  show line numbers  debug dex  old transpilations   

Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1003021
Snippet name: unstructure with back references
Eternal ID of this version: #1003021/1
Text MD5: 884f1927332db4a091c356c8f6fb8056
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-04-19 17:54:07
Source code size: 6531 bytes / 254 lines
Pitched / IR pitched: No / No
Views / Downloads: 525 / 737
Referenced in: [show references]