用C#实现一个JSON解释器

[原创]
https://www.cnblogs.com/gangjian/p/14386552.html

public class JSONReader
{
    // 从文件读出JSON对象
    public static JSONObject Read(string path)
    {
        if (!File.Exists(path))
        {
            return null;
        }
        try
        {
            string txt = File.ReadAllText(path);
            int offset = 0;
            JSONObject obj = null;
            if (JSONObject.TryParse(txt, ref offset, out obj))
            {
                return obj;
            }
        }
        catch (Exception)
        {
        }
        return null;
    }
}

public class JSONObject
{
    // JSON对象
    List _pairs = new List();            // '名称:值'对list
    private JSONObject(List pair_list)
    {
        this._pairs = pair_list;
    }

    public static bool TryParse(string in_str, ref int offset, out JSONObject obj)
    {
        obj = null;
        int idx = offset;
        char? ch = Util.GetNextNsChar(in_str, ref idx);
        if (null == ch
            || !ch.Equals('{'))
        {
            return false;
        }
        idx += 1;
        List pair_list = new List();
        while (true)
        {
            JSONPair pair;
            if (JSONPair.TryParse(in_str, ref idx, out pair))
            {
                pair_list.Add(pair);
                idx += 1;
            }
            ch = Util.GetNextNsChar(in_str, ref idx);
            if (null != ch)
            {
                if (ch.Equals('}'))
                {
                    // 结束
                    obj = new JSONObject(pair_list);
                    offset = idx;
                    return true;
                }
                else if (ch.Equals(','))
                {
                    idx += 1;
                    continue;
                }
            }
            break;
        }
        return false;
    }
}

public class JSONArray
{
    // JSON数组
    List _valList = new List();
    internal List ValueList
    {
        get { return _valList; }
    }
    private JSONArray(List val_list)
    {
        this._valList = val_list;
    }

    public static bool TryParse(string in_str, ref int offset, out JSONArray array)
    {
        array = null;
        int idx = offset;
        char? ch = Util.GetNextNsChar(in_str, ref idx);
        if (null == ch
            || !ch.Equals('['))
        {
            return false;
        }
        idx += 1;
        List val_list = new List();
        while (true)
        {
            JSONValue val;
            if (JSONValue.TryParse(in_str, ref idx, out val))
            {
                val_list.Add(val);
                idx += 1;
            }
            ch = Util.GetNextNsChar(in_str, ref idx);
            if (null != ch)
            {
                if (ch.Equals(']'))
                {
                    // 结束
                    array = new JSONArray(val_list);
                    offset = idx;
                    return true;
                }
                else if (ch.Equals(','))
                {
                    idx += 1;
                    continue;
                }
            }
            break;
        }
        return false;
    }
}

public class JSONPair
{
    // '名称:值'对
    string _name = string.Empty;
    object _value = null;
    private JSONPair(string name, JSONValue val)
    {
        this._name = name;
        this._value = val;
    }

    public static bool TryParse(string in_str, ref int offset, out JSONPair pair)
    {
        pair = null;
        int idx = offset;
        string name = Util.GetJsonStr(in_str, ref idx);
        if (null == name)
        {
            return false;
        }
        idx += 1;
        char? ch = Util.GetNextNsChar(in_str, ref idx);
        if (null == ch
            || !ch.Equals(':'))
        {
            return false;
        }
        idx += 1;
        JSONValue val;
        if (!JSONValue.TryParse(in_str, ref idx, out val))
        {
            return false;
        }
        pair = new JSONPair(name, val);
        offset = idx;
        return true;
    }
}

public class JSONValue
{
    // 字符串
    // 数字
    // JSONObject
    // JSONArray
    // true/false
    // null
    object _value = null;
    public object Value
    {
        get { return _value; }
    }
    string _category = string.Empty;
    public string Category
    {
        get { return _category; }
    }
    private JSONValue(string category, object val)
    {
        this._category = category;
        this._value = val;
    }

