yaml解析示例(javascript)

作者: 王强儿 | 来源:发表于2016-05-09 23:03 被阅读4094次
    yaml解析示例(javascript)

    yaml概述

    yaml容易被机器解析,且人类可读。

    这是一个谎言吧!

    利用冒号分隔键和值,用中划线表示数组。这就是所有的规则。

    年轻人都喜欢simple,这是句名言。可以去官网查看详情,和其他解析库。

    yaml示例

    yaml:data 
    seq: 
    - 
      1:yi 
      2:er 
    - 
      1:one
      2 :two
    

    js的全部代码

    
    /**
     * yaml 解析简单实现
     */
    var pos = 0;
    /**
     * token
     * @returns
     */
    function getNextToken() {
        if (pos == len) {
            return {
                type : "EOF"
            }
        }
        skipSpace();
        var c = yaml[pos];
        if (isString(c)) {
            return getString();
        }
    
        pos++;
        return {
            val : c,
            type : c
        };
    }
    /**
     * next but do not changed
     * @param n
     * @returns
     */
    function peek(n) {
        skipSpace();
        return yaml[pos]
    }
    function skipSpace() {
        var c = yaml[pos];
        while (isSpace(c) && pos < len) {
            pos++;
            c = yaml[pos];
        }
    
    }
    function isSpace(c) {
        return c == ' ' || c == '\t' || c == '\n'
    
    }
    function getString() {
        var c = yaml[pos];
        var str = "";
            //没有考虑转义字符
        while (isString(c) && pos < len) {
            str += yaml[pos];
            pos++;
            c = yaml[pos];
        }
    
        return {
            val : str,
            type : "str"
        };
    }
    function isString(c) {
        return !isSpace(c) && !isSpecial(c);
    }
    function isSpecial(c) {
        return c == ':' || c == '-'
    }
    
    
    //can be simple type kv array
    function getYaml() {
        var currentToken = getNextToken();
    
        while (currentToken.type != "EOF") {
    
            if (peek() == ':') {
                return getkv(currentToken)
            }
            if (currentToken.type == '-') {
                return getArray();
            }
                    //string
            return currentToken.val;
        }
    
    }
    //键值对  其后不能是序列符号 
    function getkv(currentToken) {
        var yaml = {};
    
        getNextToken();
        yaml[currentToken.val] = getYaml();
        while (peek() != "-"&&currentToken.type != "EOF") {
            
            currentToken = getNextToken();
    
            getNextToken();//check : or thorw error
            yaml[currentToken.val] = getYaml();
    
        }
    
        return yaml;
    }
    function getArray() {
        var a = [];
        a.push(getYaml());
        while (peek() == "-") {
            getNextToken();//check -
            a.push(getYaml());
        }
        return a;
    }
    
    var yaml = "yaml:data " + "seq: " + "- 1:yi 2:er " + " - 1:one 2 :two";
    
    var len = yaml.length;
    console.log(JSON.stringify(getYaml()))
    //{"yaml":"data","seq":[{"1":"yi","2":"er"},{"1":"one","2":"two"}]}
    
    

    没有错误处理,也没有很好的封装,但是有详细的注释,容易改写和理解。

    json结果查看

    
    {"yaml":"data",
     "seq":
          [  {"1":"yi",
               "2":"er"
             },
            {"1":"one",
             "2":"two"
            }
          ]
    }
    

    对比一下,我个人感觉对于yaml,机器确实容易解析,而可读性并不算太好,可写性很好。不知道为什么最近就火了。

    尽量不写简单的示例了,可能方法不对,太无聊,得做点有意义的事情了[加了几个小时班,却没有工作成果]。不知道怎么从大体上把屋项目,现在只能看到代码里面的细节,几乎看不到思想层面的东西。

    其实我前面的定义就是错误的,没有考虑空格分隔的情况,这里的空格是有语法意义的(两个空格的缩减),类似python的语法。

    对于给出的示例正好可以运行。复杂的数据会把后面的对象加在前面的对象上,类似于if if else中的第二个else会被吞掉,其实好的做法是利用大括号({}),就是程序块中一句也加上括号。

    欺骗大家了,解析的结果其实是错误的。
    那么现在如何修改昵?首先设定两个空格的缩进,再根据缩进的结构进行读取。isSpace和peek需要改写。getYaml的时候语言增加参数记录当前的位置。说实话,我后来尝试改写代码,也没有正确解析,对我来说不好解析…。在网上看了一下,Python的解析,用了一下hack,才能正确。

    当然这个时候其实和人眼处理这样的东西是一样的,需要记忆功能前面空格数量。在没有工具支持,当编辑和阅读很长的文件时,基本属于瞎猜,和读几十层的js闭包一样让人崩溃。

    yaml的最后一个优点,就是可以用流的方式解析,就是yaml文件的大小几乎可以没有限制,利用buf在没有传递完全的时候也可以处理,对网络传递和文件读取特别有意义。这是因为没有开始符和终结符的原因,当然这些的文件要有一定的格式要求,就是缩进不能太深。把json或者xml的第一个开始符和最后的结束符去掉,我想我们也可以构造出这样的结构。据说Google map为了节省流量,用的就是自己设计的一种格式来传递数据,然后自己解析。当然任何人都可以根据业务来设计自己最合适的数据格式,但是普遍情况下这样的好处比缺点还多,还是使用通用的比较稳妥。

    最近涌现出很多新东西,新技术的快速入门的东西并不能让人感到尽兴,又不容易找到好的阅读材料。
    欢迎阅读我的其它文章

    相关文章

      网友评论

        本文标题:yaml解析示例(javascript)

        本文链接:https://www.haomeiwen.com/subject/gjwerttx.html