diff options
Diffstat (limited to 'src/org/json/simple/parser/JSONParser.java')
-rw-r--r-- | src/org/json/simple/parser/JSONParser.java | 544 |
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 | */ | ||
5 | package org.json.simple.parser; | ||
6 | |||
7 | import java.io.IOException; | ||
8 | import java.util.LinkedList; | ||
9 | import java.util.List; | ||
10 | import java.util.Map; | ||
11 | |||
12 | import org.json.simple.JSONArray; | ||
13 | import org.json.simple.JSONObject; | ||
14 | |||
15 | import rejava.io.Reader; | ||
16 | import 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 | */ | ||
23 | public 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); | ||