按照BNF语法重新写就的JsonAnalyzer2

本例源码:https://files.cnblogs.com/files/heyang78/JsonAnalyzer2-20200525-01.rar

自从按BNF重新书写了算术表达式解析(https://www.cnblogs.com/heyang78/p/12951492.html)后,深感这种方式精简,于是又用它重写了Json解析器.

此解析器通过的测试用例在:https://www.cnblogs.com/heyang78/p/12955028.html

新Json解析器核心类:

package com.heyang;

import java.util.List;

public class TreeBuilder {
    private Node root;
    private List<Token> tokens;
    private int tokenIdx;
    
    public TreeBuilder(List<Token> tokens)  throws Exception{
        this.tokens=tokens;
        this.tokenIdx=0;
        
        root=new Node(null,Node.Type_List);
        parse_object(root);
    }
    
    private void parse_object(Node parent) throws Exception{
        Token token;
        
        token=fetchToken();
        if(token.getType()!=Token.TYPE_OPEN_BRACE) {
            throw new Exception("Missing '{'");
        }
        
        for(;;) {
            token=fetchToken();
            if(token.getType()!=Token.TYPE_TEXT) {
                break;
            }
            String key=token.getText();
            
            token=fetchToken();
            if(token.getType()!=Token.TYPE_COLON) {
                throw new Exception("Should be ':' after key:"+key);
            }
            
            token=fetchToken();
            if(token.getType()==Token.TYPE_TEXT) {
                String value=token.getText();
                
                parent.addChild(new Node(key,value));
            }else if(token.getType()==Token.TYPE_OPEN_BRACE){
                Node node=new Node(key,Node.Type_List);
                parent.addChild(node);
                
                returnToken();
                parse_object(node);
                
                
            }else if(token.getType()==Token.TYPE_OPEN_BRACKET) {
                Node node=new Node(key,Node.Type_Array);
                parse_array(node);
                parent.addChild(node);
            }else {
                throw new Exception("value should be string/object/array but not.");
            }
            
            token=fetchToken();
            if(token.getType()==Token.TYPE_COMMA) {
                continue;
            }else {
                returnToken();
                break;
            }
        }
        
        token=fetchToken();
        if(token.getType()!=Token.TYPE_CLOSE_BRACE) {
            throw new Exception("Missing '}'");
        }
    }
    
    private void parse_array(Node parent) throws Exception {
        Token token;
        
        for(;;) {
            token=fetchToken();
            if(token.getType()==Token.TYPE_TEXT) {
                String value=token.getText();
                Node node=new Node(null,value);
                parent.addChild(node);
            }else if(token.getType()==Token.TYPE_OPEN_BRACE) {
                Node node=new Node(null,Node.Type_List);
                parent.addChild(node);
                
                returnToken();
                parse_object(node);
            }else {
                returnToken();
            }
            
            token=fetchToken();
            if(token.getType()==Token.TYPE_COMMA) {
                continue;
            }else {
                returnToken();
                break;
            }
        }
        
        token=fetchToken();
        if(token.getType()!=Token.TYPE_CLOSE_BRACKET) {
            throw new Exception("Missing ']'");
        }
    }
    
    private Token fetchToken() {
        if(tokenIdx>=tokens.size()) {
            return null;
        }else {
            Token t=tokens.get(tokenIdx);
            tokenIdx++;
            return t;
        }        
    }
    
    private void returnToken() {
        if(tokenIdx>0) {
            tokenIdx--;
        }
    }
    
    public Node getRoot() {
        return root;
    }
}

该解析器目前有bug,即;,{}[]出现在值的字符串中时,会导致解析异常.这个需要调整Lexer,此事留待日后完成.

--2020年5月25日--

原文地址:https://www.cnblogs.com/heyang78/p/12955080.html