Skip to main content
1 of 2
yankee
  • 498
  • 3
  • 5
  • 11

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 />'+'&nbsp;'.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(/&/,'&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');

  }



  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&ouml;n verschachtelt..."},"tippt einfach json-zeugs in dem grossen Feld.","Die Anzeige aktualisiert sich sofort...","Die Formatierungen sind als &lt;style&gt; gespeichert. Ihr k&ouml;nnt sie so beliebig &auml;ndern.",{"Zahlen":1,"sind":[1,4,55.67],"auch":"sch&ouml;n"}]</textarea>

<div id="ausgabe"></div>

</body>

</html>
yankee
  • 498
  • 3
  • 5
  • 11