001: /*
002: * $Id: JSONParser.java,v 1.1 2006/04/15 14:10:48 platform Exp $
003: * Created on 2006-4-15
004: */
005: package org.zkforge.json.simple.parser;
006:
007: import java.io.Reader;
008: import java.util.Stack;
009:
010: import org.zkforge.json.simple.JSONArray;
011: import org.zkforge.json.simple.JSONObject;
012:
013: /**
014: * @author FangYidong<fangyidong@yahoo.com.cn>
015: */
016: public class JSONParser {
017: public static final int S_INIT = 0;
018: public static final int S_IN_FINISHED_VALUE = 1;//string,number,boolean,null,object,array
019: public static final int S_IN_OBJECT = 2;
020: public static final int S_IN_ARRAY = 3;
021: public static final int S_PASSED_PAIR_KEY = 4;
022: public static final int S_IN_ERROR = -1;
023:
024: private int peekStatus(Stack statusStack) {
025: if (statusStack.size() == 0)
026: return -1;
027: Integer status = (Integer) statusStack.peek();
028: return status.intValue();
029: }
030:
031: public Object parse(Reader in) throws Exception {
032: Stack statusStack = new Stack();
033: Stack valueStack = new Stack();
034: Yylex lexer = new Yylex(in);
035: Yytoken token = null;
036: int status = S_INIT;
037:
038: try {
039: do {
040: token = lexer.yylex();
041: if (token == null)
042: token = new Yytoken(Yytoken.TYPE_EOF, null);
043: switch (status) {
044: case S_INIT:
045: switch (token.type) {
046: case Yytoken.TYPE_VALUE:
047: status = S_IN_FINISHED_VALUE;
048: statusStack.push(new Integer(status));
049: valueStack.push(token.value);
050: break;
051: case Yytoken.TYPE_LEFT_BRACE:
052: status = S_IN_OBJECT;
053: statusStack.push(new Integer(status));
054: valueStack.push(new JSONObject());
055: break;
056: case Yytoken.TYPE_LEFT_SQUARE:
057: status = S_IN_ARRAY;
058: statusStack.push(new Integer(status));
059: valueStack.push(new JSONArray());
060: break;
061: default:
062: status = S_IN_ERROR;
063: }//inner switch
064: break;
065:
066: case S_IN_FINISHED_VALUE:
067: if (token.type == Yytoken.TYPE_EOF)
068: return valueStack.pop();
069: else
070: return null;
071:
072: case S_IN_OBJECT:
073: switch (token.type) {
074: case Yytoken.TYPE_COMMA:
075: break;
076: case Yytoken.TYPE_VALUE:
077: if (token.value instanceof String) {
078: String key = (String) token.value;
079: valueStack.push(key);
080: status = S_PASSED_PAIR_KEY;
081: statusStack.push(new Integer(status));
082: } else {
083: status = S_IN_ERROR;
084: }
085: break;
086: case Yytoken.TYPE_RIGHT_BRACE:
087: if (valueStack.size() > 1) {
088: statusStack.pop();
089: valueStack.pop();
090: status = peekStatus(statusStack);
091: } else {
092: status = S_IN_FINISHED_VALUE;
093: }
094: break;
095: default:
096: status = S_IN_ERROR;
097: break;
098: }//inner switch
099: break;
100:
101: case S_PASSED_PAIR_KEY:
102: switch (token.type) {
103: case Yytoken.TYPE_COLON:
104: break;
105: case Yytoken.TYPE_VALUE:
106: statusStack.pop();
107: String key = (String) valueStack.pop();
108: JSONObject parent = (JSONObject) valueStack
109: .peek();
110: parent.put(key, token.value);
111: status = peekStatus(statusStack);
112: break;
113: case Yytoken.TYPE_LEFT_SQUARE:
114: statusStack.pop();
115: key = (String) valueStack.pop();
116: parent = (JSONObject) valueStack.peek();
117: JSONArray newArray = new JSONArray();
118: parent.put(key, newArray);
119: status = S_IN_ARRAY;
120: statusStack.push(new Integer(status));
121: valueStack.push(newArray);
122: break;
123: case Yytoken.TYPE_LEFT_BRACE:
124: statusStack.pop();
125: key = (String) valueStack.pop();
126: parent = (JSONObject) valueStack.peek();
127: JSONObject newObject = new JSONObject();
128: parent.put(key, newObject);
129: status = S_IN_OBJECT;
130: statusStack.push(new Integer(status));
131: valueStack.push(newObject);
132: break;
133: default:
134: status = S_IN_ERROR;
135: }
136: break;
137:
138: case S_IN_ARRAY:
139: switch (token.type) {
140: case Yytoken.TYPE_COMMA:
141: break;
142: case Yytoken.TYPE_VALUE:
143: JSONArray val = (JSONArray) valueStack.peek();
144: val.add(token.value);
145: break;
146: case Yytoken.TYPE_RIGHT_SQUARE:
147: if (valueStack.size() > 1) {
148: statusStack.pop();
149: valueStack.pop();
150: status = peekStatus(statusStack);
151: } else {
152: status = S_IN_FINISHED_VALUE;
153: }
154: break;
155: case Yytoken.TYPE_LEFT_BRACE:
156: val = (JSONArray) valueStack.peek();
157: JSONObject newObject = new JSONObject();
158: val.add(newObject);
159: status = S_IN_OBJECT;
160: statusStack.push(new Integer(status));
161: valueStack.push(newObject);
162: break;
163: case Yytoken.TYPE_LEFT_SQUARE:
164: val = (JSONArray) valueStack.peek();
165: JSONArray newArray = new JSONArray();
166: val.add(newArray);
167: status = S_IN_ARRAY;
168: statusStack.push(new Integer(status));
169: valueStack.push(newArray);
170: break;
171: default:
172: status = S_IN_ERROR;
173: }//inner switch
174: break;
175: case S_IN_ERROR:
176: return null;
177: }//switch
178: if (status == S_IN_ERROR)
179: return null;
180: } while (token.type != Yytoken.TYPE_EOF);
181: } catch (Exception e) {
182: throw e;
183: }
184: return null;
185: }
186: }
|