花费比较长时间对付缩进语法, 两年多, 直到现在才初步实现一个解析器,
基于缩进语法的编程语言日益增多, 主要是在动态语言和 DSL 里明显,
通过括号实现的语法, 在编辑过程中特别容易产生多余的编辑, 虽然对编程是可以接受的.
但为了便利, 特别是作为标记语言, 配置语言, 缩进替代括号很自然.
我现在还没有全掌握关于 LR 解析的编程实现, 只把探索中的资源记录下.

JS 目前两个主要的 parser generator, 一个是 Jison, 另一个是 PEG.js.
另外有看到 Parsec 移植到 JS 的一些版本, 具体用法还没有细看.
两个文档都是有的, 后者相对清晰些. 同样都提供了在线运行的版本...
学习的话, 两个代码对应仓库里都附上了 examples/, 可以参考.

http://jison.org/
Jison 是从 Bson 移植到 JS 的. CoffeeScript 用了 Jison.
当然用 Jison 本来就应该很多才对, 直接看 Wiki:
https://github.com/zaach/jison/wiki/ProjectsUsingJison

http://pegjs.majda.cz/
PEG.js 是基于 PEG 的实现, CoffeeScript 2.0 是通过 PEG 重写的.
PEG.js 通过 .pegjs 文件生成 parser, 因为其中会嵌入 JS 代码,
为了方便, 有人做了 CoffeeScript 的版本, 可能还有两个, 我尝试过这个:
https://github.com/Dignifiedquire/pegjs-coffee-plugin
这样语法高亮也就变成两个版本的了, 一个 JS 的, 一个是 CoffeeScript 的:
https://github.com/nornalbion/Sublime-PEGjs
https://github.com/jiyinyiyong/Sublime-PEGcoffee
使用 PEG 的项目还不少, Wiki 上给出了, 我印象比较深是 Blade:
https://github.com/dmajda/pegjs/wiki/Projects-Using-PEG.js

文本解析的意图还算清晰, 就是文本一层层进行嵌套,
在 Lisp 语法里这非常清晰, 因为括号就表明嵌套了,
其他的复杂语法的语言里类似, 具体尝试过 PEG 更清楚一些.

我折腾了一会 PEG.js , 但缩进语法相对更复杂, 实际上我没成功,
虽然有 Blade 代码可以参考, 我还是感到有巨大的难度,
中间有学长帮忙补了一些解析器的知识, 梳理具体的形态... 但还是有不同,
文本解析将整个文件看成是一串字符, 一步步拆分开直接 token 的层级,
当然算法中间可能有尝试, 又失败, 回滚, 我感到这边比较复杂,
而缩进并不是, 缩进是将文本视为行列的矩阵, 通过缩进层级完成第一步的解析,
当成文本也能做, 但复杂多了, 这是我遇到最大的分歧.

文本解析, 包括后来按解析的数据生成数据, 都让我更深感受到递归得作用,
或者不说递归, 说私有数据吧, 每一个操作过程带的私有数据, 面向对象也用到的.
私有数据可以比较好地模拟问题中状态的内容, 以及其他的操作,
我们需要多一些合理的层级, 这里理解软件也就更容易一些, 递归得过程同样.
可能是在不是语言能表达清楚的, 还是要再代码里直接体会...

很多语言解析器都是手写的, 听说就 Ruby Python 语法太大所以是生成的,
手写的话, Lexer Parser 分离比较明显, 更复杂了... 没学会..

文本解析在编辑器做语法支持时候也比较重要, 但相对简单些,
Sublime Text 高亮代码主要用正则, 也会出现复杂的组合来解析复杂的,
CodeMirror 高亮语法用得也是类似, 用正则对代码进行处理,
http://codemirror.net/doc/manual.html#modeapi


返回博客首页: http://blog.tiye.me


题叶
17.3k 声望2.6k 粉丝

Calcit 语言作者