X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=json.awk;h=93f6b498c9c277bcaff45551f1d6b3cd599d9102;hb=7c0cb1f9fb1b5684991570e0fcb401a0502c7ee3;hp=2f735c4b44405340cef0ad5c1353849d6d03f01c;hpb=520dcb84adcd9af6b1f3734495650c862bc9f55e;p=~andy%2Frhawk diff --git a/json.awk b/json.awk index 2f735c4..93f6b49 100644 --- a/json.awk +++ b/json.awk @@ -19,7 +19,6 @@ # \t # \u four-hex-digits - # Helpers function json_gettype(value, key, sort, n, i) { @@ -33,6 +32,8 @@ function json_gettype(value, key, sort, n, i) return "object" return "array" } else { + if (value == 0 && value == "") + return "null" if (value == value + 0) return "number" if (value == value "") @@ -71,6 +72,7 @@ function json_write_value(value, pad) case "array": return json_write_array(value, pad) case "number": return json_write_number(value) case "string": return json_write_string(value) + case "null": return "null" default: return "error" } } @@ -112,23 +114,28 @@ function json_write_string(string) # Read functions -function json_tokenize(str, tokens, i, items, table, type, found) +function json_tokenize(str, tokens, i, line, items, table, type, found) { table["term"] = "^[\\[\\]{}:,]" table["str"] = "^\"[^\"]*\"" - table["num"] = "^[0-9]+" + table["num"] = "^[+-]?[0-9]+(.[0-9]+)?" table["var"] = "^(true|false|null)" - table["space"] = "^[ \\t\\n]+" - i = 0 + table["space"] = "^[ \\t]+" + table["line"] = "^\n" + i = 0; + line = 1; while (length(str) > 0) { found = 0 for (type in table) { #print "match: str=["str"] type="type" regex=/"table[type]"/" if (match(str, table[type], items) > 0) { #print " len="RLENGTH" item=["items[0]"]" + if (type == "line") + line++; if (type == "term") type = items[0] - if (type != "space") { + if (type != "space" && type != "line") { + tokens[i]["line"] = line tokens[i]["type"] = type tokens[i]["text"] = items[0] i++ @@ -139,7 +146,7 @@ function json_tokenize(str, tokens, i, items, table, type, found) } } if (!found) { - debug("error tokenizing") + debug("line " line ": error tokenizing") return 0 } } @@ -150,11 +157,12 @@ function json_tokenize(str, tokens, i, items, table, type, found) # tokens[i]["type"], tokens[i]["text"] } -function json_parse_value(tokens, i, value, key, type, text) +function json_parse_value(tokens, i, value, key, line, type, text) { if (!i ) i = 0; if (!depth) depth = 0 depth++ + line = tokens[i]["line"] type = tokens[i]["type"] text = tokens[i]["text"] #printf "parse %d: i=%-2d type=%-3s text=%s\n", depth, i, type, text @@ -164,7 +172,7 @@ function json_parse_value(tokens, i, value, key, type, text) case "str": i = json_parse_string(tokens, i, value, key); break case "num": i = json_parse_number(tokens, i, value, key); break case "var": i = json_parse_var(tokens, i, value, key); break - default: debug("error: type="type" text="text); return 0 + default: debug("line "line": error type="type" text="text); return 0 } depth-- return i @@ -175,18 +183,20 @@ function json_parse_object(tokens, i, value, key, object, k, v) if (tokens[i++]["text"] != "{") return 0; - do { - delete k - delete v - if (!(i=json_parse_value(tokens, i, k, 0))) - return 0 - if (tokens[i++]["text"] != ":") - return 0 - if (!(i=json_parse_value(tokens, i, v, 0))) - return 0 - json_copy(object, k[0], v[0]) - } while (tokens[i++]["text"] == ",") - i-- + if (tokens[i]["text"] != "}") { + do { + delete k + delete v + if (!(i=json_parse_value(tokens, i, k, 0))) + return 0 + if (tokens[i++]["text"] != ":") + return 0 + if (!(i=json_parse_value(tokens, i, v, 0))) + return 0 + json_copy(object, k[0], v[0]) + } while (tokens[i++]["text"] == ",") + i-- + } if (tokens[i++]["text"] != "}") return 0; @@ -197,17 +207,18 @@ function json_parse_object(tokens, i, value, key, object, k, v) function json_parse_array(tokens, i, value, key, array, k, v) { - #print "parse_array: .." if (tokens[i++]["text"] != "[") return 0; - do { - delete v - if (!(i=json_parse_value(tokens, i, v, 0))) - return 0 - json_copy(array, k++, v[0]) - } while (tokens[i++]["text"] == ",") - i-- + if (tokens[i]["text"] != "]") { + do { + delete v + if (!(i=json_parse_value(tokens, i, v, 0))) + return 0 + json_copy(array, k++, v[0]) + } while (tokens[i++]["text"] == ",") + i-- + } if (tokens[i++]["text"] != "]") return 0; @@ -227,16 +238,20 @@ function json_parse_number(tokens, i, value, key, text) function json_parse_string(tokens, i, value, key, text) { text = tokens[i++]["text"] - text = substr(text, 2, length(text)-2) + len = length(text); + text = len == 2 ? "" : substr(text, 2, len-2) json_copy(value, key, text) - #print "parse_string: " text + #print "parse_string: [" text "]" return i } -function json_parse_var(tokens, i, value, key, text) +function json_parse_var(tokens, i, value, key, text, null) { - text = tokens[i++]["text"] - json_copy(value, key, text == "true") + switch (tokens[i++]["text"]) { + case "true": json_copy(value, key, 1==1); break; + case "false": json_copy(value, key, 1==2); break; + case "null": json_copy(value, key, null); break; + } #print "parse_var: " text " -> " text == "true" return i } @@ -256,11 +271,12 @@ function json_load(file, var, line, text, tokens, data, key) return data[0] for (key in data[0]) json_copy(var, key, data[0][key]) + return 1 } function json_save(file, var, cmd, tmp) { - cmd = "mktemp ." file ".XXX" + cmd = "mktemp " file ".XXX" cmd | getline tmp close(cmd) print json_write_value(var) > tmp @@ -298,28 +314,33 @@ function json_test_read() { json_tokenize("[8, \"abc\", 9]", tokens) json_parse_value(tokens, 0, array, 0) - json_print write_value(array[0]) + print json_write_value(array[0]) json_tokenize("{\"abc\": 1, \"def\": 2}", tokens) json_parse_value(tokens, 0, array, 0) - json_print write_value(array[0]) - - json = "{ \"first\": { \"arr\": [ \"zero\", " \ - " \"one\", " \ - " \"two\" ], " \ - " \"number\": 42, " \ - " \"obj\": { \"A\": \"a!\", " \ - " \"B\": \"b!\", " \ - " \"C\": \"c!\" }, " \ - " \"str\": \"hello, world\" }, " \ - " \"second\": { \"arr\": [ \"zero\", " \ - " \"one\", " \ - " \"two\" ], " \ - " \"number\": 42, " \ - " \"obj\": { \"A\": \"a!\", " \ - " \"B\": \"b!\", " \ - " \"C\": \"c!\" }, " \ - " \"str\": \"hello, world\" } }" + print json_write_value(array[0]) + + json = "{ \"first\": { \"arr\": [ \"\", \n" \ + " -1, \n" \ + " 1.2, \n" \ + " true, \n" \ + " false, \n" \ + " null ], \n" \ + " \"number\": 42, \n" \ + " \"eobj\": [ ], \n" \ + " \"earr\": { }, \n" \ + " \"obj\": { \"A\": \"a!\", \n" \ + " \"B\": \"b!\", \n" \ + " \"C\": \"c!\" }, \n" \ + " \"str\": \"hello, world\" }, \n" \ + " \"second\": { \"arr\": [ \"zero\", \n" \ + " \"one\", \n" \ + " \"two\" ], \n" \ + " \"number\": 42, \n" \ + " \"obj\": { \"A\": \"a!\", \n" \ + " \"B\": \"b!\", \n" \ + " \"C\": \"c!\" }, \n" \ + " \"str\": \"hello, world\" } }\n" json_tokenize(json, tokens) json_parse_value(tokens, 0, array, 0)