I'd write it as a recursive descent parser since this is quite simple:
http://en.wikipedia.org/wiki/Recursive_descent_parser
Actually I already did this a couple of years back, when I wanted to create something that simply formats and highlights JSON a bit. If you can understand it, then you can modify it to your needs:
<html>
<head>
<style type="text/css">
.str
{
color: green;
}
.obj
{
font-weight: bold;
}
.num
{
color: red;
}
</style>
<script language="javascript" type="text/javascript">
String.prototype.repeat = function(n) {
result = '';
for (var i = 0; i < n; i++) result += this;
return result;
}
function jsonFormater() {
this.reset = function() {
this.txt = '';
this.pos = 0;
this.result = '';
this.indent = 0;
this.classes = Array();
};
this.undoindent = function() {
this.indent -= 4;
this.nline();
};
this.doindent = function() {
this.indent += 4;
this.nline();
};
this.nline = function() {
this.result += '<br />' + ' '.repeat(this.indent);
};
this.chClass = function(neu) {
if (this.classes.length > 0) this.result += '</span>';
this.result += '<span class="' + neu + '">';
this.classes.push(neu);
};
this.endClass = function() {
this.classes.pop();
this.result += '</span>';
if (this.classes.length > 0) this.result += '<span class="' + this.classes[this.classes.length - 1] + '">';
};
this.formatJson = function(txt) {
this.txt = txt;
this.pos = 0;
this.result = '';
while (this.pos < this.txt.length) {
if (this.txt[this.pos] == '{') this.parseObj();
else if (this.txt[this.pos] =='[') this.parseArray();
this.pos++;
}
return this.result;
}
this.parseObj = function(ende) {
if (typeof ende =='undefined') var ende = '}';
this.chClass('obj');
do {
if ((this.txt[this.pos] == '{') || (this.txt[this.pos] == '[')) this.nline();
this.result += this.txt[this.pos];
if (this.txt[this.pos] == ',') this.nline();
if ((this.txt[this.pos] == '{') || (this.txt[this.pos] == '[')) this.doindent();
this.pos++;
if (this.txt[this.pos] == '{') this.parseObj();
if (this.txt[this.pos] == '[') this.parseArray();
if (this.txt[this.pos] == '"') this.parseString();
if (/\d/.test(this.txt[this.pos])) this.parseNum();
if ((this.txt[this.pos] == '}') || (this.txt[this.pos] == ']')) this.undoindent();
} while ((this.pos < this.txt.length) && (this.txt[this.pos] != ende));
this.result += this.txt[this.pos];
this.pos++;
this.endClass();
};
this.parseArray = function() {
this.parseObj(']');
};
this.parseString = function() {
this.chClass('str');
do {
this.result += this.htmlEscape(this.txt[this.pos]);
this.pos++;
} while ((this.pos < this.txt.length) && ((this.txt[this.pos] != '"') || (this.txt[this.pos - 1] == '\\')));
this.result += this.htmlEscape(this.txt[this.pos]);
this.pos++;
this.endClass();
};
this.parseNum = function() {
this.chClass('num');
do {
this.result += this.txt[this.pos];
this.pos++;
} while ((this.pos < this.txt.length) && (/[\d\.]/.test(this.txt[this.pos])));
this.endClass();
};
this.htmlEscape = function(txt) {
return txt.replace(/&/,'&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
};
this.reset();
}
var parser = new jsonFormater();
function go(txt) {
document.getElementById('ausgabe').innerHTML = parser.formatJson(txt);
parser.reset();
}
</script>
</head>
<body onLoad="go(document.getElementById('thetextarea').value);">
<textarea id="thetextarea" rows="25" cols="70" onKeyUp="go(this.value);">[{"Dies":"Ist ein Beispiel...","mit":["Arrays","und","so"]},{"alles":"schön verschachtelt..."},"tippt einfach json-zeugs in dem grossen Feld.","Die Anzeige aktualisiert sich sofort...","Die Formatierungen sind als <style> gespeichert. Ihr könnt sie so beliebig ändern.",{"Zahlen":1,"sind":[1,4,55.67],"auch":"schön"}]</textarea>
<div id="ausgabe"></div>
</body>
</html>