オープンソースJson解析器の概要


以前はプロジェクトでJsonというデータ変換フォーマットがよく使われていましたが、なぜですか.1、その使いやすさ、クロスプラットフォーム性、それはJS(JavaScript)のサブセットであり、オブジェクトの字面量であると思います.2、XMLとともにツリー構造の文法ツリーである.同じXML、JSONは、Jsonは比較的簡潔で、XMLは相対的に冗長で、もちろん互いにかけがえのないもので、具体的な需要に応じて適切に選択するのが完璧だと述べた.
オリジナルのJson解析器を作るのは科学技術を手にした大物が提出した問題で、これまでこのJson解析器を相対的に深く理解していなかったが、プロジェクトで使われたのはorg.JsonオープンソースパッケージGsonパッケージだった.今週は主にJson解析器の崩壊に関する知識を整理し,ネットワーク構造を形成した.Json解析器を作るには、Json自身を理解しなければなりません.ここでは主に以下に必要な点をいくつか出します.JSON構造:
"string":Java String;
number:Java Long Double;
true/false:Java Booleannull:Java null;
[array]:Java List<Object> Object[];
{"key":"value"}:Java Map<String, Object>。

JSON文法:
Jsonobject = {} | { members } members = pair | pair , members pair = string : value array = [] | [ elements ] elements = value | value , elements value = string | number | object | array | true | false | null string = “” | ” chars ” chars = char | char chars char = any-Unicode-character-except-“-or–or- control-character |\”|||/|b|f|||r|t|u four-hex-digits number=int|int frac|int exp|int frac exp int=digit|digit 1-9 digits|-digit 1-9 digits frac=.digits exp=e digits=digit|digit|digit|e+|e+|E-細節は「Json必知必会」を参照http://download.csdn.net/download/qq_34417408/10122524;
同時にコンパイル原理のいくつかの知識を理解しなければならない:コンパイル過程:文法分析、文法分析、意味分析、もちろんその中にコード最適化、目標コードがある.その中で、文法分析の役割:単語を見つける.例えばint a=b+c;結果はint,a,=,b,+,cおよび;構文解析の役割:式、セグメント、文などを見つけます.例えばint a=b=c;の構文解析結果はint a=b+cという文です.意味解析の役割:タイプが一致しているかどうかなどを表示します.
中間コードの最適化もあります.http://blog.csdn.net/qq_34417408/article/details/78126087(前にまとめたブログ)
同時に解析器の機能、原理を理解しなければならない.Json解析器は入力文字列を熟知したタイプのオブジェクトに再変換し,関数のようにJSONを表す文字列であり,出力は言語そのものに対応する構造化されたデータ構造である.
解析の過程で、主に2つの部分があります.1つは、文法分析で、ソースコードを文法ユニットtokenに解析します.もう1つは文法分析で、文法ツリーparserを構築します.もちろんJsonの文法と文法に基づいています.
第1部では、文法分析を形成する際、すなわち構造自動機(DFA)である.Jsonを書く前に、私は先にいくつかの簡単な自動機を書いて、長い間書いたことがなくて、体を温めて、実は論理分析さえすれば大丈夫で、とても簡単で、コードの実現です.(a|bb)「a」と「b」の文字列があり、「b」が現れると必ず偶数である.
public class ABB {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
        // TODO code application logic here
        Scanner in =new Scanner(System.in);
        String string=in.nextLine();
        char[] ch=string.toCharArray();
        if(ch.length==0){
            throw new Exception("     !");
        }
        int i=0;
        while(iif(ch[i]=='a'){
                ++i;
            }else if(i1&&ch[i]=='b'){
                ++i;
                if(i'b'){
                   ++i;
                }else{
                    throw new Exception("     !");
                }
            }else{
                throw new Exception("     !");
            }
        }
        System.out.println("    !");
    }
}

Jsonの構造が特殊であるため、最初の文字を入力するときにどのオブジェクトであるかを判断することができ、{}/[]/string/true/false/number/null;構造を加工し、列挙タイプであるtokenストリームに対応し、文法分析を行うことができる.
STRING(      )
NUMBER(     )
NULLnull)
START_ARRAY([)
END_ARRAY(])
START_OBJ({)
END_OBJ(})
COMMA(,)
COLON(:)
BOOLEAN(true  false)
END_DOC(  JSON     )

列挙タイプ:
public enum TokenType {
    START_OBJ, END_OBJ, START_ARRAY, END_ARRAY, NULL, NUMBER, STRING, BOOLEAN, COLON, COMMA, END_DOC
}

同時にtokenクラスを構築するには:
public class Token {
    private TokenType type;
    private String value;

    public Token(TokenType type, String value) {
        this.type = type;
        this.value = value;
    }

    public TokenType getType() {
        return type;
    }

    public void setType(TokenType type) {
        this.type = type;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String toString() {
        return getValue();
    }
}

Json解析の構文解析を行うには、まず文字列を文字配列に変換する必要があります.BufferReader(new StringReader(String str);BufferReader()について以下を参照してください.https://www.cnblogs.com/meilidelaohuhua/p/6638545.html ;変換後に文字を逐一分析し、Jsonの構造の自動機を用いてtokenストリームに変換する.このとき第一部分の文法分析が完了する.第二部分の文法木parser構造では、主に二つの部分に分けられる.一つは対象Object文法で、一つは配列Array文法で、その彼の文法は基本的なタイプで、その中のオブジェクトはMapで実現することができて、配列はListの集合を使います
public class JObject implements Json {
    private Map map = new HashMap<>();
    public JObject(Map map) {
        this.map = map;
    }

    public int getInt(String key) {
        return Integer.parseInt((String) map.get(key).value());
    }

    public String getString(String key) {
        return (String) map.get(key).value();
    }

    public boolean getBoolean(String key) {
        return Boolean.parseBoolean((String) map.get(key).value());
    }

    public JArray getJArray(String key) {
        return (JArray) map.get(key).value();
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("{ ");
        int size = map.size();
        for (String key : map.keySet()) {
            sb.append(key + " : " + map.get(key));
            if (--size != 0) {
                sb.append(", ");
            }
        }
        sb.append(" }");
        return sb.toString();
    }
}
public class JArray implements  Json, Value {
    private List list = new ArrayList<>();

    public JArray(List list) {
        this.list = list;
    }

    public int length() {
        return list.size();
    }

    public void add(Json element) {
        list.add(element);
    }

    public Json get(int i) {
        return list.get(i);
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[ ");
        for (int i =0; i < list.size(); i++) {
            sb.append(list.get(i).toString());
            if (i != list.size() - 1) {
                sb.append(", ");
            }
        }
        sb.append(" ]");
        return sb.toString();
    }

    @Override
    public Object value() {
        return this;
    }
}

その中で重要なのはJsonであり、Value抽象クラスの構築によってJObjectとJArrayが互いに変換され、動的な完成オブジェクトと配列が互いにネストされた変換である.また、tokenクラスを構築する際に列挙タイプとValueを属性とし、後でlistを追加する際には、多くの面倒を省くことができる.ソースコード:https://github.com/weiyanyanyan/Json
データ検索:https://www.cnblogs.com/meilidelaohuhua/p/6638545.html https://www.zhihu.com/question/24640264/answer/80500016 http://blog.csdn.net/yuanzhou314/article/details/43032067 https://www.liaoxuefeng.com/article/0014211269349633dda29ee3f29413c91fa65c372585f23000