    public static bool TryParse(string in_str, ref int offset, out JSONValue val)
    {
        val = null;
        int idx = offset;
        char? ch = Util.GetNextNsChar(in_str, ref idx);
        if (null == ch)
        {
            return false;
        }
        else if (ch.Equals('\"'))
        {
            // 字符串
            string str = Util.GetJsonStr(in_str, ref idx);
            if (null != str)
            {
                val = new JSONValue("string", str);
                offset = idx;
                return true;
            }
        }
        else if (char.IsDigit(Convert.ToChar(ch)))
        {
            // 数字
            string word_str = Util.GetWord(in_str, ref idx);
            int ival;
            if (null != word_str
                && int.TryParse(word_str, out ival))
            {
                val = new JSONValue("number", ival);
                offset = idx;
                return true;
            }
        }
        else if (ch.Equals('{'))
        {
            // JSON对象
            JSONObject obj;
            if (JSONObject.TryParse(in_str, ref idx, out obj))
            {
                val = new JSONValue("JSON Object", obj);
                offset = idx;
                return true;
            }
        }
        else if (ch.Equals('['))
        {
            // JSON数组
            JSONArray arr;
            if (JSONArray.TryParse(in_str, ref idx, out arr))
            {
                val = new JSONValue("JSON Array", arr);
                offset = idx;
                return true;
            }
        }
        else
        {
            // true,false,null
            string word = Util.GetWord(in_str, ref idx);
            if (word.ToLower().Equals("true"))
            {
                val = new JSONValue("bool", true);
                offset = idx;
                return true;
            }
            else if (word.ToLower().Equals("false"))
            {
                val = new JSONValue("bool", false);
                offset = idx;
                return true;
            }
            else if (word.ToLower().Equals("null"))
            {
                val = new JSONValue("null", null);
                offset = idx;
                return true;
            }
        }
        return false;
    }
}

class Util
{
    public static char? GetNextNsChar(string in_str, ref int offset)
    {
        char? ret = null;
        for (int i = offset; i < in_str.Length; i++)
        {
            if (char.IsWhiteSpace(in_str[i])
                || in_str[i].Equals('\r')
                || in_str[i].Equals('\n'))
            {
            }
            else
            {
                offset = i;
                return in_str[i] as char?;
            }
        }
        return ret;
    }
    public static string GetWord(string in_str, ref int offset)
    {
        StringBuilder sb = new StringBuilder();
        for (int i = offset; i < in_str.Length; i++)
        {
            char ch = in_str[i];
            if (char.IsWhiteSpace(ch)
                || ch.Equals('\r')
                || ch.Equals('\n'))
            {
                if (0 != sb.Length)
                {
                    offset = i - 1;
                    return sb.ToString();
                }
                break;
            }
            else
            {
                sb.Append(ch);
            }
        }
        return null;
    }
    public static string GetJsonStr(string in_str, ref int offset)
    {
        int idx = offset;
        char? quote = GetNextNsChar(in_str, ref idx);
        if (!quote.Equals('"'))
        {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        sb.Append(in_str[idx]);
        for (int i = idx + 1; i < in_str.Length; i++)
        {
            char ch = in_str[i];
            if (ch.Equals('\r') || ch.Equals('\n'))
            {
                // 回车换行
                break;
            }
            else if (ch.Equals('\\'))
            {
                // 转义字符
                sb.Append(ch);
                if (i + 1 < in_str.Length
                    && !in_str[i + 1].Equals('\r')
                    && !in_str[i + 1].Equals('\n'))
                {
                    sb.Append(in_str[i + 1]);
                    i += 1;
                }
                else
                {
                    break;
                }
            }
            else if (ch.Equals('"'))
            {
                // 字符串结束
                sb.Append(ch);
                offset = i;
                return sb.ToString();
            }
            else
            {
                sb.Append(ch);
            }
        }
        return null;
    }
}

参考:

http://www.json.org.cn/

你可能感兴趣的:(用C#实现一个JSON解释器)