從零開始寫一個Jison解析器(1/10):Jison,不是Json

從零開始寫一個Jison解析器(1/10):Jison,不是Json

標題沒有寫錯,Jison,不是Json

JSON(JavaScript Object Notation)是源自JavaScript的輕量級數據交換格式,既便於人類讀寫,也易於機器解析和生成。JSON基於Standard ECMA-262 3rd Edition - December 1999的一個子集。因此名字中包含JavaScript,不過JSON採用完全獨立於語言的文本格式,但是也使用了類似於C語言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 這些特性使JSON成爲理想的數據交換語言。

JisonJavaScript解析器生成器(parser generator)。

什麼是解析器(parser)?

解析器生成器(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規範的字符串。類似的還有HjsonHOCON,都是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 listTOML(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 generator)?

前面提到了常見的幾種需要自行編寫解析器(parser)的場景以及面臨的挑戰,那麼有沒有辦法能又快又好的開發一個解析器(parser)呢?也有一類成熟的產品,專門用於生成解析器(parser),這類產品就是解析器生成器(parser generator)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章