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 | // actually it's now almost the same as jsonDecode :) |
11 | static Object unstructure(String text, final boolean allDynamic) { |
12 | final L<S> tok = javaTok(text); |
13 | |
14 | class X { |
15 | int i = 1; |
16 | |
17 | Object parse() { |
18 | String t = tok.get(i); |
19 | if (t.startsWith("\"")) { |
20 | String s = unquote(tok.get(i)); |
21 | i += 2; |
22 | return s; |
23 | } |
24 | if (t.equals("hashset")) |
25 | return parseHashSet(); |
26 | if (t.equals("treeset")) |
27 | return parseTreeSet(); |
28 | if (t.equals("hashmap")) |
29 | return parseHashMap(); |
30 | if (t.equals("{")) |
31 | return parseMap(); |
32 | if (t.equals("[")) |
33 | return parseList(); |
34 | if (t.equals("array")) |
35 | return parseArray(); |
36 | if (t.equals("class")) |
37 | return parseClass(); |
38 | if (t.equals("bigint")) |
39 | return parseBigInt(); |
40 | if (t.equals("d")) |
41 | return parseDouble(); |
42 | if (t.equals("l")) |
43 | return parseLisp(); |
44 | if (t.equals("null")) { |
45 | i += 2; return null; |
46 | } |
47 | if (t.equals("false")) { |
48 | i += 2; return false; |
49 | } |
50 | if (t.equals("true")) { |
51 | i += 2; return true; |
52 | } |
53 | if (t.equals("-")) { |
54 | t = tok.get(i+2); |
55 | i += 4; |
56 | t = dropSuffix("L", t); |
57 | long l = -Long.parseLong(t); |
58 | ret l == (int) l ? (int) l : l; |
59 | } |
60 | if (isInteger(t) || isLongConstant(t)) { |
61 | i += 2; |
62 | t = dropSuffix("L", t); |
63 | long l = Long.parseLong(t); |
64 | ret l == (int) l ? (int) l : l; |
65 | } |
66 | if (isJavaIdentifier(t)) { |
67 | Class c = allDynamic ? null : findClass(t); |
68 | DynamicObject dO = null; |
69 | O o = null; |
70 | if (c != null) |
71 | o = nuObject(c); |
72 | else { |
73 | dO = new DynamicObject; |
74 | dO.className = t; |
75 | } |
76 | i += 2; |
77 | if (i < tok.size() && tok.get(i).equals("(")) { |
78 | consume("("); |
79 | while (!tok.get(i).equals(")")) { |
80 | // It's like parsing a map. |
81 | //Object key = parse(); |
82 | //if (tok.get(i).equals(")")) |
83 | // key = onlyField(); |
84 | String key = unquote(tok.get(i)); |
85 | i += 2; |
86 | consume("="); |
87 | Object value = parse(); |
88 | if (o != null) |
89 | setOpt(o, key, value); |
90 | else |
91 | dO.fieldValues.put(key, value); |
92 | if (tok.get(i).equals(",")) i += 2; |
93 | } |
94 | consume(")"); |
95 | } |
96 | return o != null ? o : dO; |
97 | } |
98 | throw new RuntimeException("Unknown token " + (i+1) + ": " + t); |
99 | } |
100 | |
101 | Object parseSet(Set set) { |
102 | set.addAll((L) parseList()); |
103 | return set; |
104 | } |
105 | |
106 | Object parseLisp() { |
107 | consume("l"); |
108 | consume("("); |
109 | List list = new ArrayList; |
110 | while (!tok.get(i).equals(")")) { |
111 | list.add(parse()); |
112 | if (tok.get(i).equals(",")) i += 2; |
113 | } |
114 | consume(")"); |
115 | return newObject("main$Lisp", (S) list.get(0), subList(list, 1)); |
116 | } |
117 | |
118 | Object parseList() { |
119 | consume("["); |
120 | List list = new ArrayList; |
121 | while (!tok.get(i).equals("]")) { |
122 | list.add(parse()); |
123 | if (tok.get(i).equals(",")) i += 2; |
124 | } |
125 | consume("]"); |
126 | return list; |
127 | } |
128 | |
129 | Object parseArray() { |
130 | consume("array"); |
131 | consume("{"); |
132 | List list = new ArrayList; |
133 | while (!tok.get(i).equals("}")) { |
134 | list.add(parse()); |
135 | if (tok.get(i).equals(",")) i += 2; |
136 | } |
137 | consume("}"); |
138 | return list.toArray(); |
139 | } |
140 | |
141 | Object parseClass() { |
142 | consume("class"); |
143 | consume("("); |
144 | S name = tok.get(i); |
145 | i += 2; |
146 | consume(")"); |
147 | Class c = allDynamic ? null : findClass(name); |
148 | if (c != null) ret c; |
149 | new DynamicObject dO; |
150 | dO.className = "java.lang.Class"; |
151 | dO.fieldValues.put("name", name); |
152 | ret dO; |
153 | } |
154 | |
155 | Object parseBigInt() { |
156 | consume("bigint"); |
157 | consume("("); |
158 | S val = tok.get(i); |
159 | i += 2; |
160 | if (eq(val, "-")) { |
161 | val = "-" + tok.get(i); |
162 | i += 2; |
163 | } |
164 | consume(")"); |
165 | ret new BigInteger(val); |
166 | } |
167 | |
168 | Object parseDouble() { |
169 | consume("d"); |
170 | consume("("); |
171 | S val = unquote(tok.get(i)); |
172 | i += 2; |
173 | consume(")"); |
174 | ret Double.parseDouble(val); |
175 | } |
176 | |
177 | Object parseHashMap() { |
178 | consume("hashmap"); |
179 | return parseMap(new HashMap); |
180 | } |
181 | |
182 | Object parseHashSet() { |
183 | consume("hashset"); |
184 | return parseSet(new HashSet); |
185 | } |
186 | |
187 | Object parseTreeSet() { |
188 | consume("treeset"); |
189 | return parseSet(new TreeSet); |
190 | } |
191 | |
192 | Object parseMap() { |
193 | return parseMap(new TreeMap); |
194 | } |
195 | |
196 | Object parseMap(Map map) { |
197 | consume("{"); |
198 | while (!tok.get(i).equals("}")) { |
199 | O key = unstructure(tok.get(i)); |
200 | i += 2; |
201 | consume("="); |
202 | Object value = parse(); |
203 | map.put(key, value); |
204 | if (tok.get(i).equals(",")) i += 2; |
205 | } |
206 | consume("}"); |
207 | return map; |
208 | } |
209 | |
210 | void consume(String s) { |
211 | if (!tok.get(i).equals(s)) { |
212 | S prevToken = i-2 >= 0 ? tok.get(i-2) : ""; |
213 | S nextTokens = join(tok.subList(i, Math.min(i+4, tok.size()))); |
214 | fail(quote(s) + " expected: " + prevToken + " " + nextTokens + " (" + i + "/" + tok.size() + ")"); |
215 | } |
216 | i += 2; |
217 | } |
218 | } |
219 | |
220 | return new X().parse(); |
221 | } |
Began life as a copy of #1001061 now uses setOpt...
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: | #1001355 |
Snippet name: | unstructure (opposite of "structure") - restores data structures from a string (old) |
Eternal ID of this version: | #1001355/1 |
Text MD5: | 0864a35d78dc7feba9482337302dbd17 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-11-28 23:39:58 |
Source code size: | 5697 bytes / 221 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 686 / 3666 |
Referenced in: | [show references] |