improve json parsing

This commit is contained in:
TopchetoEU 2024-12-25 02:48:37 +02:00
parent c7c31c3859
commit 05bafc7317
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
2 changed files with 16 additions and 14 deletions

View File

@ -6,6 +6,7 @@ import java.util.stream.Collectors;
import me.topchetoeu.jscript.common.SyntaxException; import me.topchetoeu.jscript.common.SyntaxException;
import me.topchetoeu.jscript.common.parsing.Filename; import me.topchetoeu.jscript.common.parsing.Filename;
import me.topchetoeu.jscript.common.parsing.Location;
import me.topchetoeu.jscript.common.parsing.ParseRes; import me.topchetoeu.jscript.common.parsing.ParseRes;
import me.topchetoeu.jscript.common.parsing.Parsing; import me.topchetoeu.jscript.common.parsing.Parsing;
import me.topchetoeu.jscript.common.parsing.Source; import me.topchetoeu.jscript.common.parsing.Source;
@ -41,7 +42,7 @@ public class JSON {
); );
} }
public static ParseRes<JSONMap> parseMap(Source src, int i) { public static ParseRes<JSONElement> parseMap(Source src, int i) {
var n = Parsing.skipEmpty(src, i); var n = Parsing.skipEmpty(src, i);
if (!src.is(i + n, "{")) return ParseRes.failed(); if (!src.is(i + n, "{")) return ParseRes.failed();
@ -49,7 +50,7 @@ public class JSON {
var values = new JSONMap(); var values = new JSONMap();
if (src.is(i + n, "}")) return ParseRes.res(new JSONMap(new HashMap<>()), n + 1); if (src.is(i + n, "}")) return ParseRes.res(JSONElement.map(new JSONMap(new HashMap<>())), n + 1);
while (true) { while (true) {
var name = parseString(src, i + n); var name = parseString(src, i + n);
if (!name.isSuccess()) return name.chainError(src.loc(i + n), "Expected an index"); if (!name.isSuccess()) return name.chainError(src.loc(i + n), "Expected an index");
@ -72,16 +73,16 @@ public class JSON {
} }
} }
return ParseRes.res(values, n); return ParseRes.res(JSONElement.map(values), n);
} }
public static ParseRes<JSONList> parseList(Source src, int i) { public static ParseRes<JSONElement> parseList(Source src, int i) {
var n = Parsing.skipEmpty(src, i); var n = Parsing.skipEmpty(src, i);
if (!src.is(i + n++, "[]")) return ParseRes.failed(); if (!src.is(i + n++, "[")) return ParseRes.failed();
var values = new JSONList(); var values = new JSONList();
if (src.is(i + n, "]")) return ParseRes.res(new JSONList(), n + 1); if (src.is(i + n, "]")) return ParseRes.res(JSONElement.list(new JSONList()), n + 1);
while (true) { while (true) {
var res = parseValue(src, i + n); var res = parseValue(src, i + n);
if (!res.isSuccess()) return res.chainError(src.loc(i + n), "Expected a list element"); if (!res.isSuccess()) return res.chainError(src.loc(i + n), "Expected a list element");
@ -96,14 +97,14 @@ public class JSON {
} }
} }
return ParseRes.res(values, n); return ParseRes.res(JSONElement.list(values), n);
} }
public static JSONElement parse(Filename filename, String raw) { public static JSONElement parse(Filename filename, String raw) {
if (filename == null) filename = new Filename("jscript", "json"); if (filename == null) filename = new Filename("jscript", "json");
var res = parseValue(new Source(null, filename, raw), 0); var res = parseValue(new Source(null, filename, raw), 0);
if (res.isFailed()) throw new SyntaxException(null, "Invalid JSON given"); if (res.isFailed()) throw new SyntaxException(Location.of(filename, 0, 0), "Invalid JSON given");
else if (res.isError()) throw new SyntaxException(null, res.error); else if (res.isError()) throw new SyntaxException(res.errorLocation, res.error);
else return JSONElement.of(res.result); else return JSONElement.of(res.result);
} }

View File

@ -29,11 +29,12 @@ public class JSONElement {
} }
public static JSONElement of(Object val) { public static JSONElement of(Object val) {
if (val instanceof JSONMap) return map((JSONMap)val); if (val instanceof JSONElement el) return el;
else if (val instanceof JSONList) return list((JSONList)val); else if (val instanceof JSONMap map) return map(map);
else if (val instanceof String) return string((String)val); else if (val instanceof JSONList list) return list(list);
else if (val instanceof Boolean) return bool((Boolean)val); else if (val instanceof String str) return string(str);
else if (val instanceof Number) return number(((Number)val).doubleValue()); else if (val instanceof Boolean bool) return bool(bool);
else if (val instanceof Number num) return number(num.doubleValue());
else if (val == null) return NULL; else if (val == null) return NULL;
else throw new IllegalArgumentException("val must be: String, Boolean, Number, JSONList or JSONMap"); else throw new IllegalArgumentException("val must be: String, Boolean, Number, JSONList or JSONMap");
} }