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() != "-"&¤tToken.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为了节省流量,用的就是自己设计的一种格式来传递数据,然后自己解析。当然任何人都可以根据业务来设计自己最合适的数据格式,但是普遍情况下这样的好处比缺点还多,还是使用通用的比较稳妥。
最近涌现出很多新东西,新技术的快速入门的东西并不能让人感到尽兴,又不容易找到好的阅读材料。
欢迎阅读我的其它文章。
网友评论