Skip to content

Instantly share code, notes, and snippets.

@lexich
Created November 7, 2012 12:23
Show Gist options
  • Save lexich/4031246 to your computer and use it in GitHub Desktop.
Save lexich/4031246 to your computer and use it in GitHub Desktop.
Own realization SAX parser of JSON
// Generated by CoffeeScript 1.4.0
(function() {
var DATA, JSON2, res;
JSON2 = {
OBJECT: "Object",
ARRAY: "Array",
nextToken: function(buf, i) {
var ch, isFloat, isNum, isWord, str, token;
token = void 0;
isWord = false;
isNum = false;
isFloat = false;
str = "";
while (i < buf.length) {
ch = buf.charCodeAt(i);
++i;
switch (ch) {
case 123:
case 125:
case 58:
case 91:
case 93:
case 44:
return [String.fromCharCode(ch), str, i];
case 34:
isWord = !isWord;
if (!isWord) {
return ["w", str, i];
}
break;
default:
if (ch === 46 && isNum) {
if (!isFloat) {
isFloat = true;
} else {
throw new Error("more then one char '.' in number token");
}
}
if (!isWord && ch >= 48 && ch <= 57) {
isNum = true;
}
if (isWord || isNum) {
str += String.fromCharCode(ch);
}
if (isNum && i + 1 < buf.length) {
ch = buf.charCodeAt(i + 1);
if ((ch < 48 || ch > 57) && ch !== 46) {
if (!isFloat) {
return ['i', parseInt(str), i];
} else {
return ["f", parseFloat(str), i];
}
}
}
}
}
return ["", "", i];
},
processValue: function(obj, key, value, type) {
if (type === this.OBJECT) {
if ((key != null) && (value != null) && (obj != null)) {
obj[key] = value;
} else {
throw new Error("Invalid params for [" + type + "]: key:'" + key + "' value:'" + value + "' obj:'" + obj + "'");
}
} else if (type === this.ARRAY) {
if ((value != null) && (obj != null)) {
obj.push(value);
} else {
throw new Error("Invalid params for [" + type + "]: value:'" + value + "' obj:'" + obj + "'");
}
} else {
throw new Error("Unknown type");
}
key = null;
value = null;
return [obj, key, value, type];
},
_parse: function(buf, obj, i, type) {
var key, token, v, value, _ref, _ref1, _ref2, _ref3, _ref4;
key = null;
value = null;
try {
while (i < buf.length) {
_ref = this.nextToken(buf, i), token = _ref[0], v = _ref[1], i = _ref[2];
switch (token) {
case "{":
_ref1 = this._parse(buf, {}, i, this.OBJECT), i = _ref1[0], value = _ref1[1];
break;
case "[":
_ref2 = this._parse(buf, [], i, this.ARRAY), i = _ref2[0], value = _ref2[1];
break;
case "}":
case "]":
_ref3 = this.processValue(obj, key, value, type), obj = _ref3[0], key = _ref3[1], value = _ref3[2], type = _ref3[3];
return [i, obj];
case ",":
_ref4 = this.processValue(obj, key, value, type), obj = _ref4[0], key = _ref4[1], value = _ref4[2], type = _ref4[3];
break;
case ":":
key = value;
value = null;
break;
case "w":
case "i":
case "f":
value = v;
}
}
} catch (e) {
e.buf = buf;
e.i = i;
throw e;
}
return [i, value];
},
parse: function(buf) {
try {
return this._parse(buf, {}, 0, this.OBJECT)[1];
} catch (e) {
throw new Error("msg:" + e.message + " text:" + (e.buf.slice(0, e.i).to));
}
}
};
DATA = "{\n \"one\":[0,\"1\",0,\"3\",\"4\",\"9\"],\n \"two\":\"three\",\n \"four\":{\n 1:\"one\",\n \"five\":1.0,\n \"six\":3\n }\n}";
res = JSON2.parse(DATA.toString());
if (res.one.length === 6) {
console.log("PASS");
} else {
console.error("FAIL");
}
if (res.one[0] === 0) {
console.log("PASS");
} else {
console.error("FAIL");
}
if (res.one[1] === "1") {
console.log("PASS");
} else {
console.error("FAIL");
}
if (res.two === "three") {
console.log("PASS");
} else {
console.error("FAIL");
}
if (res.four["1"] === "one") {
console.log("PASS");
} else {
console.error("FAIL");
}
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment