aboutsummaryrefslogtreecommitdiff
path: root/src/org/json/simple/parser/JSONParser.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/json/simple/parser/JSONParser.java')
-rw-r--r--src/org/json/simple/parser/JSONParser.java544
1 files changed, 544 insertions, 0 deletions
diff --git a/src/org/json/simple/parser/JSONParser.java b/src/org/json/simple/parser/JSONParser.java
new file mode 100644
index 0000000..4874eea
--- /dev/null
+++ b/src/org/json/simple/parser/JSONParser.java
@@ -0,0 +1,544 @@
1/*
2 * $Id: JSONParser.java,v 1.1 2006/04/15 14:10:48 platform Exp $
3 * Created on 2006-4-15
4 */
5package org.json.simple.parser;
6
7import java.io.IOException;
8import java.util.LinkedList;
9import java.util.List;
10import java.util.Map;
11
12import org.json.simple.JSONArray;
13import org.json.simple.JSONObject;
14
15import rejava.io.Reader;
16import rejava.io.StringReader;
17
18/**
19 * Parser for JSON text. Please note that JSONParser is NOT thread-safe.
20 *
21 * @author FangYidong<fangyidong@yahoo.com.cn>
22 */
23public class JSONParser {
24 public static final int S_INIT = 0;
25 public static final int S_IN_FINISHED_VALUE = 1;// string,number,boolean,null,object,array
26 public static final int S_IN_OBJECT = 2;
27 public static final int S_IN_ARRAY = 3;
28 public static final int S_PASSED_PAIR_KEY = 4;
29 public static final int S_IN_PAIR_VALUE = 5;
30 public static final int S_END = 6;
31 public static final int S_IN_ERROR = -1;
32
33 private LinkedList<?> handlerStatusStack;
34 private final Yylex lexer = new Yylex((Reader) null);
35 private Yytoken token = null;
36 private int status = JSONParser.S_INIT;
37
38 private int peekStatus(final LinkedList<?> statusStack) {
39 if (statusStack.size() == 0) {
40 return -1;
41 }
42 final Integer status = (Integer) statusStack.getFirst();
43 return status.intValue();
44 }
45
46 /**
47 * Reset the parser to the initial state without resetting the underlying
48 * reader.
49 *
50 */
51 public void reset() {
52 this.token = null;
53 this.status = JSONParser.S_INIT;
54 this.handlerStatusStack = null;
55 }
56
57 /**
58 * Reset the parser to the initial state with a new character reader.
59 *
60 * @param in
61 * - The new character reader.
62 * @throws IOException
63 * @throws ParseException
64 */
65 public void reset(final Reader in) {
66 this.lexer.yyreset(in);
67 this.reset();
68 }
69
70 /**
71 * @return The position of the beginning of the current token.
72 */
73 public int getPosition() {
74 return this.lexer.getPosition();
75 }
76
77 public Object parse(final String s) throws ParseException {
78 return this.parse(s, (ContainerFactory) null);
79 }
80
81 public Object parse(final String s, final ContainerFactory containerFactory) throws ParseException {
82 final StringReader in = new StringReader(s);
83 try {
84 return this.parse(in, containerFactory);
85 } catch (final IOException ie) {
86 /*
87 * Actually it will never happen.
88 */
89 throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
90 }
91 }
92
93 public Object parse(final Reader in) throws IOException, ParseException {
94 return this.parse(in, (ContainerFactory) null);
95 }
96
97 /**
98 * Parse JSON text into java object from the input source.
99 *
100 * @param in
101 * @param containerFactory
102 * - Use this factory to createyour own JSON object and JSON
103 * array containers.
104 * @return Instance of the following: org.json.simple.JSONObject,
105 * org.json.simple.JSONArray, java.lang.String, java.lang.Number,
106 * java.lang.Boolean, null
107 *
108 * @throws IOException
109 * @throws ParseException
110 */
111 @SuppressWarnings({ "rawtypes", "unchecked" })
112 public Object parse(final Reader in, final ContainerFactory containerFactory) throws IOException, ParseException {
113 this.reset(in);
114 final LinkedList statusStack = new LinkedList();
115 final LinkedList valueStack = new LinkedList();
116
117 try {
118 do {
119 this.nextToken();
120 switch (this.status) {
121 case S_INIT:
122 switch (this.token.type) {
123 case Yytoken.TYPE_VALUE:
124 this.status = JSONParser.S_IN_FINISHED_VALUE;
125 statusStack.addFirst(new Integer(this.status));
126 valueStack.addFirst(this.token.value);
127 break;
128 case Yytoken.TYPE_LEFT_BRACE:
129 this.status = JSONParser.S_IN_OBJECT;
130 statusStack.addFirst(new Integer(this.status));
131 valueStack.addFirst(this.createObjectContainer(containerFactory));
132 break;
133 case Yytoken.TYPE_LEFT_SQUARE:
134 this.status = JSONParser.S_IN_ARRAY;
135 statusStack.addFirst(new Integer(this.status));
136 valueStack.addFirst(this.createArrayContainer(containerFactory));
137 break;
138 default:
139 this.status = JSONParser.S_IN_ERROR;
140 }// inner switch
141 break;
142
143 case S_IN_FINISHED_VALUE:
144 if (this.token.type == Yytoken.TYPE_EOF) {
145 return valueStack.removeFirst();
146 } else {
147 throw new ParseException(this.getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, this.token);
148 }
149
150 case S_IN_OBJECT:
151 switch (this.token.type) {
152 case Yytoken.TYPE_COMMA:
153 break;
154 case Yytoken.TYPE_VALUE:
155 if (this.token.value instanceof String) {
156 final String key = (String) this.token.value;
157 valueStack.addFirst(key);
158 this.status = JSONParser.S_PASSED_PAIR_KEY;
159 statusStack.addFirst(new Integer(this.status));
160 } else {
161 this.status = JSONParser.S_IN_ERROR;
162 }
163 break;
164 case Yytoken.TYPE_RIGHT_BRACE:
165 if (valueStack.size() > 1) {
166 statusStack.removeFirst();
167 valueStack.removeFirst();
168 this.status = this.peekStatus(statusStack);
169 } else {
170 this.status = JSONParser.S_IN_FINISHED_VALUE;
171 }
172 break;
173 default:
174 this.status = JSONParser.S_IN_ERROR;
175 break;
176 }// inner switch
177 break;
178
179 case S_PASSED_PAIR_KEY:
180 switch (this.token.type) {
181 case Yytoken.TYPE_COLON:
182 break;
183 case Yytoken.TYPE_VALUE:
184 statusStack.removeFirst();
185 String key = (String) valueStack.removeFirst();
186 Map parent = (Map) valueStack.getFirst();
187 parent.put(key, this.token.value);
188 this.status = this.peekStatus(statusStack);
189 break;
190 case Yytoken.TYPE_LEFT_SQUARE:
191 statusStack.removeFirst();
192 key = (String) valueStack.removeFirst();
193 parent = (Map) valueStack.getFirst();
194 final List newArray = this.createArrayContainer(containerFactory);
195 parent.put(key, newArray);
196 this.status = JSONParser.S_IN_ARRAY;
197 statusStack.addFirst(new Integer(this.status));
198 valueStack.addFirst(newArray);
199 break;
200 case Yytoken.TYPE_LEFT_BRACE:
201 statusStack.removeFirst();
202 key = (String) valueStack.removeFirst();
203 parent = (Map) valueStack.getFirst();
204 final Map newObject = this.createObjectContainer(containerFactory);
205 parent.put(key, newObject);
206 this.status = JSONParser.S_IN_OBJECT;
207 statusStack.addFirst(new Integer(this.status));
208 valueStack.addFirst(newObject);