json-simple/trunk/src/main/java/org/json/simple/parser/JSONParser.java

Code
Comments
Other
Rev Date Author Line
50 26 Feb 19 nicklas 1 /*
50 26 Feb 19 nicklas 2  * $Id: JSONParser.java,v 1.1 2006/04/15 14:10:48 platform Exp $
50 26 Feb 19 nicklas 3  * Created on 2006-4-15
50 26 Feb 19 nicklas 4  */
50 26 Feb 19 nicklas 5 package org.json.simple.parser;
50 26 Feb 19 nicklas 6
50 26 Feb 19 nicklas 7 import java.io.IOException;
50 26 Feb 19 nicklas 8 import java.io.Reader;
50 26 Feb 19 nicklas 9 import java.io.StringReader;
50 26 Feb 19 nicklas 10 import java.util.LinkedList;
50 26 Feb 19 nicklas 11 import java.util.List;
50 26 Feb 19 nicklas 12 import java.util.Map;
50 26 Feb 19 nicklas 13
50 26 Feb 19 nicklas 14 import org.json.simple.JSONArray;
50 26 Feb 19 nicklas 15 import org.json.simple.JSONObject;
50 26 Feb 19 nicklas 16
50 26 Feb 19 nicklas 17
50 26 Feb 19 nicklas 18 /**
50 26 Feb 19 nicklas 19  * Parser for JSON text. Please note that JSONParser is NOT thread-safe.
50 26 Feb 19 nicklas 20  * 
50 26 Feb 19 nicklas 21  * @author FangYidong<fangyidong@yahoo.com.cn>
50 26 Feb 19 nicklas 22  */
50 26 Feb 19 nicklas 23 public class JSONParser {
50 26 Feb 19 nicklas 24   public static final int S_INIT=0;
50 26 Feb 19 nicklas 25   public static final int S_IN_FINISHED_VALUE=1;//string,number,boolean,null,object,array
50 26 Feb 19 nicklas 26   public static final int S_IN_OBJECT=2;
50 26 Feb 19 nicklas 27   public static final int S_IN_ARRAY=3;
50 26 Feb 19 nicklas 28   public static final int S_PASSED_PAIR_KEY=4;
50 26 Feb 19 nicklas 29   public static final int S_IN_PAIR_VALUE=5;
50 26 Feb 19 nicklas 30   public static final int S_END=6;
50 26 Feb 19 nicklas 31   public static final int S_IN_ERROR=-1;
50 26 Feb 19 nicklas 32   
57 26 Feb 19 nicklas 33   private LinkedList<Integer> handlerStatusStack;
50 26 Feb 19 nicklas 34   private Yylex lexer = new Yylex((Reader)null);
50 26 Feb 19 nicklas 35   private Yytoken token = null;
50 26 Feb 19 nicklas 36   private int status = S_INIT;
50 26 Feb 19 nicklas 37   
57 26 Feb 19 nicklas 38   private int peekStatus(LinkedList<Integer> statusStack){
50 26 Feb 19 nicklas 39     if(statusStack.size()==0)
50 26 Feb 19 nicklas 40       return -1;
50 26 Feb 19 nicklas 41     Integer status=(Integer)statusStack.getFirst();
50 26 Feb 19 nicklas 42     return status.intValue();
50 26 Feb 19 nicklas 43   }
50 26 Feb 19 nicklas 44   
50 26 Feb 19 nicklas 45     /**
50 26 Feb 19 nicklas 46      *  Reset the parser to the initial state without resetting the underlying reader.
50 26 Feb 19 nicklas 47      *
50 26 Feb 19 nicklas 48      */
50 26 Feb 19 nicklas 49     public void reset(){
50 26 Feb 19 nicklas 50         token = null;
50 26 Feb 19 nicklas 51         status = S_INIT;
50 26 Feb 19 nicklas 52         handlerStatusStack = null;
50 26 Feb 19 nicklas 53     }
50 26 Feb 19 nicklas 54     
50 26 Feb 19 nicklas 55     /**
50 26 Feb 19 nicklas 56      * Reset the parser to the initial state with a new character reader.
50 26 Feb 19 nicklas 57      * 
50 26 Feb 19 nicklas 58      * @param in - The new character reader.
50 26 Feb 19 nicklas 59      * @throws IOException
50 26 Feb 19 nicklas 60      * @throws ParseException
50 26 Feb 19 nicklas 61      */
50 26 Feb 19 nicklas 62   public void reset(Reader in){
50 26 Feb 19 nicklas 63     lexer.yyreset(in);
50 26 Feb 19 nicklas 64     reset();
50 26 Feb 19 nicklas 65   }
50 26 Feb 19 nicklas 66   
50 26 Feb 19 nicklas 67   /**
50 26 Feb 19 nicklas 68    * @return The position of the beginning of the current token.
50 26 Feb 19 nicklas 69    */
50 26 Feb 19 nicklas 70   public int getPosition(){
50 26 Feb 19 nicklas 71     return lexer.getPosition();
50 26 Feb 19 nicklas 72   }
50 26 Feb 19 nicklas 73   
50 26 Feb 19 nicklas 74   public Object parse(String s) throws ParseException{
50 26 Feb 19 nicklas 75     return parse(s, (ContainerFactory)null);
50 26 Feb 19 nicklas 76   }
50 26 Feb 19 nicklas 77   
50 26 Feb 19 nicklas 78   public Object parse(String s, ContainerFactory containerFactory) throws ParseException{
50 26 Feb 19 nicklas 79     StringReader in=new StringReader(s);
50 26 Feb 19 nicklas 80     try{
50 26 Feb 19 nicklas 81       return parse(in, containerFactory);
50 26 Feb 19 nicklas 82     }
50 26 Feb 19 nicklas 83     catch(IOException ie){
50 26 Feb 19 nicklas 84       /*
50 26 Feb 19 nicklas 85        * Actually it will never happen.
50 26 Feb 19 nicklas 86        */
50 26 Feb 19 nicklas 87       throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
50 26 Feb 19 nicklas 88     }
50 26 Feb 19 nicklas 89   }
50 26 Feb 19 nicklas 90   
50 26 Feb 19 nicklas 91   public Object parse(Reader in) throws IOException, ParseException{
50 26 Feb 19 nicklas 92     return parse(in, (ContainerFactory)null);
50 26 Feb 19 nicklas 93   }
50 26 Feb 19 nicklas 94   
50 26 Feb 19 nicklas 95   /**
50 26 Feb 19 nicklas 96    * Parse JSON text into java object from the input source.
50 26 Feb 19 nicklas 97    *   
50 26 Feb 19 nicklas 98    * @param in
50 26 Feb 19 nicklas 99      * @param containerFactory - Use this factory to createyour own JSON object and JSON array containers.
50 26 Feb 19 nicklas 100    * @return Instance of the following:
50 26 Feb 19 nicklas 101    *  org.json.simple.JSONObject,
50 26 Feb 19 nicklas 102    *   org.json.simple.JSONArray,
50 26 Feb 19 nicklas 103    *   java.lang.String,
50 26 Feb 19 nicklas 104    *   java.lang.Number,
50 26 Feb 19 nicklas 105    *   java.lang.Boolean,
50 26 Feb 19 nicklas 106    *   null
50 26 Feb 19 nicklas 107    * 
50 26 Feb 19 nicklas 108    * @throws IOException
50 26 Feb 19 nicklas 109    * @throws ParseException
50 26 Feb 19 nicklas 110    */
57 26 Feb 19 nicklas 111   @SuppressWarnings({ "unchecked", "rawtypes" })
50 26 Feb 19 nicklas 112   public Object parse(Reader in, ContainerFactory containerFactory) throws IOException, ParseException{
50 26 Feb 19 nicklas 113     reset(in);
57 26 Feb 19 nicklas 114     LinkedList<Integer> statusStack = new LinkedList<>();
57 26 Feb 19 nicklas 115     LinkedList<Object> valueStack = new LinkedList<>();
50 26 Feb 19 nicklas 116     
50 26 Feb 19 nicklas 117     try{
50 26 Feb 19 nicklas 118       do{
50 26 Feb 19 nicklas 119         nextToken();
50 26 Feb 19 nicklas 120         switch(status){
50 26 Feb 19 nicklas 121         case S_INIT:
50 26 Feb 19 nicklas 122           switch(token.type){
50 26 Feb 19 nicklas 123           case Yytoken.TYPE_VALUE:
50 26 Feb 19 nicklas 124             status=S_IN_FINISHED_VALUE;
50 26 Feb 19 nicklas 125             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 126             valueStack.addFirst(token.value);
50 26 Feb 19 nicklas 127             break;
50 26 Feb 19 nicklas 128           case Yytoken.TYPE_LEFT_BRACE:
50 26 Feb 19 nicklas 129             status=S_IN_OBJECT;
50 26 Feb 19 nicklas 130             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 131             valueStack.addFirst(createObjectContainer(containerFactory));
50 26 Feb 19 nicklas 132             break;
50 26 Feb 19 nicklas 133           case Yytoken.TYPE_LEFT_SQUARE:
50 26 Feb 19 nicklas 134             status=S_IN_ARRAY;
50 26 Feb 19 nicklas 135             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 136             valueStack.addFirst(createArrayContainer(containerFactory));
50 26 Feb 19 nicklas 137             break;
50 26 Feb 19 nicklas 138           default:
50 26 Feb 19 nicklas 139             status=S_IN_ERROR;
50 26 Feb 19 nicklas 140           }//inner switch
50 26 Feb 19 nicklas 141           break;
50 26 Feb 19 nicklas 142           
50 26 Feb 19 nicklas 143         case S_IN_FINISHED_VALUE:
50 26 Feb 19 nicklas 144           if(token.type==Yytoken.TYPE_EOF)
50 26 Feb 19 nicklas 145             return valueStack.removeFirst();
50 26 Feb 19 nicklas 146           else
50 26 Feb 19 nicklas 147             throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
50 26 Feb 19 nicklas 148           
50 26 Feb 19 nicklas 149         case S_IN_OBJECT:
50 26 Feb 19 nicklas 150           switch(token.type){
50 26 Feb 19 nicklas 151           case Yytoken.TYPE_COMMA:
50 26 Feb 19 nicklas 152             break;
50 26 Feb 19 nicklas 153           case Yytoken.TYPE_VALUE:
50 26 Feb 19 nicklas 154             if(token.value instanceof String){
50 26 Feb 19 nicklas 155               String key=(String)token.value;
50 26 Feb 19 nicklas 156               valueStack.addFirst(key);
50 26 Feb 19 nicklas 157               status=S_PASSED_PAIR_KEY;
50 26 Feb 19 nicklas 158               statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 159             }
50 26 Feb 19 nicklas 160             else{
50 26 Feb 19 nicklas 161               status=S_IN_ERROR;
50 26 Feb 19 nicklas 162             }
50 26 Feb 19 nicklas 163             break;
50 26 Feb 19 nicklas 164           case Yytoken.TYPE_RIGHT_BRACE:
50 26 Feb 19 nicklas 165             if(valueStack.size()>1){
50 26 Feb 19 nicklas 166               statusStack.removeFirst();
50 26 Feb 19 nicklas 167               valueStack.removeFirst();
50 26 Feb 19 nicklas 168               status=peekStatus(statusStack);
50 26 Feb 19 nicklas 169             }
50 26 Feb 19 nicklas 170             else{
50 26 Feb 19 nicklas 171               status=S_IN_FINISHED_VALUE;
50 26 Feb 19 nicklas 172             }
50 26 Feb 19 nicklas 173             break;
50 26 Feb 19 nicklas 174           default:
50 26 Feb 19 nicklas 175             status=S_IN_ERROR;
50 26 Feb 19 nicklas 176             break;
50 26 Feb 19 nicklas 177           }//inner switch
50 26 Feb 19 nicklas 178           break;
50 26 Feb 19 nicklas 179           
50 26 Feb 19 nicklas 180         case S_PASSED_PAIR_KEY:
50 26 Feb 19 nicklas 181           switch(token.type){
50 26 Feb 19 nicklas 182           case Yytoken.TYPE_COLON:
50 26 Feb 19 nicklas 183             break;
50 26 Feb 19 nicklas 184           case Yytoken.TYPE_VALUE:
50 26 Feb 19 nicklas 185             statusStack.removeFirst();
50 26 Feb 19 nicklas 186             String key=(String)valueStack.removeFirst();
57 26 Feb 19 nicklas 187             Map<String, Object> parent=(Map)valueStack.getFirst();
50 26 Feb 19 nicklas 188             parent.put(key,token.value);
50 26 Feb 19 nicklas 189             status=peekStatus(statusStack);
50 26 Feb 19 nicklas 190             break;
50 26 Feb 19 nicklas 191           case Yytoken.TYPE_LEFT_SQUARE:
50 26 Feb 19 nicklas 192             statusStack.removeFirst();
50 26 Feb 19 nicklas 193             key=(String)valueStack.removeFirst();
50 26 Feb 19 nicklas 194             parent=(Map)valueStack.getFirst();
57 26 Feb 19 nicklas 195             List<Object> newArray=createArrayContainer(containerFactory);
50 26 Feb 19 nicklas 196             parent.put(key,newArray);
50 26 Feb 19 nicklas 197             status=S_IN_ARRAY;
50 26 Feb 19 nicklas 198             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 199             valueStack.addFirst(newArray);
50 26 Feb 19 nicklas 200             break;
50 26 Feb 19 nicklas 201           case Yytoken.TYPE_LEFT_BRACE:
50 26 Feb 19 nicklas 202             statusStack.removeFirst();
50 26 Feb 19 nicklas 203             key=(String)valueStack.removeFirst();
50 26 Feb 19 nicklas 204             parent=(Map)valueStack.getFirst();
57 26 Feb 19 nicklas 205             Map<String, Object> newObject=createObjectContainer(containerFactory);
50 26 Feb 19 nicklas 206             parent.put(key,newObject);
50 26 Feb 19 nicklas 207             status=S_IN_OBJECT;
50 26 Feb 19 nicklas 208             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 209             valueStack.addFirst(newObject);
50 26 Feb 19 nicklas 210             break;
50 26 Feb 19 nicklas 211           default:
50 26 Feb 19 nicklas 212             status=S_IN_ERROR;
50 26 Feb 19 nicklas 213           }
50 26 Feb 19 nicklas 214           break;
50 26 Feb 19 nicklas 215           
50 26 Feb 19 nicklas 216         case S_IN_ARRAY:
50 26 Feb 19 nicklas 217           switch(token.type){
50 26 Feb 19 nicklas 218           case Yytoken.TYPE_COMMA:
50 26 Feb 19 nicklas 219             break;
50 26 Feb 19 nicklas 220           case Yytoken.TYPE_VALUE:
57 26 Feb 19 nicklas 221             List<Object> val=(List)valueStack.getFirst();
50 26 Feb 19 nicklas 222             val.add(token.value);
50 26 Feb 19 nicklas 223             break;
50 26 Feb 19 nicklas 224           case Yytoken.TYPE_RIGHT_SQUARE:
50 26 Feb 19 nicklas 225             if(valueStack.size()>1){
50 26 Feb 19 nicklas 226               statusStack.removeFirst();
50 26 Feb 19 nicklas 227               valueStack.removeFirst();
50 26 Feb 19 nicklas 228               status=peekStatus(statusStack);
50 26 Feb 19 nicklas 229             }
50 26 Feb 19 nicklas 230             else{
50 26 Feb 19 nicklas 231               status=S_IN_FINISHED_VALUE;
50 26 Feb 19 nicklas 232             }
50 26 Feb 19 nicklas 233             break;
50 26 Feb 19 nicklas 234           case Yytoken.TYPE_LEFT_BRACE:
50 26 Feb 19 nicklas 235             val=(List)valueStack.getFirst();
57 26 Feb 19 nicklas 236             Map<String, Object> newObject=createObjectContainer(containerFactory);
50 26 Feb 19 nicklas 237             val.add(newObject);
50 26 Feb 19 nicklas 238             status=S_IN_OBJECT;
50 26 Feb 19 nicklas 239             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 240             valueStack.addFirst(newObject);
50 26 Feb 19 nicklas 241             break;
50 26 Feb 19 nicklas 242           case Yytoken.TYPE_LEFT_SQUARE:
50 26 Feb 19 nicklas 243             val=(List)valueStack.getFirst();
57 26 Feb 19 nicklas 244             List<Object> newArray=createArrayContainer(containerFactory);
50 26 Feb 19 nicklas 245             val.add(newArray);
50 26 Feb 19 nicklas 246             status=S_IN_ARRAY;
50 26 Feb 19 nicklas 247             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 248             valueStack.addFirst(newArray);
50 26 Feb 19 nicklas 249             break;
50 26 Feb 19 nicklas 250           default:
50 26 Feb 19 nicklas 251             status=S_IN_ERROR;
50 26 Feb 19 nicklas 252           }//inner switch
50 26 Feb 19 nicklas 253           break;
50 26 Feb 19 nicklas 254         case S_IN_ERROR:
50 26 Feb 19 nicklas 255           throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
50 26 Feb 19 nicklas 256         }//switch
50 26 Feb 19 nicklas 257         if(status==S_IN_ERROR){
50 26 Feb 19 nicklas 258           throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
50 26 Feb 19 nicklas 259         }
50 26 Feb 19 nicklas 260       }while(token.type!=Yytoken.TYPE_EOF);
50 26 Feb 19 nicklas 261     }
50 26 Feb 19 nicklas 262     catch(IOException ie){
50 26 Feb 19 nicklas 263       throw ie;
50 26 Feb 19 nicklas 264     }
50 26 Feb 19 nicklas 265     
50 26 Feb 19 nicklas 266     throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
50 26 Feb 19 nicklas 267   }
50 26 Feb 19 nicklas 268   
50 26 Feb 19 nicklas 269   private void nextToken() throws ParseException, IOException{
50 26 Feb 19 nicklas 270     token = lexer.yylex();
50 26 Feb 19 nicklas 271     if(token == null)
50 26 Feb 19 nicklas 272       token = new Yytoken(Yytoken.TYPE_EOF, null);
50 26 Feb 19 nicklas 273   }
50 26 Feb 19 nicklas 274   
57 26 Feb 19 nicklas 275   private Map<String, Object> createObjectContainer(ContainerFactory containerFactory){
50 26 Feb 19 nicklas 276     if(containerFactory == null)
50 26 Feb 19 nicklas 277       return new JSONObject();
57 26 Feb 19 nicklas 278     Map<String, Object> m = containerFactory.createObjectContainer();
50 26 Feb 19 nicklas 279     
50 26 Feb 19 nicklas 280     if(m == null)
50 26 Feb 19 nicklas 281       return new JSONObject();
50 26 Feb 19 nicklas 282     return m;
50 26 Feb 19 nicklas 283   }
50 26 Feb 19 nicklas 284   
57 26 Feb 19 nicklas 285   private List<Object> createArrayContainer(ContainerFactory containerFactory){
50 26 Feb 19 nicklas 286     if(containerFactory == null)
50 26 Feb 19 nicklas 287       return new JSONArray();
57 26 Feb 19 nicklas 288     List<Object> l = containerFactory.creatArrayContainer();
50 26 Feb 19 nicklas 289     
50 26 Feb 19 nicklas 290     if(l == null)
50 26 Feb 19 nicklas 291       return new JSONArray();
50 26 Feb 19 nicklas 292     return l;
50 26 Feb 19 nicklas 293   }
50 26 Feb 19 nicklas 294   
50 26 Feb 19 nicklas 295   public void parse(String s, ContentHandler contentHandler) throws ParseException{
50 26 Feb 19 nicklas 296     parse(s, contentHandler, false);
50 26 Feb 19 nicklas 297   }
50 26 Feb 19 nicklas 298   
50 26 Feb 19 nicklas 299   public void parse(String s, ContentHandler contentHandler, boolean isResume) throws ParseException{
50 26 Feb 19 nicklas 300     StringReader in=new StringReader(s);
50 26 Feb 19 nicklas 301     try{
50 26 Feb 19 nicklas 302       parse(in, contentHandler, isResume);
50 26 Feb 19 nicklas 303     }
50 26 Feb 19 nicklas 304     catch(IOException ie){
50 26 Feb 19 nicklas 305       /*
50 26 Feb 19 nicklas 306        * Actually it will never happen.
50 26 Feb 19 nicklas 307        */
50 26 Feb 19 nicklas 308       throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
50 26 Feb 19 nicklas 309     }
50 26 Feb 19 nicklas 310   }
50 26 Feb 19 nicklas 311   
50 26 Feb 19 nicklas 312   public void parse(Reader in, ContentHandler contentHandler) throws IOException, ParseException{
50 26 Feb 19 nicklas 313     parse(in, contentHandler, false);
50 26 Feb 19 nicklas 314   }
50 26 Feb 19 nicklas 315   
50 26 Feb 19 nicklas 316   /**
50 26 Feb 19 nicklas 317    * Stream processing of JSON text.
50 26 Feb 19 nicklas 318    * 
50 26 Feb 19 nicklas 319    * @see ContentHandler
50 26 Feb 19 nicklas 320    * 
50 26 Feb 19 nicklas 321    * @param in
50 26 Feb 19 nicklas 322    * @param contentHandler
50 26 Feb 19 nicklas 323    * @param isResume - Indicates if it continues previous parsing operation.
50 26 Feb 19 nicklas 324      *                   If set to true, resume parsing the old stream, and parameter 'in' will be ignored. 
50 26 Feb 19 nicklas 325    *                   If this method is called for the first time in this instance, isResume will be ignored.
50 26 Feb 19 nicklas 326    * 
50 26 Feb 19 nicklas 327    * @throws IOException
50 26 Feb 19 nicklas 328    * @throws ParseException
50 26 Feb 19 nicklas 329    */
50 26 Feb 19 nicklas 330   public void parse(Reader in, ContentHandler contentHandler, boolean isResume) throws IOException, ParseException{
50 26 Feb 19 nicklas 331     if(!isResume){
50 26 Feb 19 nicklas 332       reset(in);
57 26 Feb 19 nicklas 333       handlerStatusStack = new LinkedList<>();
50 26 Feb 19 nicklas 334     }
50 26 Feb 19 nicklas 335     else{
50 26 Feb 19 nicklas 336       if(handlerStatusStack == null){
50 26 Feb 19 nicklas 337         isResume = false;
50 26 Feb 19 nicklas 338         reset(in);
57 26 Feb 19 nicklas 339         handlerStatusStack = new LinkedList<>();
50 26 Feb 19 nicklas 340       }
50 26 Feb 19 nicklas 341     }
50 26 Feb 19 nicklas 342     
57 26 Feb 19 nicklas 343     LinkedList<Integer> statusStack = handlerStatusStack;  
50 26 Feb 19 nicklas 344     
50 26 Feb 19 nicklas 345     try{
50 26 Feb 19 nicklas 346       do{
50 26 Feb 19 nicklas 347         switch(status){
50 26 Feb 19 nicklas 348         case S_INIT:
50 26 Feb 19 nicklas 349           contentHandler.startJSON();
50 26 Feb 19 nicklas 350           nextToken();
50 26 Feb 19 nicklas 351           switch(token.type){
50 26 Feb 19 nicklas 352           case Yytoken.TYPE_VALUE:
50 26 Feb 19 nicklas 353             status=S_IN_FINISHED_VALUE;
50 26 Feb 19 nicklas 354             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 355             if(!contentHandler.primitive(token.value))
50 26 Feb 19 nicklas 356               return;
50 26 Feb 19 nicklas 357             break;
50 26 Feb 19 nicklas 358           case Yytoken.TYPE_LEFT_BRACE:
50 26 Feb 19 nicklas 359             status=S_IN_OBJECT;
50 26 Feb 19 nicklas 360             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 361             if(!contentHandler.startObject())
50 26 Feb 19 nicklas 362               return;
50 26 Feb 19 nicklas 363             break;
50 26 Feb 19 nicklas 364           case Yytoken.TYPE_LEFT_SQUARE:
50 26 Feb 19 nicklas 365             status=S_IN_ARRAY;
50 26 Feb 19 nicklas 366             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 367             if(!contentHandler.startArray())
50 26 Feb 19 nicklas 368               return;
50 26 Feb 19 nicklas 369             break;
50 26 Feb 19 nicklas 370           default:
50 26 Feb 19 nicklas 371             status=S_IN_ERROR;
50 26 Feb 19 nicklas 372           }//inner switch
50 26 Feb 19 nicklas 373           break;
50 26 Feb 19 nicklas 374           
50 26 Feb 19 nicklas 375         case S_IN_FINISHED_VALUE:
50 26 Feb 19 nicklas 376           nextToken();
50 26 Feb 19 nicklas 377           if(token.type==Yytoken.TYPE_EOF){
50 26 Feb 19 nicklas 378             contentHandler.endJSON();
50 26 Feb 19 nicklas 379             status = S_END;
50 26 Feb 19 nicklas 380             return;
50 26 Feb 19 nicklas 381           }
50 26 Feb 19 nicklas 382           else{
50 26 Feb 19 nicklas 383             status = S_IN_ERROR;
50 26 Feb 19 nicklas 384             throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
50 26 Feb 19 nicklas 385           }
50 26 Feb 19 nicklas 386       
50 26 Feb 19 nicklas 387         case S_IN_OBJECT:
50 26 Feb 19 nicklas 388           nextToken();
50 26 Feb 19 nicklas 389           switch(token.type){
50 26 Feb 19 nicklas 390           case Yytoken.TYPE_COMMA:
50 26 Feb 19 nicklas 391             break;
50 26 Feb 19 nicklas 392           case Yytoken.TYPE_VALUE:
50 26 Feb 19 nicklas 393             if(token.value instanceof String){
50 26 Feb 19 nicklas 394               String key=(String)token.value;
50 26 Feb 19 nicklas 395               status=S_PASSED_PAIR_KEY;
50 26 Feb 19 nicklas 396               statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 397               if(!contentHandler.startObjectEntry(key))
50 26 Feb 19 nicklas 398                 return;
50 26 Feb 19 nicklas 399             }
50 26 Feb 19 nicklas 400             else{
50 26 Feb 19 nicklas 401               status=S_IN_ERROR;
50 26 Feb 19 nicklas 402             }
50 26 Feb 19 nicklas 403             break;
50 26 Feb 19 nicklas 404           case Yytoken.TYPE_RIGHT_BRACE:
50 26 Feb 19 nicklas 405             if(statusStack.size()>1){
50 26 Feb 19 nicklas 406               statusStack.removeFirst();
50 26 Feb 19 nicklas 407               status=peekStatus(statusStack);
50 26 Feb 19 nicklas 408             }
50 26 Feb 19 nicklas 409             else{
50 26 Feb 19 nicklas 410               status=S_IN_FINISHED_VALUE;
50 26 Feb 19 nicklas 411             }
50 26 Feb 19 nicklas 412             if(!contentHandler.endObject())
50 26 Feb 19 nicklas 413               return;
50 26 Feb 19 nicklas 414             break;
50 26 Feb 19 nicklas 415           default:
50 26 Feb 19 nicklas 416             status=S_IN_ERROR;
50 26 Feb 19 nicklas 417             break;
50 26 Feb 19 nicklas 418           }//inner switch
50 26 Feb 19 nicklas 419           break;
50 26 Feb 19 nicklas 420           
50 26 Feb 19 nicklas 421         case S_PASSED_PAIR_KEY:
50 26 Feb 19 nicklas 422           nextToken();
50 26 Feb 19 nicklas 423           switch(token.type){
50 26 Feb 19 nicklas 424           case Yytoken.TYPE_COLON:
50 26 Feb 19 nicklas 425             break;
50 26 Feb 19 nicklas 426           case Yytoken.TYPE_VALUE:
50 26 Feb 19 nicklas 427             statusStack.removeFirst();
50 26 Feb 19 nicklas 428             status=peekStatus(statusStack);
50 26 Feb 19 nicklas 429             if(!contentHandler.primitive(token.value))
50 26 Feb 19 nicklas 430               return;
50 26 Feb 19 nicklas 431             if(!contentHandler.endObjectEntry())
50 26 Feb 19 nicklas 432               return;
50 26 Feb 19 nicklas 433             break;
50 26 Feb 19 nicklas 434           case Yytoken.TYPE_LEFT_SQUARE:
50 26 Feb 19 nicklas 435             statusStack.removeFirst();
50 26 Feb 19 nicklas 436             statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
50 26 Feb 19 nicklas 437             status=S_IN_ARRAY;
50 26 Feb 19 nicklas 438             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 439             if(!contentHandler.startArray())
50 26 Feb 19 nicklas 440               return;
50 26 Feb 19 nicklas 441             break;
50 26 Feb 19 nicklas 442           case Yytoken.TYPE_LEFT_BRACE:
50 26 Feb 19 nicklas 443             statusStack.removeFirst();
50 26 Feb 19 nicklas 444             statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
50 26 Feb 19 nicklas 445             status=S_IN_OBJECT;
50 26 Feb 19 nicklas 446             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 447             if(!contentHandler.startObject())
50 26 Feb 19 nicklas 448               return;
50 26 Feb 19 nicklas 449             break;
50 26 Feb 19 nicklas 450           default:
50 26 Feb 19 nicklas 451             status=S_IN_ERROR;
50 26 Feb 19 nicklas 452           }
50 26 Feb 19 nicklas 453           break;
50 26 Feb 19 nicklas 454         
50 26 Feb 19 nicklas 455         case S_IN_PAIR_VALUE:
50 26 Feb 19 nicklas 456           /*
50 26 Feb 19 nicklas 457            * S_IN_PAIR_VALUE is just a marker to indicate the end of an object entry, it doesn't proccess any token,
50 26 Feb 19 nicklas 458            * therefore delay consuming token until next round.
50 26 Feb 19 nicklas 459            */
50 26 Feb 19 nicklas 460           statusStack.removeFirst();
50 26 Feb 19 nicklas 461           status = peekStatus(statusStack);
50 26 Feb 19 nicklas 462           if(!contentHandler.endObjectEntry())
50 26 Feb 19 nicklas 463             return;
50 26 Feb 19 nicklas 464           break;
50 26 Feb 19 nicklas 465           
50 26 Feb 19 nicklas 466         case S_IN_ARRAY:
50 26 Feb 19 nicklas 467           nextToken();
50 26 Feb 19 nicklas 468           switch(token.type){
50 26 Feb 19 nicklas 469           case Yytoken.TYPE_COMMA:
50 26 Feb 19 nicklas 470             break;
50 26 Feb 19 nicklas 471           case Yytoken.TYPE_VALUE:
50 26 Feb 19 nicklas 472             if(!contentHandler.primitive(token.value))
50 26 Feb 19 nicklas 473               return;
50 26 Feb 19 nicklas 474             break;
50 26 Feb 19 nicklas 475           case Yytoken.TYPE_RIGHT_SQUARE:
50 26 Feb 19 nicklas 476             if(statusStack.size()>1){
50 26 Feb 19 nicklas 477               statusStack.removeFirst();
50 26 Feb 19 nicklas 478               status=peekStatus(statusStack);
50 26 Feb 19 nicklas 479             }
50 26 Feb 19 nicklas 480             else{
50 26 Feb 19 nicklas 481               status=S_IN_FINISHED_VALUE;
50 26 Feb 19 nicklas 482             }
50 26 Feb 19 nicklas 483             if(!contentHandler.endArray())
50 26 Feb 19 nicklas 484               return;
50 26 Feb 19 nicklas 485             break;
50 26 Feb 19 nicklas 486           case Yytoken.TYPE_LEFT_BRACE:
50 26 Feb 19 nicklas 487             status=S_IN_OBJECT;
50 26 Feb 19 nicklas 488             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 489             if(!contentHandler.startObject())
50 26 Feb 19 nicklas 490               return;
50 26 Feb 19 nicklas 491             break;
50 26 Feb 19 nicklas 492           case Yytoken.TYPE_LEFT_SQUARE:
50 26 Feb 19 nicklas 493             status=S_IN_ARRAY;
50 26 Feb 19 nicklas 494             statusStack.addFirst(new Integer(status));
50 26 Feb 19 nicklas 495             if(!contentHandler.startArray())
50 26 Feb 19 nicklas 496               return;
50 26 Feb 19 nicklas 497             break;
50 26 Feb 19 nicklas 498           default:
50 26 Feb 19 nicklas 499             status=S_IN_ERROR;
50 26 Feb 19 nicklas 500           }//inner switch
50 26 Feb 19 nicklas 501           break;
50 26 Feb 19 nicklas 502           
50 26 Feb 19 nicklas 503         case S_END:
50 26 Feb 19 nicklas 504           return;
50 26 Feb 19 nicklas 505           
50 26 Feb 19 nicklas 506         case S_IN_ERROR:
50 26 Feb 19 nicklas 507           throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
50 26 Feb 19 nicklas 508         }//switch
50 26 Feb 19 nicklas 509         if(status==S_IN_ERROR){
50 26 Feb 19 nicklas 510           throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
50 26 Feb 19 nicklas 511         }
50 26 Feb 19 nicklas 512       }while(token.type!=Yytoken.TYPE_EOF);
50 26 Feb 19 nicklas 513     }
50 26 Feb 19 nicklas 514     catch(IOException ie){
50 26 Feb 19 nicklas 515       status = S_IN_ERROR;
50 26 Feb 19 nicklas 516       throw ie;
50 26 Feb 19 nicklas 517     }
50 26 Feb 19 nicklas 518     catch(ParseException pe){
50 26 Feb 19 nicklas 519       status = S_IN_ERROR;
50 26 Feb 19 nicklas 520       throw pe;
50 26 Feb 19 nicklas 521     }
50 26 Feb 19 nicklas 522     catch(RuntimeException re){
50 26 Feb 19 nicklas 523       status = S_IN_ERROR;
50 26 Feb 19 nicklas 524       throw re;
50 26 Feb 19 nicklas 525     }
50 26 Feb 19 nicklas 526     catch(Error e){
50 26 Feb 19 nicklas 527       status = S_IN_ERROR;
50 26 Feb 19 nicklas 528       throw e;
50 26 Feb 19 nicklas 529     }
50 26 Feb 19 nicklas 530     
50 26 Feb 19 nicklas 531     status = S_IN_ERROR;
50 26 Feb 19 nicklas 532     throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
50 26 Feb 19 nicklas 533   }
50 26 Feb 19 nicklas 534 }