JSON parser

psuedo code for simple json parser creating a tree-like value.
usage: a root value is created by code, then a file parsed into it.


Value  (Node is also rather vague)

 

  • double number
  • utf8s text
  • vector<Value*> array
  • map<utf8s*,Value*> object
  • type {
    • dontKnowYet
    • number
    • text
    • array
    • object
    • ?null
    • ?errored
      }

parseFile(filename){

  1. open filestream for binary input (line ending might not be same
    as locale)
  2. wrap stream with diagnoser stream
  3. parseValue(stream)  return should be ‘}’ else we have
    perhaps corrupted some of this Value. 
  4. close stream

}

parseValue(istream){ on success returns first non-blank char that
followed value’s image

  1. getNextNotBlank
  2. { do {  //could make this
    into a parseObject() 

    make key=new utf8s
    follower = parseText(key,stream)
    if follower is not ‘:’ error
    make value=new Value
    follower =value.parseValue(istream)
    if follower is not comma or end-curly error
    object.insert(key,value)

    } while(isComma);

    if follower is erroneous
    then 

    delete key
    and value
    [ do {   //could make
    this into a parseArray() 

    make value= new Value
    follower=newone.parseValue() 

    if follower is legit

    append newone t ‘array’
    else error

    } while(follower isComma);
    if follower is ‘]’ then return

    else delete array’s contents

    on error in do loop 

    delete the value
    mark error on this value

     

    parseText(&text,istream) 

    if follower is legit return it

    on error from parseText set
    text to an error message.
    digit parseNumber(&number,istream)
    if follower is legit return it
    on error from parseNumber
    set text to an error message.
    else  parseKeyword() simple minded compare a char
    at a time for the three keywords
    i.e. since we are doing a switch add cases for the initial chars of the
    keywords and in each case match the rest of the letters (could share
    code by iterating over const strings …
  3. above on success have parsed directly into the data members of
    the value and returned so if we get here we do common parts of error
    handling and return a 0.

}

parseText(text,stream){on success returns first non-blank char that
followed value’s image

while(stream has more){
getNextNotBlank
return that
\ switch on next 

processing various escape
sequences each case of which

appends decoded char to text

isMBC append it to text
for(more=# of followers;more–>0;) 

append next to text;
}
return error code (a 0 will do nicely).

}

parseNumber(…) like parseText in the ins and outs, but a bit messier
in the internals.
copy numberparser and recode to use istream


class DiagnosticTextStream public
istream

 

  • line count
  • char count
  • istream &wrapped
  • overload/implement get()
    • wrapped.get
    • possibly handle cr lf vs lf
      vs cr here.
    • if newline then ++line count and clear char count
    • ++char count
    • return char
  • simple punt on other members as they are used
    • ‘hasmore'()
    • close()
  • print(ostream) for diganostic messages
    • print line then char count.

Could also make a Sequencer<u8> which wraps an istream so that we
can use hasNext()/next() syntax which we can quickly mate to existing
number parser.


parseKeyword(const char
*keyword,stream){

 

while(stream has next){
c=++keyword;//pass in the full keyword text for
mental convenience
if(c==0){
getnext
if is white then return
getNextNotBlank
else return 0 as error indicator 

}
}
return 0 as error indicator

}


Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s