static class DynamicObject {
S className;
new Map<S, O> fieldValues;
}
static Object unstructure(String text) {
ret unstructure(text, false);
}
static Object unstructure(String text, boolean allDynamic) {
ret unstructure(text, allDynamic, new HashMap<Integer, O>());
}
static Object unstructure(String text, final boolean allDynamic,
final HashMap<Integer, O> seen) {
final L<S> tok = javaTok(text);
final boolean debug = true;
class X {
int i = 1;
Object parse() {
// the non-backreference things
String t = tok.get(i);
if (debug)
print("parse: " + quote(t));
if (t.startsWith("\"")) {
String s = unquote(tok.get(i));
i += 2;
return s;
}
if (t.equals("bigint"))
return parseBigInt();
if (t.equals("d"))
return parseDouble();
if (t.equals("false")) {
i += 2; return false;
}
if (t.equals("true")) {
i += 2; return true;
}
if (t.equals("-")) {
t = tok.get(i+2);
i += 4;
t = dropSuffix("L", t);
long l = -Long.parseLong(t);
ret l == (int) l ? (int) l : l;
}
if (isInteger(t) || isLongConstant(t)) {
i += 2;
t = dropSuffix("L", t);
long l = Long.parseLong(t);
ret l == (int) l ? (int) l : l;
}
if (t.startsWith("r") && isInteger(t.substring(1))) {
i += 2;
int ref = Integer.parseInt(t.substring(1));
O o = seen.get(ref);
if (o == null)
print("Warning: unsatisfied back reference " + ref);
ret o;
}
O o = parse_inner();
seen.put(seen.size()+1, o);
ret o;
}
// everything that can be backreferenced
O parse_inner() {
String t = tok.get(i);
if (debug)
print("parse_inner: " + quote(t));
if (t.equals("hashset"))
return parseHashSet();
if (t.equals("treeset"))
return parseTreeSet();
if (t.equals("hashmap"))
return parseHashMap();
if (t.equals("{"))
return parseMap();
if (t.equals("["))
return parseList();
if (t.equals("array"))
return parseArray();
if (t.equals("class"))
return parseClass();
if (t.equals("l"))
return parseLisp();
if (t.equals("null")) {
i += 2; return null;
}
if (isJavaIdentifier(t)) {
Class c = allDynamic ? null : findClass(t);
DynamicObject dO = null;
O o = null;
if (c != null)
o = nuObject(c);
else {
dO = new DynamicObject;
dO.className = t;
}
i += 2;
if (i < tok.size() && tok.get(i).equals("(")) {
consume("(");
while (!tok.get(i).equals(")")) {
// It's like parsing a map.
//Object key = parse();
//if (tok.get(i).equals(")"))
// key = onlyField();
String key = unquote(tok.get(i));
i += 2;
consume("=");
Object value = parse();
if (o != null)
setOpt(o, key, value);
else
dO.fieldValues.put(key, value);
if (tok.get(i).equals(",")) i += 2;
}
consume(")");
}
return o != null ? o : dO;
}
throw new RuntimeException("Unknown token " + (i+1) + ": " + t);
}
Object parseSet(Set set) {
set.addAll((L) parseList());
return set;
}
Object parseLisp() {
consume("l");
consume("(");
List list = new ArrayList;
while (!tok.get(i).equals(")")) {
list.add(parse());
if (tok.get(i).equals(",")) i += 2;
}
consume(")");
return newObject("main$Lisp", (S) list.get(0), subList(list, 1));
}
Object parseList() {
consume("[");
List list = new ArrayList;
while (!tok.get(i).equals("]")) {
list.add(parse());
if (tok.get(i).equals(",")) i += 2;
}
consume("]");
return list;
}
Object parseArray() {
consume("array");
consume("{");
List list = new ArrayList;
while (!tok.get(i).equals("}")) {
list.add(parse());
if (tok.get(i).equals(",")) i += 2;
}
consume("}");
return list.toArray();
}
Object parseClass() {
consume("class");
consume("(");
S name = tok.get(i);
i += 2;
consume(")");
Class c = allDynamic ? null : findClass(name);
if (c != null) ret c;
new DynamicObject dO;
dO.className = "java.lang.Class";
dO.fieldValues.put("name", name);
ret dO;
}
Object parseBigInt() {
consume("bigint");
consume("(");
S val = tok.get(i);
i += 2;
if (eq(val, "-")) {
val = "-" + tok.get(i);
i += 2;
}
consume(")");
ret new BigInteger(val);
}
Object parseDouble() {
consume("d");
consume("(");
S val = unquote(tok.get(i));
i += 2;
consume(")");
ret Double.parseDouble(val);
}
Object parseHashMap() {
consume("hashmap");
return parseMap(new HashMap);
}
Object parseHashSet() {
consume("hashset");
return parseSet(new HashSet);
}
Object parseTreeSet() {
consume("treeset");
return parseSet(new TreeSet);
}
Object parseMap() {
return parseMap(new TreeMap);
}
Object parseMap(Map map) {
consume("{");
while (!tok.get(i).equals("}")) {
//O key = unstructure(tok.get(i));
O key = parse();
consume("=");
Object value = parse();
map.put(key, value);
if (tok.get(i).equals(",")) i += 2;
}
consume("}");
return map;
}
void consume(String s) {
if (!tok.get(i).equals(s)) {
S prevToken = i-2 >= 0 ? tok.get(i-2) : "";
S nextTokens = join(tok.subList(i, Math.min(i+4, tok.size())));
fail(quote(s) + " expected: " + prevToken + " " + nextTokens + " (" + i + "/" + tok.size() + ")");
}
i += 2;
}
}
return new X().parse();
}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: | 1033 / 1223 |
| Referenced in: | #1003020 - Test Opposites Bot Load Bug #1003039 - unstructure with new new back references and fixed int/long (v4, outdated) #3000382 - Answer for ferdie (>> t = 1, f = 0) #3000383 - Answer for funkoverflow (>> t=1, f=0 okay) |