import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
-
/**
* Parser for JSON text. Please note that JSONParser is NOT thread-safe.
*
* @author FangYidong<fangyidong@yahoo.com.cn>
*/
-public class JSONParser {
- public static final int S_INIT=0;
- public static final int S_IN_FINISHED_VALUE=1;//string,number,boolean,null,object,array
- public static final int S_IN_OBJECT=2;
- public static final int S_IN_ARRAY=3;
- public static final int S_PASSED_PAIR_KEY=4;
- public static final int S_IN_PAIR_VALUE=5;
- public static final int S_END=6;
- public static final int S_IN_ERROR=-1;
-
- private LinkedList handlerStatusStack;
- private Yylex lexer = new Yylex((Reader)null);
- private Yytoken token = null;
- private int status = S_INIT;
-
- private int peekStatus(LinkedList statusStack){
- if(statusStack.size()==0)
- return -1;
- Integer status=(Integer)statusStack.getFirst();
- return status.intValue();
- }
-
- /**
- * Reset the parser to the initial state without resetting the underlying reader.
- *
- */
- public void reset(){
- token = null;
- status = S_INIT;
- handlerStatusStack = null;
+public class JSONParser
+{
+ public static final int S_INIT = 0;
+
+ public static final int S_IN_FINISHED_VALUE = 1;// string,number,boolean,null,object,array
+
+ public static final int S_IN_OBJECT = 2;
+
+ public static final int S_IN_ARRAY = 3;
+
+ public static final int S_PASSED_PAIR_KEY = 4;
+
+ public static final int S_IN_PAIR_VALUE = 5;
+
+ public static final int S_END = 6;
+
+ public static final int S_IN_ERROR = -1;
+
+ private LinkedList handlerStatusStack;
+
+ private Yylex lexer = new Yylex((Reader) null);
+
+ private Yytoken token = null;
+
+ private int status = S_INIT;
+
+ private int peekStatus(LinkedList statusStack)
+ {
+ if (statusStack.size() == 0)
+ return -1;
+ Integer status = (Integer) statusStack.getFirst();
+ return status.intValue();
+ }
+
+ /**
+ * Reset the parser to the initial state without resetting the underlying
+ * reader.
+ *
+ */
+ public void reset()
+ {
+ token = null;
+ status = S_INIT;
+ handlerStatusStack = null;
+ }
+
+ /**
+ * Reset the parser to the initial state with a new character reader.
+ *
+ * @param in
+ * - The new character reader.
+ * @throws IOException
+ * @throws ParseException
+ */
+ public void reset(Reader in)
+ {
+ lexer.yyreset(in);
+ reset();
+ }
+
+ /**
+ * @return The position of the beginning of the current token.
+ */
+ public int getPosition()
+ {
+ return lexer.getPosition();
+ }
+
+ public Object parse(String s) throws ParseException
+ {
+ return parse(s, (ContainerFactory) null);
+ }
+
+ public Object parse(String s, ContainerFactory containerFactory)
+ throws ParseException
+ {
+ StringReader in = new StringReader(s);
+ try
+ {
+ return parse(in, containerFactory);
+ } catch (IOException ie)
+ {
+ /*
+ * Actually it will never happen.
+ */
+ throw new ParseException(-1,
+ ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
+ }
+ }
+
+ public Object parse(Reader in) throws IOException, ParseException
+ {
+ return parse(in, (ContainerFactory) null);
+ }
+
+ /**
+ * Parse JSON text into java object from the input source.
+ *
+ * @param in
+ * @param containerFactory
+ * - Use this factory to createyour own JSON object and JSON array
+ * containers.
+ * @return Instance of the following: org.json.simple.JSONObject,
+ * org.json.simple.JSONArray, java.lang.String, java.lang.Number,
+ * java.lang.Boolean, null
+ *
+ * @throws IOException
+ * @throws ParseException
+ */
+ public Object parse(Reader in, ContainerFactory containerFactory)
+ throws IOException, ParseException
+ {
+ reset(in);
+ LinkedList statusStack = new LinkedList();
+ LinkedList valueStack = new LinkedList();
+
+ try
+ {
+ do
+ {
+ nextToken();
+ switch (status)
+ {
+ case S_INIT:
+ switch (token.type)
+ {
+ case Yytoken.TYPE_VALUE:
+ status = S_IN_FINISHED_VALUE;
+ statusStack.addFirst(new Integer(status));
+ valueStack.addFirst(token.value);
+ break;
+ case Yytoken.TYPE_LEFT_BRACE:
+ status = S_IN_OBJECT;
+ statusStack.addFirst(new Integer(status));
+ valueStack.addFirst(createObjectContainer(containerFactory));
+ break;
+ case Yytoken.TYPE_LEFT_SQUARE:
+ status = S_IN_ARRAY;
+ statusStack.addFirst(new Integer(status));
+ valueStack.addFirst(createArrayContainer(containerFactory));
+ break;
+ default:
+ status = S_IN_ERROR;
+ }// inner switch
+ break;
+
+ case S_IN_FINISHED_VALUE:
+ if (token.type == Yytoken.TYPE_EOF)
+ return valueStack.removeFirst();
+ else
+ throw new ParseException(getPosition(),
+ ParseException.ERROR_UNEXPECTED_TOKEN, token);
+
+ case S_IN_OBJECT:
+ switch (token.type)
+ {
+ case Yytoken.TYPE_COMMA:
+ break;
+ case Yytoken.TYPE_VALUE:
+ if (token.value instanceof String)
+ {
+ String key = (String) token.value;
+ valueStack.addFirst(key);
+ status = S_PASSED_PAIR_KEY;
+ statusStack.addFirst(new Integer(status));
+ }
+ else
+ {
+ status = S_IN_ERROR;
+ }
+ break;
+ case Yytoken.TYPE_RIGHT_BRACE:
+ if (valueStack.size() > 1)
+ {
+ statusStack.removeFirst();
+ valueStack.removeFirst();
+ status = peekStatus(statusStack);
+ }
+ else
+ {
+ status = S_IN_FINISHED_VALUE;
+ }
+ break;
+ default:
+ status = S_IN_ERROR;
+ break;
+ }// inner switch
+ break;
+
+ case S_PASSED_PAIR_KEY:
+ switch (token.type)
+ {
+ case Yytoken.TYPE_COLON:
+ break;
+ case Yytoken.TYPE_VALUE:
+ statusStack.removeFirst();
+ String key = (String) valueStack.removeFirst();
+ Map parent = (Map) valueStack.getFirst();
+ parent.put(key, token.value);
+ status = peekStatus(statusStack);
+ break;
+ case Yytoken.TYPE_LEFT_SQUARE:
+ statusStack.removeFirst();
+ key = (String) valueStack.removeFirst();
+ parent = (Map) valueStack.getFirst();
+ List newArray = createArrayContainer(containerFactory);
+ parent.put(key, newArray);
+ status = S_IN_ARRAY;
+ statusStack.addFirst(new Integer(status));
+ valueStack.addFirst(newArray);
+ break;
+ case Yytoken.TYPE_LEFT_BRACE:
+ statusStack.removeFirst();
+ key = (String) valueStack.removeFirst();
+ parent = (Map) valueStack.getFirst();
+ Map newObject = createObjectContainer(containerFactory);
+ parent.put(key, newObject);
+ status = S_IN_OBJECT;
+ statusStack.addFirst(new Integer(status));
+ valueStack.addFirst(newObject);
+ break;
+ default:
+ status = S_IN_ERROR;
+ }
+ break;
+
+ case S_IN_ARRAY:
+ switch (token.type)
+ {
+ case Yytoken.TYPE_COMMA:
+ break;
+ case Yytoken.TYPE_VALUE:
+ List val = (List) valueStack.getFirst();
+ val.add(token.value);
+ break;
+ case Yytoken.TYPE_RIGHT_SQUARE:
+ if (valueStack.size() > 1)
+ {
+ statusStack.removeFirst();
+ valueStack.removeFirst();
+ status = peekStatus(statusStack);
+ }
+ else
+ {
+ status = S_IN_FINISHED_VALUE;
+ }
+ break;
+ case Yytoken.TYPE_LEFT_BRACE:
+ val = (List) valueStack.getFirst();
+ Map newObject = createObjectContainer(containerFactory);
+ val.add(newObject);
+ status = S_IN_OBJECT;
+ statusStack.addFirst(new Integer(status));
+ valueStack.addFirst(newObject);
+ break;
+ case Yytoken.TYPE_LEFT_SQUARE:
+ val = (List) valueStack.getFirst();
+ List newArray = createArrayContainer(containerFactory);
+ val.add(newArray);
+ status = S_IN_ARRAY;
+ statusStack.addFirst(new Integer(status));
+ valueStack.addFirst(newArray);
+ break;
+ default:
+ status = S_IN_ERROR;
+ }// inner switch
+ break;
+ case S_IN_ERROR:
+ throw new ParseException(getPosition(),
+ ParseException.ERROR_UNEXPECTED_TOKEN, token);
+ }// switch
+ if (status == S_IN_ERROR)
+ {
+ throw new ParseException(getPosition(),
+ ParseException.ERROR_UNEXPECTED_TOKEN, token);
+ }
+ } while (token.type != Yytoken.TYPE_EOF);
+ } catch (IOException ie)
+ {
+ throw ie;
+ }
+
+ throw new ParseException(getPosition(),
+ ParseException.ERROR_UNEXPECTED_TOKEN, token);
+ }
+
+ private void nextToken() throws ParseException, IOException
+ {
+ token = lexer.yylex();
+ if (token == null)
+ token = new Yytoken(Yytoken.TYPE_EOF, null);
+ }
+
+ private Map createObjectContainer(ContainerFactory containerFactory)
+ {
+ if (containerFactory == null)
+ return new JSONObject();
+ Map m = containerFactory.createObjectContainer();
+
+ if (m == null)
+ return new JSONObject();
+ return m;
+ }
+
+ private List createArrayContainer(ContainerFactory containerFactory)
+ {
+ if (containerFactory == null)
+ return new JSONArray();
+ List l = containerFactory.creatArrayContainer();
+
+ if (l == null)
+ return new JSONArray();
+ return l;
+ }
+
+ public void parse(String s, ContentHandler contentHandler)
+ throws ParseException
+ {
+ parse(s, contentHandler, false);
+ }
+
+ public void parse(String s, ContentHandler contentHandler,
+ boolean isResume) throws ParseException
+ {
+ StringReader in = new StringReader(s);
+ try
+ {
+ parse(in, contentHandler, isResume);
+ } catch (IOException ie)
+ {
+ /*
+ * Actually it will never happen.
+ */
+ throw new ParseException(-1,
+ ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
+ }
+ }
+
+ public void parse(Reader in, ContentHandler contentHandler)
+ throws IOException, ParseException
+ {
+ parse(in, contentHandler, false);
+ }
+
+ /**
+ * Stream processing of JSON text.
+ *
+ * @see ContentHandler
+ *
+ * @param in
+ * @param contentHandler
+ * @param isResume
+ * - Indicates if it continues previous parsing operation. If set to
+ * true, resume parsing the old stream, and parameter 'in' will be
+ * ignored. If this method is called for the first time in this
+ * instance, isResume will be ignored.
+ *
+ * @throws IOException
+ * @throws ParseException
+ */
+ public void parse(Reader in, ContentHandler contentHandler,
+ boolean isResume) throws IOException, ParseException
+ {
+ if (!isResume)
+ {
+ reset(in);
+ handlerStatusStack = new LinkedList();
}
-
- /**
- * Reset the parser to the initial state with a new character reader.
- *
- * @param in - The new character reader.
- * @throws IOException
- * @throws ParseException
- */
- public void reset(Reader in){
- lexer.yyreset(in);
- reset();
- }
-
- /**
- * @return The position of the beginning of the current token.
- */
- public int getPosition(){
- return lexer.getPosition();
- }
-
- public Object parse(String s) throws ParseException{
- return parse(s, (ContainerFactory)null);
- }
-
- public Object parse(String s, ContainerFactory containerFactory) throws ParseException{
- StringReader in=new StringReader(s);
- try{
- return parse(in, containerFactory);
- }
- catch(IOException ie){
- /*
- * Actually it will never happen.
- */
- throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
- }
- }
-
- public Object parse(Reader in) throws IOException, ParseException{
- return parse(in, (ContainerFactory)null);
- }
-
- /**
- * Parse JSON text into java object from the input source.
- *
- * @param in
- * @param containerFactory - Use this factory to createyour own JSON object and JSON array containers.
- * @return Instance of the following:
- * org.json.simple.JSONObject,
- * org.json.simple.JSONArray,
- * java.lang.String,
- * java.lang.Number,
- * java.lang.Boolean,
- * null
- *
- * @throws IOException
- * @throws ParseException
- */
- public Object parse(Reader in, ContainerFactory containerFactory) throws IOException, ParseException{
- reset(in);
- LinkedList statusStack = new LinkedList();
- LinkedList valueStack = new LinkedList();
-
- try{
- do{
- nextToken();
- switch(status){
- case S_INIT:
- switch(token.type){
- case Yytoken.TYPE_VALUE:
- status=S_IN_FINISHED_VALUE;
- statusStack.addFirst(new Integer(status));
- valueStack.addFirst(token.value);
- break;
- case Yytoken.TYPE_LEFT_BRACE:
- status=S_IN_OBJECT;
- statusStack.addFirst(new Integer(status));
- valueStack.addFirst(createObjectContainer(containerFactory));
- break;
- case Yytoken.TYPE_LEFT_SQUARE:
- status=S_IN_ARRAY;
- statusStack.addFirst(new Integer(status));
- valueStack.addFirst(createArrayContainer(containerFactory));
- break;
- default:
- status=S_IN_ERROR;
- }//inner switch
- break;
-
- case S_IN_FINISHED_VALUE:
- if(token.type==Yytoken.TYPE_EOF)
- return valueStack.removeFirst();
- else
- throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
-
- case S_IN_OBJECT:
- switch(token.type){
- case Yytoken.TYPE_COMMA:
- break;
- case Yytoken.TYPE_VALUE:
- if(token.value instanceof String){
- String key=(String)token.value;
- valueStack.addFirst(key);
- status=S_PASSED_PAIR_KEY;
- statusStack.addFirst(new Integer(status));
- }
- else{
- status=S_IN_ERROR;
- }
- break;
- case Yytoken.TYPE_RIGHT_BRACE:
- if(valueStack.size()>1){
- statusStack.removeFirst();
- valueStack.removeFirst();
- status=peekStatus(statusStack);
- }
- else{
- status=S_IN_FINISHED_VALUE;
- }
- break;
- default:
- status=S_IN_ERROR;
- break;
- }//inner switch
- break;
-
- case S_PASSED_PAIR_KEY:
- switch(token.type){
- case Yytoken.TYPE_COLON:
- break;
- case Yytoken.TYPE_VALUE:
- statusStack.removeFirst();
- String key=(String)valueStack.removeFirst();
- Map parent=(Map)valueStack.getFirst();
- parent.put(key,token.value);
- status=peekStatus(statusStack);
- break;
- case Yytoken.TYPE_LEFT_SQUARE:
- statusStack.removeFirst();
- key=(String)valueStack.removeFirst();
- parent=(Map)valueStack.getFirst();
- List newArray=createArrayContainer(containerFactory);
- parent.put(key,newArray);
- status=S_IN_ARRAY;
- statusStack.addFirst(new Integer(status));
- valueStack.addFirst(newArray);
- break;
- case Yytoken.TYPE_LEFT_BRACE:
- statusStack.removeFirst();
- key=(String)valueStack.removeFirst();
- parent=(Map)valueStack.getFirst();
- Map newObject=createObjectContainer(containerFactory);
- parent.put(key,newObject);
- status=S_IN_OBJECT;
- statusStack.addFirst(new Integer(status));
- valueStack.addFirst(newObject);
- break;
- default:
- status=S_IN_ERROR;
- }
- break;
-
- case S_IN_ARRAY:
- switch(token.type){
- case Yytoken.TYPE_COMMA:
- break;
- case Yytoken.TYPE_VALUE:
- List val=(List)valueStack.getFirst();
- val.add(token.value);
- break;
- case Yytoken.TYPE_RIGHT_SQUARE:
- if(valueStack.size()>1){
- statusStack.removeFirst();
- valueStack.removeFirst();
- status=peekStatus(statusStack);
- }
- else{
- status=S_IN_FINISHED_VALUE;
- }
- break;
- case Yytoken.TYPE_LEFT_BRACE:
- val=(List)valueStack.getFirst();
- Map newObject=createObjectContainer(containerFactory);
- val.add(newObject);
- status=S_IN_OBJECT;
- statusStack.addFirst(new Integer(status));
- valueStack.addFirst(newObject);
- break;
- case Yytoken.TYPE_LEFT_SQUARE:
- val=(List)valueStack.getFirst();
- List newArray=createArrayContainer(containerFactory);
- val.add(newArray);
- status=S_IN_ARRAY;
- statusStack.addFirst(new Integer(status));
- valueStack.addFirst(newArray);
- break;
- default:
- status=S_IN_ERROR;
- }//inner switch
- break;
- case S_IN_ERROR:
- throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
- }//switch
- if(status==S_IN_ERROR){
- throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
- }
- }while(token.type!=Yytoken.TYPE_EOF);
- }
- catch(IOException ie){
- throw ie;
- }
-
- throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
- }
-
- private void nextToken() throws ParseException, IOException{
- token = lexer.yylex();
- if(token == null)
- token = new Yytoken(Yytoken.TYPE_EOF, null);
- }
-
- private Map createObjectContainer(ContainerFactory containerFactory){
- if(containerFactory == null)
- return new JSONObject();
- Map m = containerFactory.createObjectContainer();
-
- if(m == null)
- return new JSONObject();
- return m;
- }
-
- private List createArrayContainer(ContainerFactory containerFactory){
- if(containerFactory == null)
- return new JSONArray();
- List l = containerFactory.creatArrayContainer();
-
- if(l == null)
- return new JSONArray();
- return l;
- }
-
- public void parse(String s, ContentHandler contentHandler) throws ParseException{
- parse(s, contentHandler, false);
- }
-
- public void parse(String s, ContentHandler contentHandler, boolean isResume) throws ParseException{
- StringReader in=new StringReader(s);
- try{
- parse(in, contentHandler, isResume);
- }
- catch(IOException ie){
- /*
- * Actually it will never happen.
- */
- throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
- }
- }
-
- public void parse(Reader in, ContentHandler contentHandler) throws IOException, ParseException{
- parse(in, contentHandler, false);
- }
-
- /**
- * Stream processing of JSON text.
- *
- * @see ContentHandler
- *
- * @param in
- * @param contentHandler
- * @param isResume - Indicates if it continues previous parsing operation.
- * If set to true, resume parsing the old stream, and parameter 'in' will be ignored.
- * If this method is called for the first time in this instance, isResume will be ignored.
- *
- * @throws IOException
- * @throws ParseException
- */
- public void parse(Reader in, ContentHandler contentHandler, boolean isResume) throws IOException, ParseException{
- if(!isResume){
- reset(in);
- handlerStatusStack = new LinkedList();
- }
- else{
- if(handlerStatusStack == null){
- isResume = false;
- reset(in);
- handlerStatusStack = new LinkedList();
- }
- }
-
- LinkedList statusStack = handlerStatusStack;
-
- try{
- do{
- switch(status){
- case S_INIT:
- contentHandler.startJSON();
- nextToken();
- switch(token.type){
- case Yytoken.TYPE_VALUE:
- status=S_IN_FINISHED_VALUE;
- statusStack.addFirst(new Integer(status));
- if(!contentHandler.primitive(token.value))
- return;
- break;
- case Yytoken.TYPE_LEFT_BRACE:
- status=S_IN_OBJECT;
- statusStack.addFirst(new Integer(status));
- if(!contentHandler.startObject())
- return;
- break;
- case Yytoken.TYPE_LEFT_SQUARE:
- status=S_IN_ARRAY;
- statusStack.addFirst(new Integer(status));
- if(!contentHandler.startArray())
- return;
- break;
- default:
- status=S_IN_ERROR;
- }//inner switch
- break;
-
- case S_IN_FINISHED_VALUE:
- nextToken();
- if(token.type==Yytoken.TYPE_EOF){
- contentHandler.endJSON();
- status = S_END;
- return;
- }
- else{
- status = S_IN_ERROR;
- throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
- }
-
- case S_IN_OBJECT:
- nextToken();
- switch(token.type){
- case Yytoken.TYPE_COMMA:
- break;
- case Yytoken.TYPE_VALUE:
- if(token.value instanceof String){
- String key=(String)token.value;
- status=S_PASSED_PAIR_KEY;
- statusStack.addFirst(new Integer(status));
- if(!contentHandler.startObjectEntry(key))
- return;
- }
- else{
- status=S_IN_ERROR;
- }
- break;
- case Yytoken.TYPE_RIGHT_BRACE:
- if(statusStack.size()>1){
- statusStack.removeFirst();
- status=peekStatus(statusStack);
- }
- else{
- status=S_IN_FINISHED_VALUE;
- }
- if(!contentHandler.endObject())
- return;
- break;
- default:
- status=S_IN_ERROR;
- break;
- }//inner switch
- break;
-
- case S_PASSED_PAIR_KEY:
- nextToken();
- switch(token.type){
- case Yytoken.TYPE_COLON:
- break;
- case Yytoken.TYPE_VALUE:
- statusStack.removeFirst();
- status=peekStatus(statusStack);
- if(!contentHandler.primitive(token.value))
- return;
- if(!contentHandler.endObjectEntry())
- return;
- break;
- case Yytoken.TYPE_LEFT_SQUARE:
- statusStack.removeFirst();
- statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
- status=S_IN_ARRAY;
- statusStack.addFirst(new Integer(status));
- if(!contentHandler.startArray())
- return;
- break;
- case Yytoken.TYPE_LEFT_BRACE:
- statusStack.removeFirst();
- statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
- status=S_IN_OBJECT;
- statusStack.addFirst(new Integer(status));
- if(!contentHandler.startObject())
- return;
- break;
- default:
- status=S_IN_ERROR;
- }
- break;
-
- case S_IN_PAIR_VALUE:
- /*
- * S_IN_PAIR_VALUE is just a marker to indicate the end of an object entry, it doesn't proccess any token,
- * therefore delay consuming token until next round.
- */
- statusStack.removeFirst();
- status = peekStatus(statusStack);
- if(!contentHandler.endObjectEntry())
- return;
- break;
-
- case S_IN_ARRAY:
- nextToken();
- switch(token.type){
- case Yytoken.TYPE_COMMA:
- break;
- case Yytoken.TYPE_VALUE:
- if(!contentHandler.primitive(token.value))
- return;
- break;
- case Yytoken.TYPE_RIGHT_SQUARE:
- if(statusStack.size()>1){
- statusStack.removeFirst();
- status=peekStatus(statusStack);
- }
- else{
- status=S_IN_FINISHED_VALUE;
- }
- if(!contentHandler.endArray())
- return;
- break;
- case Yytoken.TYPE_LEFT_BRACE:
- status=S_IN_OBJECT;
- statusStack.addFirst(new Integer(status));
- if(!contentHandler.startObject())
- return;
- break;
- case Yytoken.TYPE_LEFT_SQUARE:
- status=S_IN_ARRAY;
- statusStack.addFirst(new Integer(status));
- if(!contentHandler.startArray())
- return;
- break;
- default:
- status=S_IN_ERROR;
- }//inner switch
- break;
-
- case S_END:
- return;
-
- case S_IN_ERROR:
- throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
- }//switch
- if(status==S_IN_ERROR){
- throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
- }
- }while(token.type!=Yytoken.TYPE_EOF);
- }
- catch(IOException ie){
- status = S_IN_ERROR;
- throw ie;
- }
- catch(ParseException pe){
- status = S_IN_ERROR;
- throw pe;
- }
- catch(RuntimeException re){
- status = S_IN_ERROR;
- throw re;
- }
- catch(Error e){
- status = S_IN_ERROR;
- throw e;
- }
-
- status = S_IN_ERROR;
- throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
- }
+ else
+ {
+ if (handlerStatusStack == null)
+ {
+ isResume = false;
+ reset(in);
+ handlerStatusStack = new LinkedList();
+ }
+ }
+
+ LinkedList statusStack = handlerStatusStack;
+
+ try
+ {
+ do
+ {
+ switch (status)
+ {
+ case S_INIT:
+ contentHandler.startJSON();
+ nextToken();
+ switch (token.type)
+ {
+ case Yytoken.TYPE_VALUE:
+ status = S_IN_FINISHED_VALUE;
+ statusStack.addFirst(new Integer(status));
+ if (!contentHandler.primitive(token.value))
+ return;
+ break;
+ case Yytoken.TYPE_LEFT_BRACE:
+ status = S_IN_OBJECT;
+ statusStack.addFirst(new Integer(status));
+ if (!contentHandler.startObject())
+ return;
+ break;
+ case Yytoken.TYPE_LEFT_SQUARE:
+ status = S_IN_ARRAY;
+ statusStack.addFirst(new Integer(status));
+ if (!contentHandler.startArray())
+ return;
+ break;
+ default:
+ status = S_IN_ERROR;
+ }// inner switch
+ break;
+
+ case S_IN_FINISHED_VALUE:
+ nextToken();
+ if (token.type == Yytoken.TYPE_EOF)
+ {
+ contentHandler.endJSON();
+ status = S_END;
+ return;
+ }
+ else
+ {
+ status = S_IN_ERROR;
+ throw new ParseException(getPosition(),
+ ParseException.ERROR_UNEXPECTED_TOKEN, token);
+ }
+
+ case S_IN_OBJECT:
+ nextToken();
+ switch (token.type)
+ {
+ case Yytoken.TYPE_COMMA:
+ break;
+ case Yytoken.TYPE_VALUE:
+ if (token.value instanceof String)
+ {
+ String key = (String) token.value;
+ status = S_PASSED_PAIR_KEY;
+ statusStack.addFirst(new Integer(status));
+ if (!contentHandler.startObjectEntry(key))
+ return;
+ }
+ else
+ {
+ status = S_IN_ERROR;
+ }
+ break;
+ case Yytoken.TYPE_RIGHT_BRACE:
+ if (statusStack.size() > 1)
+ {
+ statusStack.removeFirst();
+ status = peekStatus(statusStack);
+ }
+ else
+ {
+ status = S_IN_FINISHED_VALUE;
+ }
+ if (!contentHandler.endObject())
+ return;
+ break;
+ default:
+ status = S_IN_ERROR;
+ break;
+ }// inner switch
+ break;
+
+ case S_PASSED_PAIR_KEY:
+ nextToken();
+ switch (token.type)
+ {
+ case Yytoken.TYPE_COLON:
+ break;
+ case Yytoken.TYPE_VALUE:
+ statusStack.removeFirst();
+ status = peekStatus(statusStack);
+ if (!contentHandler.primitive(token.value))
+ return;
+ if (!contentHandler.endObjectEntry())
+ return;
+ break;
+ case Yytoken.TYPE_LEFT_SQUARE:
+ statusStack.removeFirst();
+ statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
+ status = S_IN_ARRAY;
+ statusStack.addFirst(new Integer(status));
+ if (!contentHandler.startArray())
+ return;
+ break;
+ case Yytoken.TYPE_LEFT_BRACE:
+ statusStack.removeFirst();
+ statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
+ status = S_IN_OBJECT;
+ statusStack.addFirst(new Integer(status));
+ if (!contentHandler.startObject())
+ return;
+ break;
+ default:
+ status = S_IN_ERROR;
+ }
+ break;
+
+ case S_IN_PAIR_VALUE:
+ /*
+ * S_IN_PAIR_VALUE is just a marker to indicate the end of an object entry, it doesn't proccess any token,
+ * therefore delay consuming token until next round.
+ */
+ statusStack.removeFirst();
+ status = peekStatus(statusStack);
+ if (!contentHandler.endObjectEntry())
+ return;
+ break;
+
+ case S_IN_ARRAY:
+ nextToken();
+ switch (token.type)
+ {
+ case Yytoken.TYPE_COMMA:
+ break;
+ case Yytoken.TYPE_VALUE:
+ if (!contentHandler.primitive(token.value))
+ return;
+ break;
+ case Yytoken.TYPE_RIGHT_SQUARE:
+ if (statusStack.size() > 1)
+ {
+ statusStack.removeFirst();
+ status = peekStatus(statusStack);
+ }
+ else
+ {
+ status = S_IN_FINISHED_VALUE;
+ }
+ if (!contentHandler.endArray())
+ return;
+ break;
+ case Yytoken.TYPE_LEFT_BRACE:
+ status = S_IN_OBJECT;
+ statusStack.addFirst(new Integer(status));
+ if (!contentHandler.startObject())
+ return;
+ break;
+ case Yytoken.TYPE_LEFT_SQUARE:
+ status = S_IN_ARRAY;
+ statusStack.addFirst(new Integer(status));
+ if (!contentHandler.startArray())
+ return;
+ break;
+ default:
+ status = S_IN_ERROR;
+ }// inner switch
+ break;
+
+ case S_END:
+ return;
+
+ case S_IN_ERROR:
+ throw new ParseException(getPosition(),
+ ParseException.ERROR_UNEXPECTED_TOKEN, token);
+ }// switch
+ if (status == S_IN_ERROR)
+ {
+ throw new ParseException(getPosition(),
+ ParseException.ERROR_UNEXPECTED_TOKEN, token);
+ }
+ } while (token.type != Yytoken.TYPE_EOF);
+ } catch (IOException ie)
+ {
+ status = S_IN_ERROR;
+ throw ie;
+ } catch (ParseException pe)
+ {
+ status = S_IN_ERROR;
+ throw pe;
+ } catch (RuntimeException re)
+ {
+ status = S_IN_ERROR;
+ throw re;
+ } catch (Error e)
+ {
+ status = S_IN_ERROR;
+ throw e;
+ }
+
+ status = S_IN_ERROR;
+ throw new ParseException(getPosition(),
+ ParseException.ERROR_UNEXPECTED_TOKEN, token);
+ }
}
int j = offset; /* index in unpacked array */
int l = packed.length();
while (i < l) {
- int high = packed.charAt(i++) << 16;
- result[j++] = high | packed.charAt(i++);
+ int high = packed.codePointAt(i++) << 16;
+ result[j++] = high | packed.codePointAt(i++);
}
return j;
}
/**
- * Resumes scanning until the next regular expression is matched,
- * the end of input is encountered or an I/O-Error occurs.
+ * Resumes scanning until the next regular expression is matched, the end of
+ * input is encountered or an I/O-Error occurs.
*
- * @return the next token
- * @exception java.io.IOException if any I/O-Error occurs
+ * @return the next token
+ * @exception java.io.IOException
+ * if any I/O-Error occurs
*/
- public Yytoken yylex() throws java.io.IOException, ParseException {
+ public Yytoken yylex() throws java.io.IOException, ParseException
+ {
int zzInput;
int zzAction;
int zzCurrentPosL;
int zzMarkedPosL;
int zzEndReadL = zzEndRead;
- char [] zzBufferL = zzBuffer;
- char [] zzCMapL = ZZ_CMAP;
+ char[] zzBufferL = zzBuffer;
+ char[] zzCMapL = ZZ_CMAP;
- int [] zzTransL = ZZ_TRANS;
- int [] zzRowMapL = ZZ_ROWMAP;
- int [] zzAttrL = ZZ_ATTRIBUTE;
+ int[] zzTransL = ZZ_TRANS;
+ int[] zzRowMapL = ZZ_ROWMAP;
+ int[] zzAttrL = ZZ_ATTRIBUTE;
- while (true) {
+ while (true)
+ {
zzMarkedPosL = zzMarkedPos;
- yychar+= zzMarkedPosL-zzStartRead;
+ yychar += zzMarkedPosL - zzStartRead;
zzAction = -1;
zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;
-
+
zzState = ZZ_LEXSTATE[zzLexicalState];
+ zzForAction:
+ {
+ while (true)
+ {
- zzForAction: {
- while (true) {
-
if (zzCurrentPosL < zzEndReadL)
zzInput = zzBufferL[zzCurrentPosL++];
- else if (zzAtEOF) {
+ else if (zzAtEOF)
+ {
zzInput = YYEOF;
break zzForAction;
}
- else {
+ else
+ {
// store back cached positions
- zzCurrentPos = zzCurrentPosL;
- zzMarkedPos = zzMarkedPosL;
+ zzCurrentPos = zzCurrentPosL;
+ zzMarkedPos = zzMarkedPosL;
boolean eof = zzRefill();
// get translated positions and possibly new buffer
- zzCurrentPosL = zzCurrentPos;
- zzMarkedPosL = zzMarkedPos;
- zzBufferL = zzBuffer;
- zzEndReadL = zzEndRead;
- if (eof) {
+ zzCurrentPosL = zzCurrentPos;
+ zzMarkedPosL = zzMarkedPos;
+ zzBufferL = zzBuffer;
+ zzEndReadL = zzEndRead;
+ if (eof)
+ {
zzInput = YYEOF;
break zzForAction;
}
- else {
+ else
+ {
zzInput = zzBufferL[zzCurrentPosL++];
}
}
- int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];
- if (zzNext == -1) break zzForAction;
+ int zzNext = zzTransL[zzRowMapL[zzState] + zzCMapL[zzInput]];
+ if (zzNext == -1)
+ break zzForAction;
zzState = zzNext;
int zzAttributes = zzAttrL[zzState];
- if ( (zzAttributes & 1) == 1 ) {
+ if ((zzAttributes & 1) == 1)
+ {
zzAction = zzState;
zzMarkedPosL = zzCurrentPosL;
- if ( (zzAttributes & 8) == 8 ) break zzForAction;
+ if ((zzAttributes & 8) == 8)
+ break zzForAction;
}
}
// store back cached position
zzMarkedPos = zzMarkedPosL;
-
- switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
- case 11:
- { sb.append(yytext());
- }
- case 25: break;
- case 4:
- { sb = null; sb = new StringBuffer(); yybegin(STRING_BEGIN);
- }
- case 26: break;
- case 16:
- { sb.append('\b');
- }
- case 27: break;
- case 6:
- { return new Yytoken(Yytoken.TYPE_RIGHT_BRACE,null);
- }
- case 28: break;
- case 23:
- { Boolean val=Boolean.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE, val);
- }
- case 29: break;
- case 22:
- { return new Yytoken(Yytoken.TYPE_VALUE, null);
- }
- case 30: break;
- case 13:
- { yybegin(YYINITIAL);return new Yytoken(Yytoken.TYPE_VALUE, sb.toString());
- }
- case 31: break;
- case 12:
- { sb.append('\\');
- }
- case 32: break;
- case 21:
- { Double val=Double.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE, val);
- }
- case 33: break;
- case 1:
- { throw new ParseException(yychar, ParseException.ERROR_UNEXPECTED_CHAR, new Character(yycharat(0)));
- }
- case 34: break;
- case 8:
- { return new Yytoken(Yytoken.TYPE_RIGHT_SQUARE,null);
- }
- case 35: break;
- case 19:
- { sb.append('\r');
- }
- case 36: break;
- case 15:
- { sb.append('/');
- }
- case 37: break;
- case 10:
- { return new Yytoken(Yytoken.TYPE_COLON,null);
- }
- case 38: break;
- case 14:
- { sb.append('"');
- }
- case 39: break;
- case 5:
- { return new Yytoken(Yytoken.TYPE_LEFT_BRACE,null);
- }
- case 40: break;
- case 17:
- { sb.append('\f');
- }
- case 41: break;
- case 24:
- { try{
- int ch=Integer.parseInt(yytext().substring(2),16);
- sb.append((char)ch);
- }
- catch(Exception e){
- throw new ParseException(yychar, ParseException.ERROR_UNEXPECTED_EXCEPTION, e);
- }
- }
- case 42: break;
- case 20:
- { sb.append('\t');
- }
- case 43: break;
- case 7:
- { return new Yytoken(Yytoken.TYPE_LEFT_SQUARE,null);
- }
- case 44: break;
- case 2:
- { Long val=Long.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE, val);
- }
- case 45: break;
- case 18:
- { sb.append('\n');
- }
- case 46: break;
- case 9:
- { return new Yytoken(Yytoken.TYPE_COMMA,null);
- }
- case 47: break;
- case 3:
- {
- }
- case 48: break;
- default:
- if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
- zzAtEOF = true;
- return null;
- }
- else {
- zzScanError(ZZ_NO_MATCH);
- }
+ switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction])
+ {
+ case 11:
+ {
+ sb.append(yytext());
+ }
+ case 25:
+ break;
+ case 4:
+ {
+ sb = null;
+ sb = new StringBuffer();
+ yybegin(STRING_BEGIN);
+ }
+ case 26:
+ break;
+ case 16:
+ {
+ sb.append('\b');
+ }
+ case 27:
+ break;
+ case 6:
+ {
+ return new Yytoken(Yytoken.TYPE_RIGHT_BRACE, null);
+ }
+ case 28:
+ break;
+ case 23:
+ {
+ Boolean val = Boolean.valueOf(yytext());
+ return new Yytoken(Yytoken.TYPE_VALUE, val);
+ }
+ case 29:
+ break;
+ case 22:
+ {
+ return new Yytoken(Yytoken.TYPE_VALUE, null);
+ }
+ case 30:
+ break;
+ case 13:
+ {
+ yybegin(YYINITIAL);
+ return new Yytoken(Yytoken.TYPE_VALUE, sb.toString());
+ }
+ case 31:
+ break;
+ case 12:
+ {
+ sb.append('\\');
+ }
+ case 32:
+ break;
+ case 21:
+ {
+ Double val = Double.valueOf(yytext());
+ return new Yytoken(Yytoken.TYPE_VALUE, val);
+ }
+ case 33:
+ break;
+ case 1:
+ {
+ throw new ParseException(yychar,
+ ParseException.ERROR_UNEXPECTED_CHAR,
+ new Character(yycharat(0)));
+ }
+ case 34:
+ break;
+ case 8:
+ {
+ return new Yytoken(Yytoken.TYPE_RIGHT_SQUARE, null);
+ }
+ case 35:
+ break;
+ case 19:
+ {
+ sb.append('\r');
+ }
+ case 36:
+ break;
+ case 15:
+ {
+ sb.append('/');
+ }
+ case 37:
+ break;
+ case 10:
+ {
+ return new Yytoken(Yytoken.TYPE_COLON, null);
+ }
+ case 38:
+ break;
+ case 14:
+ {
+ sb.append('"');
+ }
+ case 39:
+ break;
+ case 5:
+ {
+ return new Yytoken(Yytoken.TYPE_LEFT_BRACE, null);
+ }
+ case 40:
+ break;
+ case 17:
+ {
+ sb.append('\f');
+ }
+ case 41:
+ break;
+ case 24:
+ {
+ try
+ {
+ int ch = Integer.parseInt(yytext().substring(2), 16);
+ sb.append((char) ch);
+ } catch (Exception e)
+ {
+ throw new ParseException(yychar,
+ ParseException.ERROR_UNEXPECTED_EXCEPTION, e);
+ }
+ }
+ case 42:
+ break;
+ case 20:
+ {
+ sb.append('\t');
+ }
+ case 43:
+ break;
+ case 7:
+ {
+ return new Yytoken(Yytoken.TYPE_LEFT_SQUARE, null);
+ }
+ case 44:
+ break;
+ case 2:
+ {
+ Long val = Long.valueOf(yytext());
+ return new Yytoken(Yytoken.TYPE_VALUE, val);
+ }
+ case 45:
+ break;
+ case 18:
+ {
+ sb.append('\n');
+ }
+ case 46:
+ break;
+ case 9:
+ {
+ return new Yytoken(Yytoken.TYPE_COMMA, null);
+ }
+ case 47:
+ break;
+ case 3:
+ {
+ }
+ case 48:
+ break;
+ default:
+ if (zzInput == YYEOF && zzStartRead == zzCurrentPos)
+ {
+ zzAtEOF = true;
+ return null;
+ }
+ else
+ {
+ zzScanError(ZZ_NO_MATCH);
+ }
}
}
}