< 返回版块

DiscreteTom 发表于 2025-01-30 00:26

Tags:parser,combinator,nom,whitehole

说到parser combinator,在rust生态中最知名的应该就是nom了。 不过我觉得它使用起来还是有一些麻烦,所以手搓了一套新框架:whitehole

相比于nom,whitehole的优点是:

  • 使用者只需要记住6个combinator:eat, take, next, till, wrap, recur
  • 使用运算符重载来组合combinator,比如eat('a') + eat('b')会匹配abeat('a') | eat('b')会匹配a或者beat('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 页