解析JsonValue
private static JsonValue ParseValue(ref Data data)
{
// 跳过空白字符
SkipWhiteSpace(ref data);
var c = data.json[data.index];
switch (c)
{
case '{':
// 表示Object
return ParseObject(ref data);
case '[':
// 表示Array
return ParseArray (ref data);
case '"':
// 表示string
return ParseString(ref data);
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
// 表示数值
return ParseNumber(ref data);
case 'f': // 表示可能是false
if
(
data.json[data.index + 1] == 'a' &&
data.json[data.index + 2] == 'l' &&
data.json[data.index + 3] == 's' &&
data.json[data.index + 4] == 'e'
)
{
data.index += 5;
// 表示是false
return new JsonValue(JsonType.Bool, false);
}
break;
case 't': // 表示可能是true
if
(
data.json[data.index + 1] == 'r' &&
data.json[data.index + 2] == 'u' &&
data.json[data.index + 3] == 'e'
)
{
data.index += 4;
// 表示是true
return new JsonValue(JsonType.Bool, true);
}
break;
case 'n': // 表示可能是null
if
(
data.json[data.index + 1] == 'u' &&
data.json[data.index + 2] == 'l' &&
data.json[data.index + 3] == 'l'
)
{
data.index += 4;
// 表示可能是null
return new JsonValue(JsonType.Null, null);
}
break;
}
// 不能处理了
throw new Exception(string.Format("Json ParseValue error on char '{0}' index in '{1}' ", c, data.index));
}
ParseValue是解析的主入口,代表着解析JsonValue这个抽象的JSON值,其真实的类型在解析的过程中逐渐具体化。
在剥离掉空白字符之后,就可以很容易的通过单个字符,就判断出其可能的数值类型,而不需要向前或向后检索。
true,false,null 这几个固定的类型,直接就处理掉了,而其它稍微复杂的类型需要使用函数来处理。
这里没有使用if else,而是大量使用了case,是为了提高效率,减少判断次数。
解析JsonObject
private static JsonValue ParseObject(ref Data data)
{
// Object 对应 C#的Dictionary
var jsonObject = new Dictionary<string, JsonValue>(JsonObjectInitCapacity);
// skip '{'
data.index++;
do
{
// 跳过空白字符
SkipWhiteSpace(ref data);
if (data.json[data.index] == '}')
{
// 空的Object, "{}"
break;
}
DebugTool.Assert
(
data.json[data.index] == '"',
"Json ParseObject error, char '{0}' should be '"' ",
data.json[data.index]
);
// skip '"'
data.index++;
var start = data.index;
// 解析Object的key值
while (true)
{
var c = data.json[data.index++];
switch (c)
{
case '"':
// check end '"'
break;
case '':
// skip escaped quotes
data.index++;
continue;
default:
continue;
}
// already skip the end '"'
break;
}
// get object key string
// 扣出key字符串
var key = data.json.Substring(start, data.index - start - 1);
// 跳过空白
SkipWhiteSpace(ref data);
DebugTool.Assert
(
data.json[data.index] == ':',
"Json ParseObject error, after key = {0}, char '{1}' should be ':' ",
key,
data.json[data.index]
);
// skip ':'
data.index++;
// set JsonObject key and value
// 递归的调用ParseValue获得Object的value值
jsonObject.Add(key, ParseValue(ref data));
// 跳过空白
SkipWhiteSpace(ref data);
if (data.json[data.index] == ',')
{
// Object的下一对KV
data.index++ ;
}
else
{
// 跳过空白
SkipWhiteSpace(ref data);
DebugTool.Assert
(
data.json[data.index] == '}',
"Json ParseObject error, after key = {0}, char '{1}' should be '{2}' ",
key,
data.json[data.index],
'}'
);
break;
}
}
while (true);
// skip '}' and return after '}'
data.index++;
return new JsonValue(JsonType.Object, jsonObject);
}










