zoukankan      html  css  js  c++  java
  • 按照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日--

  • 相关阅读:
    android 14 进度条和拖动条
    android 13 5种click事件不同实现方式 比较
    android 12 click事件的不同实现方式
    android 11 模拟onclick 事件
    android 10 事件
    android 09
    android 08 AndroidManifest.xml
    android 07 22 23没看
    Linux常用命令last的使用方法详解
    Linux TOP命令 按内存占用排序和按CPU占用排序
  • 原文地址:https://www.cnblogs.com/heyang78/p/12955080.html
Copyright © 2011-2022 走看看