1 | /* |
---|
2 | * STANDARD ML OF NEW JERSEY COPYRIGHT NOTICE, LICENSE AND DISCLAIMER. |
---|
3 | * |
---|
4 | * Copyright (c) 1989-1998 by Lucent Technologies |
---|
5 | * |
---|
6 | * Permission to use, copy, modify, and distribute this software and its |
---|
7 | * documentation for any purpose and without fee is hereby granted, provided |
---|
8 | * that the above copyright notice appear in all copies and that both the |
---|
9 | * copyright notice and this permission notice and warranty disclaimer appear |
---|
10 | * in supporting documentation, and that the name of Lucent Technologies, Bell |
---|
11 | * Labs or any Lucent entity not be used in advertising or publicity pertaining |
---|
12 | * to distribution of the software without specific, written prior permission. |
---|
13 | * |
---|
14 | * Lucent disclaims all warranties with regard to this software, including all |
---|
15 | * implied warranties of merchantability and fitness. In no event shall Lucent |
---|
16 | * be liable for any special, indirect or consequential damages or any damages |
---|
17 | * whatsoever resulting from loss of use, data or profits, whether in an action |
---|
18 | * of contract, negligence or other tortious action, arising out of or in |
---|
19 | * connection with the use or performance of this software. |
---|
20 | * |
---|
21 | * Taken from this URL: |
---|
22 | * http://www.smlnj.org/license.html |
---|
23 | * |
---|
24 | * This license is compatible with the GNU GPL (see section "Standard ML of New |
---|
25 | * Jersey Copyright License"): |
---|
26 | * http://www.gnu.org/licenses/license-list.html#StandardMLofNJ |
---|
27 | */ |
---|
28 | |
---|
29 | /* |
---|
30 | * Copyright 1996-1999 by Scott Hudson, Frank Flannery, C. Scott Ananian |
---|
31 | */ |
---|
32 | |
---|
33 | package weka.core.json; |
---|
34 | |
---|
35 | import java_cup.runtime.*; |
---|
36 | |
---|
37 | import java.io.*; |
---|
38 | import java.util.*; |
---|
39 | |
---|
40 | /** |
---|
41 | * A parser for parsing JSON files. |
---|
42 | * |
---|
43 | * @author FracPete (fracpete at waikato dot ac dot nz) |
---|
44 | * @version $Revision: 5785 $ |
---|
45 | */ |
---|
46 | |
---|
47 | parser code {: |
---|
48 | /** variable - value relation. */ |
---|
49 | protected HashMap m_Symbols; |
---|
50 | |
---|
51 | /** for storing the parsed JSON data structure. */ |
---|
52 | protected JSONNode m_Result; |
---|
53 | |
---|
54 | /** the stack for keeping track of the current parent node. */ |
---|
55 | protected Stack<JSONNode> m_Stack; |
---|
56 | |
---|
57 | /** |
---|
58 | * Returns the JSON data structure. |
---|
59 | * |
---|
60 | * @return the result |
---|
61 | */ |
---|
62 | public JSONNode getResult() { |
---|
63 | return m_Result; |
---|
64 | } |
---|
65 | |
---|
66 | /** |
---|
67 | * Returns the stack used internally for keeping track of the current |
---|
68 | * parent node. |
---|
69 | * |
---|
70 | * @return the stack |
---|
71 | */ |
---|
72 | protected Stack<JSONNode> getStack() { |
---|
73 | return m_Stack; |
---|
74 | } |
---|
75 | |
---|
76 | /** |
---|
77 | * Runs the parser from commandline. Expects a filename as first parameter, |
---|
78 | * pointing to a JSON file. |
---|
79 | * |
---|
80 | * @param args the commandline arguments |
---|
81 | * @throws Exception if something goes wrong |
---|
82 | */ |
---|
83 | public static void main(String args[]) throws Exception { |
---|
84 | if (args.length != 1) { |
---|
85 | System.err.println("No JSON file specified!"); |
---|
86 | System.exit(1); |
---|
87 | } |
---|
88 | |
---|
89 | FileInputStream stream = new FileInputStream(args[0]); |
---|
90 | SymbolFactory sf = new DefaultSymbolFactory(); |
---|
91 | Parser parser = new Parser(new Scanner(stream, sf), sf); |
---|
92 | parser.parse(); |
---|
93 | StringBuffer buffer = new StringBuffer(); |
---|
94 | parser.getResult().toString(buffer); |
---|
95 | System.out.println(buffer.toString()); |
---|
96 | } |
---|
97 | :} |
---|
98 | |
---|
99 | init with {: |
---|
100 | m_Symbols = new HashMap(); |
---|
101 | m_Result = new JSONNode(); |
---|
102 | m_Stack = new Stack<JSONNode>(); |
---|
103 | m_Stack.push(m_Result); |
---|
104 | :} |
---|
105 | |
---|
106 | terminal COMMA; |
---|
107 | terminal LSQUARE; |
---|
108 | terminal RSQUARE; |
---|
109 | terminal LCURLY; |
---|
110 | terminal RCURLY; |
---|
111 | terminal COLON; |
---|
112 | terminal NULL; |
---|
113 | terminal Boolean BOOLEAN; |
---|
114 | terminal Integer INTEGER; |
---|
115 | terminal Double DOUBLE; |
---|
116 | terminal String STRING; |
---|
117 | |
---|
118 | non terminal json; |
---|
119 | non terminal pairs; |
---|
120 | non terminal pair; |
---|
121 | non terminal primitive; |
---|
122 | non terminal null; |
---|
123 | non terminal Boolean boolean; |
---|
124 | non terminal Integer integer; |
---|
125 | non terminal Double double; |
---|
126 | non terminal String string; |
---|
127 | non terminal anon_object; |
---|
128 | non terminal named_object; |
---|
129 | non terminal named_object_start; |
---|
130 | non terminal anon_object_start; |
---|
131 | non terminal object_content; |
---|
132 | non terminal object_end; |
---|
133 | non terminal anon_array; |
---|
134 | non terminal named_array; |
---|
135 | non terminal named_array_start; |
---|
136 | non terminal anon_array_start; |
---|
137 | non terminal array_content; |
---|
138 | non terminal array_end; |
---|
139 | non terminal elements; |
---|
140 | non terminal element; |
---|
141 | |
---|
142 | json ::= LCURLY RCURLY |
---|
143 | | LCURLY pairs RCURLY |
---|
144 | ; |
---|
145 | |
---|
146 | pairs ::= pairs COMMA pair |
---|
147 | | pair |
---|
148 | ; |
---|
149 | |
---|
150 | pair ::= primitive |
---|
151 | | named_object |
---|
152 | | named_array |
---|
153 | ; |
---|
154 | |
---|
155 | primitive ::= null |
---|
156 | | boolean |
---|
157 | | integer |
---|
158 | | double |
---|
159 | | string |
---|
160 | ; |
---|
161 | |
---|
162 | null ::= STRING:name COLON NULL |
---|
163 | {: |
---|
164 | parser.getStack().peek().addNull(name); |
---|
165 | :} |
---|
166 | ; |
---|
167 | |
---|
168 | boolean ::= STRING:name COLON BOOLEAN:b |
---|
169 | {: |
---|
170 | parser.getStack().peek().addPrimitive(name, b); |
---|
171 | :} |
---|
172 | ; |
---|
173 | |
---|
174 | integer ::= STRING:name COLON INTEGER:i |
---|
175 | {: |
---|
176 | parser.getStack().peek().addPrimitive(name, i); |
---|
177 | :} |
---|
178 | ; |
---|
179 | |
---|
180 | double ::= STRING:name COLON DOUBLE:d |
---|
181 | {: |
---|
182 | parser.getStack().peek().addPrimitive(name, d); |
---|
183 | :} |
---|
184 | ; |
---|
185 | |
---|
186 | string ::= STRING:name COLON STRING:s |
---|
187 | {: |
---|
188 | parser.getStack().peek().addPrimitive(name, s); |
---|
189 | :} |
---|
190 | ; |
---|
191 | |
---|
192 | named_object ::= named_object_start object_end |
---|
193 | | named_object_start object_content object_end |
---|
194 | ; |
---|
195 | |
---|
196 | named_object_start ::= STRING:name COLON LCURLY |
---|
197 | {: |
---|
198 | JSONNode node = parser.getStack().peek().addObject(name); |
---|
199 | parser.getStack().push(node); |
---|
200 | :} |
---|
201 | ; |
---|
202 | |
---|
203 | anon_object ::= anon_object_start object_end |
---|
204 | | anon_object_start object_content object_end |
---|
205 | ; |
---|
206 | |
---|
207 | anon_object_start ::= LCURLY |
---|
208 | {: |
---|
209 | JSONNode node = parser.getStack().peek().addObject(null); |
---|
210 | parser.getStack().push(node); |
---|
211 | :} |
---|
212 | ; |
---|
213 | |
---|
214 | object_content ::= pairs |
---|
215 | ; |
---|
216 | |
---|
217 | object_end ::= RCURLY |
---|
218 | {: |
---|
219 | parser.getStack().pop(); |
---|
220 | :} |
---|
221 | ; |
---|
222 | |
---|
223 | named_array ::= named_array_start array_end |
---|
224 | | named_array_start array_content array_end |
---|
225 | ; |
---|
226 | |
---|
227 | named_array_start ::= STRING:name COLON LSQUARE |
---|
228 | {: |
---|
229 | JSONNode node = parser.getStack().peek().addArray(name); |
---|
230 | parser.getStack().push(node); |
---|
231 | :} |
---|
232 | ; |
---|
233 | |
---|
234 | anon_array ::= anon_array_start array_end |
---|
235 | | anon_array_start array_content array_end |
---|
236 | ; |
---|
237 | |
---|
238 | anon_array_start ::= LSQUARE |
---|
239 | {: |
---|
240 | JSONNode node = parser.getStack().peek().addArray(null); |
---|
241 | parser.getStack().push(node); |
---|
242 | :} |
---|
243 | ; |
---|
244 | |
---|
245 | array_content ::= elements |
---|
246 | ; |
---|
247 | |
---|
248 | array_end ::= RSQUARE |
---|
249 | {: |
---|
250 | parser.getStack().pop(); |
---|
251 | :} |
---|
252 | ; |
---|
253 | |
---|
254 | elements ::= elements COMMA element |
---|
255 | | element |
---|
256 | ; |
---|
257 | |
---|
258 | element ::= NULL |
---|
259 | {: |
---|
260 | parser.getStack().peek().addArrayElement(null); |
---|
261 | :} |
---|
262 | | BOOLEAN:b |
---|
263 | {: |
---|
264 | parser.getStack().peek().addArrayElement(b); |
---|
265 | :} |
---|
266 | | INTEGER:i |
---|
267 | {: |
---|
268 | parser.getStack().peek().addArrayElement(i); |
---|
269 | :} |
---|
270 | | DOUBLE:d |
---|
271 | {: |
---|
272 | parser.getStack().peek().addArrayElement(d); |
---|
273 | :} |
---|
274 | | STRING:s |
---|
275 | {: |
---|
276 | parser.getStack().peek().addArrayElement(s); |
---|
277 | :} |
---|
278 | | anon_object |
---|
279 | | anon_array |
---|
280 | ; |
---|