2 个版本

0.1.1 2021 年 6 月 6 日
0.1.0 2021 年 5 月 28 日

#246 in 解析工具

自定义许可

47KB
1.5K SLoC

ratatat

rust 的解析器组合器库

目标

  • 渐进式快速解析器
  • 对于人类编写的文件实际上很快
  • 易于调试
  • 语法应类似形式化语法
  • 快速实验

非目标

  • 对大型数据文件快速
  • 零拷贝/分配
  • 通用输入类型(仅限于 [u8]

概念

解析文件的步骤

  • 读取文件
  • 将文件转换为 Input
  • 从输入创建一个 Context
  • 在上下文中运行解析器
  • 丢弃上下文和输入
  • 使用结果

输入

输入是一个由引用计数的 vec 支持的 [u8]。这使得解析器可以保留输入的片段,而不是复制它们。

上下文

上下文有一个指向输入的引用和一个解析器缓存。这使得解析器可以预先计算整个输入的内容,缓存结果等。

一旦解析完成,上下文可以被丢弃

解析器

解析器有一个解析方法,该方法接受一个上下文、一个可变位置,并返回一个可选的结果。

有许多内置的解析器和解析器组合器。例如

  • str 是一个解析器,如果输入在位置处包含它,则返回自身
  • char 表现类似
  • Map(parser,func) 运行解析器,然后在成功时对其结果应用一个函数
  • Filter(parser, func) 运行解析器,然后通过一个函数过滤结果

生成器

解析器生成器为类型生成解析器。这是在 Context 中使用缓存解析器的主要方法

您可以使用context.parser::<Generator>()获取一个缓存的解析器,或者立即使用context.parse::<Generator>(limit, &mut position)进行解析

此外,还有很多内置的生成器

  • char生成一个解析任何字符的解析器
  • [Generator;N]生成一个解析固定大小值数组的解析器
  • Memo<Generator>从另一个生成器生成一个记忆化的解析器

库结构

查看示例以了解其工作原理。JSON解析器是一个很好的起点。通常,您需要为AST的根实现Generator<YourType>

核心特性和类型在src/lib.rs

而内置解析器和组合器在src/parsers/

依赖项

~5–15MB
~183K SLoC