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: | 584 / 799 |
Referenced in: | [show references] |