Skip to content

Instantly share code, notes, and snippets.

@liuqinh2s
Last active January 30, 2019 02:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save liuqinh2s/9cdae8d5d6e476259d82d92c7da1cb93 to your computer and use it in GitHub Desktop.
Save liuqinh2s/9cdae8d5d6e476259d82d92c7da1cb93 to your computer and use it in GitHub Desktop.
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