为 DSL 扩展 TypeScript 编译器

Extending the TypeScript compiler for a DSL

在我开始之前:我确实需要(/想要)一个 DSL(即使它只是为了体验),没有其他格式可以表达我正在尝试的东西以一种不太冗长、类型安全的方式来做。


一些背景资料,实际问题在底部


我想为我的项目 (TypeScript) 创建一个 DSL 编译器,并且由于该语言与 TypeScript 本身共享很多语法和概念(我是这样设计的)我想重新使用部分TypeScript 编译器避免重新发明轮子。我最感兴趣的是 scannerparserbinder。我的 DLS 的其他语义和发射部分与 TypeScript 有很大不同,我很确定从头开始编写它会更有效率。

我找到了 this 网站,该网站解释了编译器的实际工作原理(尽管我很确定它有点过时了),到目前为止我可以很好地理解所有内容。据我所知,如果我可以扩展 TypeScript 编译器,我没有理由重新发明轮子。

第一部分当然是scanner。 我尝试用我的语言 scan 一个文件来查看会发生什么,结果是所有 tsc 不知道的东西都被分类 (SyntaxKind) 为 Identifier(这是有道理的)。要实现我的 DLS,我必须向此扫描器添加关键字和语法类型,以将其发送到 parser 以构建 AST。当然,我也必须延长 parser,但这不是我现在关心的问题。

我的第一直觉是克隆 TypeScript respository 并添加所需的逻辑。这样我就可以使用与上述站点相同的 API,但添加了 keywords/syntax/AST-nodes。然后我会编写语义检查并实际从头开始生成生成的输出,一切都会很好。

不幸的是,这并没有真正奏效(因此出现了这个问题)。第一个障碍只是被存储库的大小和结构所淹没,我只是没有去我应该看的地方。 我试图创建一个使用本地源而不是内置源的小程序,但这也不起作用(可能是由于一些复杂的管道 tsc 在它处于任何可用状态之前经过)。 我确实找到了 compiler.tsparser.ts 等文件,但没有办法使用我的自定义版本,它们没有多大用处。 我试图只将我认为我需要的文件复制到我自己的项目中,但这导致了各种类型的输入错误和功能缺失,我不知道我应该如何(以及是否)修复它们。更糟糕的是:当我尝试在我自己的环境中编译某些文件时,它们出现了实际的编译错误(放松 tsconfig.json 设置没有帮助)。


真题

我有三个问题:

经过一段时间的摆弄,我放弃了扩展 Typescript 编译器的尝试。我最终使用 chevrotain 作为编译器-'generator',到目前为止它一直在工作 ok

这个库的主要缺点是它(根据我的经验)不能很好地与 Typescript 集成,因为有很多 "magic" 东西显然是为在高度动态的环境中使用而设计的那就是 JavaScript(虽然库本身是用 TS 写的)。

总的来说,我对它的体验非常愉快。文档很好,有很多可能性。我强烈推荐给任何想要在 Typescript 中构建 DSL 的人。

我正在考虑开始这样的旅程,我可以推荐 Myna parser 作为任何 DSL 的一个体面的、TS 友好的解析器,我以前用它来创建自定义降价变体。