说到parser combinator,在rust生态中最知名的应该就是nom了。 不过我觉得它使用起来还是有一些麻烦,所以手搓了一套新框架:whitehole
相比于nom,whitehole的优点是:
- 使用者只需要记住6个combinator:
eat
,take
,next
,till
,wrap
,recur
。 - 使用运算符重载来组合combinator,比如
eat('a') + eat('b')
会匹配ab
,eat('a') | eat('b')
会匹配a
或者b
,eat('a') * (1..=3)
会尝试匹配1到3次a
。非常符合直觉。 - 可以有状态(stateful)。nom使用函数作为combinator,所以难以进行状态管理。whitehole提供了可选的自定义状态来实现有状态的Parser。
- 可以复用堆内存。nom使用函数作为combinator所以也难以统一管理内存分配。whitehole提供了一个集中管理的内存区域来避免combinator被执行时频繁的re-allocation。
当然nom是非常优秀的框架,相比之下whitehole的不足包括:
- 不支持bit级别的解析,只支持字符串和bytes
- 没有框架级的错误处理方案。目前提供的一些通用功能已经可以解决很多错误处理的需求,所以目前没有专门把错误处理作为框架的一部分。
- 对流式输入的支持不太好,需要手动处理不完整的输入。
- 处理递归的时候需要一些额外的注意。nom使用函数作为combinator所以很容易实现递归。whitehole需要使用特殊的
recur
来实现递归。
性能测试: https://github.com/DiscreteTom/whitehole-bench
目前只对比了nom,场景为JSON lexer,在我的笔记本上测试结果如下:
lex_json_with_whitehole: lex 3 json files (total 4609769 bytes)
time: [4.2659 ms 4.3519 ms 4.4500 ms]
lex_json_with_nom: lex 3 json files (total 4609769 bytes)
time: [14.197 ms 14.456 ms 14.753 ms]
如果各位感兴趣,欢迎试用与提出改进建议~
Ext Link: https://github.com/DiscreteTom/whitehole
1
共 0 条评论, 1 页
评论区
写评论还没有评论