把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

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