把Monarch從Microsoft VSCode請出來當Parser

把Monarch從Microsoft VSCode請出來當Parser

最近用自己的Lazac解析source code,結果發現怎麼寫解析javascript和ruby的傷痛都在inline regexp上。要想不用AST,從string直接區分一個表達式是inline regexp還是普通除法,並且cover regexp的所有語法確實相當複雜。於是尋求其他解決方案。順帶分析分析一些VSCode的代碼吧。

TL;DR
NPM: https://www.npmjs.com/package/monarch.js

有沒有人已經寫好了同樣的東西呢?首先想到的當然是VSCode。找找package.json,裏面有個叫vscode-textmate的東西,這個是不是我們要的呢?於是順藤摸瓜,去了vscode-textmate的github上看一看。的確很有用,但是它有兩個問題:

  1. 解析出來的scope有一大串,而且token的type各種語言都不太一樣,沒有統一成identifier、keywords之類的。
  2. 用過VSCode的早期版本都有感覺,當時很多時候它解析javascript的inline regexp也不對。顏色會標錯。

於是繼續尋找解決方案。看看有沒有Web based editor?Google了一下,發現了從Microsoft VSCode分離出來的monaco-editor。以前一直想把VSCode轉成網頁版,竟然已經有弄好的,在Monaco Editor的網站,有一個標籤叫Monarch。一開始沒有注意,然後仔細閱讀發現它是一個定義Language的模塊,使用一堆regexp。而且doc裏自稱是inline regexp的解析很準確。試了試,javascript inline regexp確實不錯。換到ruby,註釋裏也戲稱解析ruby就是nightmare…那麼就是它了,下面就是Monarch的代碼在哪?

在github上搜索了一圈,Monarch似乎是包含在Monaco Editor裏的;那麼去找Monaco Editor的代碼,src就一個ts文件,doc裏說代碼都在VSCode裏了。這還是很坑爹的…Monaco Editor是整個打包成Browser可用的組建了,VSCode的代碼量還是很龐大的,於是github上對VSCode的repo進行搜索Monarch,發現了它的幾個文件在一個standalone的文件夾裏,全是ts的。有monarchCommon monarchCompiler monarchLexermonarchTypes,看看import,只有monarchLexer有不少。其他就零星幾個引用到最基本的諸如objects typesimport。能把Monarch分離出來麼?

它既然放在standalone文件夾裏,該不會騙人吧…於是把Monarch相關的文件全部複製出來,再嘗試展開monarchLexer的所有import,發現很多import都是一些interface。但是遇到modeServicestandaloneThemeService就有點犯難了。先把它們用null代替吧,到時候調試的時候遇到了error,一個一個mock吧。

Monarch在VSCode裏是怎麼調用的,這個搜索一下別的文件的importmonarchCompiler或者monarchLexer就好了。原來它最後也是接入TextMate那套框架的,就是先把語言定義傳給monarchCompiler,再用monarchLexer創建一個adapter可以適配原先的代碼。所以把學習這些代碼,把可用的部分提取出來。語言定義可以在一個monaco-languages的package裏找到很多:npm install monaco-languages,在其release文件夾裏有很多寫好的,除了javascript有引用到typescript的東西,我們可以直接從Monarch網站上覆制那個typescript無關的版本,其他就把release/esm下的文件改改export var ... => exports.,最後把.language傳給monarchCompiler就好了。最終可以進行簡單的tokenize了。

前面有提到modeServicethemeService沒有,Monarch有兩個版本的tokenizetokenizetokenize2,一個對應Classic,一個對應Morden。用tokenize2會報錯,因爲沒有定義兩個service。大概看了下modeServicethemeService,一個是定義corss-reference和language下寫代碼有哪些會自動觸發的action,一個是配色方案。暫時不管了,以後再看吧。有普通的就夠用了。寫個package上傳到npm上吧。

J.Y.Liu
2019.01.21

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