JSON(JavaScript Object Notation)是源自JavaScript的轻量级数据交换格式,既便于人类读写,也易于机器解析和生成。JSON基于Standard ECMA-262 3rd Edition - December 1999的一个子集。因此名字中包含JavaScript,不过JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。
而Jison是JavaScript解析器生成器(parser generator)。
解析器生成器(parser generator)?听起来有点拗口,要理解为什么Jison被称作解析器生成器(parser generator),还是从JSON说起。这是一个JSON例子。
{
"object" : {
"number" : 3.1415926,
"string" : "This is a string in an object."
},
"array" : [
"First value of array",
"Second value of array",
"Third value of array"
]
}
在JavaScript中可以直接输出JSON。
console.log({
"object" : {
"number" : 3.1415926,
"string" : "This is a string in an object."
},
"array" : [
"First value of array",
"Second value of array",
"Third value of array"
]
});
如果是字符串的话,那么就只能输出字符串了。
console.log(`{
"object" : {
"number" : 3.1415926,
"string" : "This is a string in an object."
},
"array" : [
"First value of array",
"Second value of array",
"Third value of array"
]
}`);
此时可以使用JSON.parse
函数把字符串解析成JSON。
console.log(JSON.parse(`{
"object" : {
"number" : 3.1415926,
"string" : "This is a string in an object."
},
"array" : [
"First value of array",
"Second value of array",
"Third value of array"
]
}`));
这里使用的JSON.parse
函数就是解析器(parser),函数名称即为此意。
那么解析器(parser)和解析器生成器(parser generator)有什么区别和联系呢?
JSON.parse
函数只能用于解析格式为JSON的字符串,如果字符串格式不是JSON,甚至于略有变化,例如在JSON中像写程序一样增加注释。
console.log(JSON.parse(`{
//this is a comment line
"object" : {
"number" : 3.1415926,
"string" : "This is a string in an object."
},
"array" : [
"First value of array",
"Second value of array",
"Third value of array"
]
}`));
就会报错
SyntaxError: Unexpected token / in JSON at position 4
这是因为JSON.parse
函数不能识别新增的//this is a comment line
,此时就需要使用JSON5。
const JSON5 = require('json5')
console.log(JSON5.parse(`{
//this is a comment line
"object" : {
"number" : 3.1415926,
"string" : "This is a string in an object."
},
"array" : [
"First value of array",
"Second value of array",
"Third value of array"
]
}`));
这里用到的JSON5.parse
函数,就是JSON5提供的解析器(parser),不过JSON5.parse
函数也只能识别符合JSON5规范的字符串。类似的还有Hjson、HOCON,都是JSON变体解析器(parser),每个解析器只能解析符合自己格式规范的语法。
前面提到JSON(JavaScript Object Notation)是轻量级数据交换格式,既便于人类读写,也易于机器解析和生成。类似的人类可读(非二进制)数据交换格式还有RDF(Resource Description Framework)、XML(eXtensible Markup Language)、Atom(基于XML)、YAML(是YAML Ain’t Markup Language的递归式缩写)、EDN(Extensible Data Notation)、Property list、TOML(Tom’s Obvious, Minimal Language)、Rebol(Relative Expression Based Object Language)、Gellish(Generic Engineering Language)。
这些格式都有相应的解析器(parser),类似于前面JSON中添加注释的例子,也都有各自的缺点和局限性。例如使用前述这些成熟的格式,在几乎所有常用编程语言中都可以直接使用现成的解析器(parser),有时候还有多个解析器(parser)实现,不过在享受便利的同时,也要接受其全部缺点,例如YAML的第三版YAML 1.2的规格手册PDF版本有84页!而常见的YAML通常只有几十行,为了写对几十行YAML而去阅读84页手册未免得不偿失。然而当使用程序处理YAML时,如果不是使用成熟的程序包,而是自行解析的话,失误就在所难免,毕竟84页手册中描述的细节太多了。或者像JSON的各种变体解析器那样,需要对成熟的格式改进,当原有格式不支持这种改进时,也需要自行编写解析器(parser),此时也需要充分了解原有规范。进一步,如果要自定义格式,也需要专门编写解析器(parser)。
前面提到了常见的几种需要自行编写解析器(parser)的场景以及面临的挑战,那么有没有办法能又快又好的开发一个解析器(parser)呢?也有一类成熟的产品,专门用于生成解析器(parser),这类产品就是解析器生成器(parser generator)。