Last active
January 30, 2019 02:50
-
-
Save liuqinh2s/9cdae8d5d6e476259d82d92c7da1cb93 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
public class JsonParser { | |
private String json; | |
private int index = 0; | |
private Map<Character, Boolean> numChars = new HashMap<>(); | |
public Object parse(String json) throws Exception { | |
char[] chars = {'-', '+', 'e', 'E', '.'}; | |
for (char c : chars) { | |
numChars.put(c, true); | |
} | |
this.json = json.trim(); | |
return parseValue(); | |
} | |
private Object parseValue() throws Exception { | |
ignoreWhiteSpace(); | |
switch (json.charAt(index)) { | |
case '{': | |
return parseObject(); | |
case '[': | |
return parseArray(); | |
case 'n': | |
case 'N': | |
return parseNull(); | |
case 't': | |
case 'T': | |
return parseTrue(); | |
case 'f': | |
case 'F': | |
return parseFalse(); | |
case '"': | |
case '\'': | |
return parseString(); | |
default: | |
return parseNumber(); | |
} | |
} | |
private Map parseObject() throws Exception { | |
index++; | |
ignoreWhiteSpace(); | |
Map<String, Object> map = new HashMap<>(); | |
while (index < json.length() && json.charAt(index) != '}') { | |
String key = parseString(); | |
ignoreWhiteSpace(); | |
if (json.charAt(index++) != ':') { | |
throw new Exception("illegal json string, while parsing :"); | |
} | |
Object value = parseValue(); | |
map.put(key, value); | |
ignoreWhiteSpace(); | |
if (json.charAt(index) == ',') { | |
index++; | |
} | |
ignoreWhiteSpace(); | |
} | |
if (json.charAt(index++) != '}') { | |
throw new Exception("illegal json string, while parsing object"); | |
} | |
return map; | |
} | |
private List parseArray() throws Exception { | |
index++; | |
ignoreWhiteSpace(); | |
List<Object> arrayList = new ArrayList<>(); | |
while (index < json.length() && json.charAt(index) != ']') { | |
arrayList.add(parseValue()); | |
if (json.charAt(index) == ',') { | |
index++; | |
} | |
ignoreWhiteSpace(); | |
} | |
if (json.charAt(index++) != ']') { | |
throw new Exception("illegal json string, while parsing array"); | |
} | |
return arrayList; | |
} | |
private Object parseNull() throws Exception { | |
if (json.substring(index, index + 4).equals("null")) { | |
index += 4; | |
return null; | |
} else { | |
throw new Exception("illegal json string, while parsing null"); | |
} | |
} | |
private Boolean parseTrue() throws Exception { | |
if (json.substring(index, index + 4).equals("true") || json.substring(index, index + 4).equals("True")) { | |
index += 4; | |
return true; | |
} else { | |
throw new Exception("illegal json string, while parsing true"); | |
} | |
} | |
private Boolean parseFalse() throws Exception { | |
if (json.substring(index, index + 5).equals("false") || json.substring(index, index + 5).equals("False")) { | |
index += 5; | |
return false; | |
} else { | |
throw new Exception("illegal json string, while parsing false"); | |
} | |
} | |
private String parseString() throws Exception { | |
char firstChar = json.charAt(index); | |
index++; | |
int recordIndex = index; | |
for (; index < json.length() && json.charAt(index) != firstChar; index++) { | |
if (json.charAt(index) == '\\') { | |
if (json.charAt(index + 1) == 'u') { | |
index += 5; | |
} else { | |
index++; | |
} | |
} | |
} | |
if (json.charAt(index) != firstChar) { | |
throw new Exception("illegal json string, while parsing string"); | |
} | |
return json.substring(recordIndex, index++); | |
} | |
private Object parseNumber() throws Exception { | |
ignoreWhiteSpace(); | |
int recordIndex = index; | |
boolean hasDot = false; | |
while (index < json.length() && isNumberChar(json.charAt(index))) { | |
if(json.charAt(index)=='.'){ | |
hasDot = true; | |
} | |
index++; | |
} | |
ignoreWhiteSpace(); | |
return hasDot?Double.parseDouble(json.substring(recordIndex, index)):Integer.parseInt(json.substring(recordIndex, index)); | |
} | |
private void ignoreWhiteSpace() throws Exception { | |
while (index < json.length()) { | |
if (json.charAt(index) <= ' ') { | |
index++; | |
} else { | |
break; | |
} | |
} | |
if (index >= json.length()) { | |
throw new Exception("illegal json string, while parsing value ArrayIndexOutOfBounds"); | |
} | |
} | |
private Boolean isNumberChar(char c) { | |
return numChars.get(c) != null || c <= '9' && c >= '0'; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment