Monogram:一份可执行语法,同时生成 parser 和语法高亮
做语法高亮这件事,很多编辑器生态其实一直在重复一件麻烦事:parser 是一套逻辑,highlighter 又是另一套逻辑。
前者通常更接近语言本身,后者却常常是手写 regex、补 edge case、修一堆多年遗留的高亮 bug。结果就是,真正复杂一点的语法一出现,颜色先乱。
今天想记录的 johnsoncodehk/monogram,就是在反过来做这件事。它的目标不是再写一份更大的 TextMate 规则,而是把 grammar 本身 作为唯一事实来源:先把 grammar 跑成真正可执行的 parser,再从同一份定义生成 TextMate、tree-sitter、Monarch 等高亮产物。
按 GitHub API 和仓库页面在 2026-06-21 的公开信息,这个仓库当前大约有 119 stars、3 forks,主要语言是 TypeScript,创建于 2026-05-27,最近一次公开更新时间是 2026-06-21。截至今天,GitHub metadata 里还没有列出 SPDX license,releases 页面也还没有公开发布 release。
项目概览
| 属性 | 详情 |
|---|---|
| 仓库 | johnsoncodehk/monogram |
| 定位 | 从一份 grammar 派生 parser 和多种语法高亮产物 |
| Stars | 119 |
| Forks | 3 |
| 主要语言 | TypeScript |
| 创建时间 | 2026-05-27 |
| 最近更新时间 | 2026-06-21 |
| License 状态 | GitHub metadata 未列出 SPDX license |
| Latest release | 截至 2026-06-21 暂无公开 release |
它最值得看的点,是把 “先写高亮” 反过来变成 “先证明 grammar”
Monogram README 里最核心的一句话,其实就是:
Write a language’s grammar once, as an executable definition.
它的思路不是先写一堆高亮规则,再尽量靠近 parser;而是先把 grammar 做成一个真的能执行的 parser,然后再从这份 grammar 里派生出高亮器。
这带来一个很直接的变化:
- 不再把语法高亮建立在手工 regex 猜测上;
- 先让 parser 决定语法结构;
- 再让高亮结果跟着 parser 已经证明过的结构走。
对于 TypeScript 这种存在大量歧义边界的语言,这个方向很有意义。像 README 里举的例子,typeof x < y 这种写法,如果只是 regex 高亮,就得猜 < 到底是泛型还是小于号;而 parser 根本不用猜,它按 grammar 走就行。
一份 grammar,往外派生的不只是 TextMate
Monogram 的另一个亮点,是它并不把结果收束在某一种编辑器格式里。
README 明确写到,同一份 grammar 可以产出:
- lexer;
- CST parser;
- TextMate grammar;
- VS Code language configuration;
- CST node types;
- tree-sitter grammar 和 highlights query;
- Monarch tokenizer。
这意味着它想解决的不是“某个编辑器高亮偶尔不准”,而是更大的问题:语法相关的多个下游产物,能不能共用同一份结构化定义。
这件事如果做稳,对工具链的价值会比“又一个高亮仓库”大得多。因为 parser、编辑器高亮、语言配置、tree-sitter 生态,本来就经常各自演化,最后同步成本越来越高。
README 里给出的验证口径,比常见 side project 更硬
很多语法相关项目都会说自己“更准确”或者“更聪明”,但 Monogram README 在这方面给出的不是形容词,而是比较具体的验证方式。
它提到项目当前主要覆盖四种语言:
- TypeScript;
- JavaScript;
- HTML;
- YAML。
其中 TypeScript 的状态被写成:
- 100% valid-code coverage;
- 97.8% bidirectional vs
tsc。
这里的重点不是数字本身,而是它强调了一个思路:先把 grammar 当 parser 去对照官方语法或参考实现,再去谈高亮是否值得信任。
如果一个项目真想把 highlighter 建在 parser 之上,这个验证顺序是对的。否则就还是只是在做另一版“看起来更聪明的高亮规则”。
它不只是研究味很重,已经开始接真实生态
README 里一个很有说服力的信号,是它已经明确写出:
- vuejs/language-tools 在使用 Monogram 派生的 Vue TextMate grammar 和 VS Code language configuration。
这很重要。因为很多 parser 或 grammar 项目概念都很好,但只停在 demo 或 benchmark。
Monogram 至少已经开始往真实编辑器生态里送产物,而不是只停留在“理论上可以生成”。
对一个 2026-05-27 才创建、目前 stars 还不高的仓库来说,这说明它不是纯粹停在论文式想法,而是在试图成为真正可接入的 developer tool。
Node 24+ 这个要求,也透露出它的工程取向
Monogram 的 quick start 很短:
npm install
node src/cli.ts typescript.ts
README 还特别标明它要求 Node 24+,因为它直接运行 .ts,不额外依赖 tsx 或单独 build step。
这其实也能看出作者的偏好:尽量让 grammar 本身就是可以直接执行、直接生成产物的东西,而不是再围一层很重的构建链。
对小而专的语言工具来说,这种选择挺合理。因为这类项目最怕的是核心思想不复杂,但外围脚手架反而把使用门槛抬高。
为什么这个项目值得开发者关注
我觉得 Monogram 真正有意思的地方,不只是“能生成高亮器”,而是它提出了一个很清楚的工程方向:
如果 parser 才是最接近语言事实的一层,那高亮、language config、tree-sitter query 这些衍生物,为什么不能从 parser grammar 往下生成?
这条路的价值主要在三点:
- 可以把 grammar 和 highlighter 的长期分叉收回来;
- 能把许多歧义语法问题交给 parser 结构,而不是 regex 猜测;
- 更适合让多个编辑器/工具链产物共享同一份语言定义。
当然,Monogram 现在仍然是一个活跃中的研究型项目,README 里也明确这样定位它。再加上目前仓库尚未公开 release、license metadata 也还没补齐,说明它离“成熟、稳定、广泛集成”的状态还有路要走。
但正因为它还早,才更值得现在关注。很多语言工具真正稀缺的,不是把已有做法再包装一层,而是像这样敢于重新定义 source of truth 放在哪里。
小结
johnsoncodehk/monogram 值得看的不是“又一个语法工具”,而是它把 grammar -> parser -> highlighter 这条链重新理顺了。
先证明 grammar,再派生高亮;先让语言结构说话,再让颜色跟上。这种做法未必最省事,但如果目标是长期维护多种语法产物,它显然比继续手写一堆彼此漂移的规则更有前途。